Module Name:    src
Committed By:   msaitoh
Date:           Sun Dec  2 10:51:07 UTC 2018

Modified Files:
        src/usr.sbin/acpitools/acpidump: acpi.c acpidump.8

Log Message:
 Decode IO Remapping Table.


To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/usr.sbin/acpitools/acpidump/acpi.c
cvs rdiff -u -r1.14 -r1.15 src/usr.sbin/acpitools/acpidump/acpidump.8

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/acpitools/acpidump/acpi.c
diff -u src/usr.sbin/acpitools/acpidump/acpi.c:1.41 src/usr.sbin/acpitools/acpidump/acpi.c:1.42
--- src/usr.sbin/acpitools/acpidump/acpi.c:1.41	Sun Nov 11 00:24:01 2018
+++ src/usr.sbin/acpitools/acpidump/acpi.c	Sun Dec  2 10:51:07 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi.c,v 1.41 2018/11/11 00:24:01 maya Exp $ */
+/* $NetBSD: acpi.c,v 1.42 2018/12/02 10:51:07 msaitoh Exp $ */
 
 /*-
  * Copyright (c) 1998 Doug Rabson
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: acpi.c,v 1.41 2018/11/11 00:24:01 maya Exp $");
+__RCSID("$NetBSD: acpi.c,v 1.42 2018/12/02 10:51:07 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/endian.h>
@@ -96,6 +96,7 @@ static void	acpi_handle_einj(ACPI_TABLE_
 static void	acpi_handle_erst(ACPI_TABLE_HEADER *sdp);
 static void	acpi_handle_gtdt(ACPI_TABLE_HEADER *sdp);
 static void	acpi_handle_hest(ACPI_TABLE_HEADER *sdp);
+static void	acpi_handle_iort(ACPI_TABLE_HEADER *sdp);
 static void	acpi_handle_lpit(ACPI_TABLE_HEADER *sdp);
 static void	acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
 static void	acpi_handle_msct(ACPI_TABLE_HEADER *sdp);
@@ -2063,6 +2064,320 @@ acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
 	printf(END_COMMENT);
 }
 
+/*
+ * IORT
+ * I/O Remapping Table
+ */
+
+static void acpi_print_iort_its_group(ACPI_IORT_NODE *);
+static void acpi_print_iort_named_component(ACPI_IORT_NODE *);
+static void acpi_print_iort_root_complex(ACPI_IORT_NODE *);
+static void acpi_print_iort_smmuv1v2(ACPI_IORT_NODE *);
+static void acpi_print_iort_smmuv3(ACPI_IORT_NODE *);
+
+struct iort_node_list {
+	uint8_t	Type;
+	const char *gname;
+	void (*func)(ACPI_IORT_NODE *);
+} iort_node_list [] = {
+#define NDMAC(name)	ACPI_IORT_NODE_## name
+#define PRFN(name)	acpi_print_iort_## name
+	{ NDMAC(ITS_GROUP),	   "ITS group",       PRFN(its_group)},
+	{ NDMAC(NAMED_COMPONENT),  "Named component", PRFN(named_component)},
+	{ NDMAC(PCI_ROOT_COMPLEX), "Root complex",    PRFN(root_complex)},
+	{ NDMAC(SMMU),		   "SMMUv1 or v2",    PRFN(smmuv1v2)},
+	{ NDMAC(SMMU_V3),	   "SMMUv3",	      PRFN(smmuv3)},
+	{ 255, NULL, NULL},
+#undef NDMAC
+#undef PRFN
+};
+
+static void
+acpi_print_iort_memory_access(ACPI_IORT_MEMORY_ACCESS *memacc)
+{
+
+	printf("\tMemory Access={\n");
+	printf("\t\tCacheCoherency=");
+	switch (memacc->CacheCoherency) {
+	case ACPI_IORT_NODE_COHERENT:
+		printf("Fully coherent\n");
+		break;
+	case ACPI_IORT_NODE_NOT_COHERENT:
+		printf("Not coherent\n");
+		break;
+	default:
+		printf("resrved (%u)\n", memacc->CacheCoherency);
+		break;
+	}
+	printf("\t\tAllocation Hints=");
+#define	PRINTFLAG(var, flag)	printflag((var), ACPI_IORT_HT_## flag, #flag)
+		PRINTFLAG(memacc->Hints, TRANSIENT);
+		PRINTFLAG(memacc->Hints, WRITE);
+		PRINTFLAG(memacc->Hints, READ);
+		PRINTFLAG(memacc->Hints, OVERRIDE);
+		PRINTFLAG_END();
+#undef PRINTFLAG
+	printf("\t\tMemory Access Flags=");
+#define	PRINTFLAG(var, flag)	printflag((var), ACPI_IORT_MF_## flag, #flag)
+		PRINTFLAG(memacc->MemoryFlags, COHERENCY);
+		PRINTFLAG(memacc->MemoryFlags, ATTRIBUTES);
+		PRINTFLAG_END();
+#undef PRINTFLAG
+	printf("\t}\n");
+}
+
+static void
+acpi_print_iort_its_group(ACPI_IORT_NODE *node)
+{
+	ACPI_IORT_ITS_GROUP *itsg = (ACPI_IORT_ITS_GROUP *)node->NodeData;
+	uint32_t *idp;
+	unsigned int i;
+
+	idp = itsg->Identifiers;
+	for (i = 0; i < itsg->ItsCount; i++)
+		printf("\tGIC ITS ID=%d\n", idp[i]);
+}
+
+static void
+acpi_print_iort_named_component(ACPI_IORT_NODE *node)
+{
+	ACPI_IORT_NAMED_COMPONENT *ncomp
+	    = (ACPI_IORT_NAMED_COMPONENT *)node->NodeData;
+
+#define	PRINTFLAG(var, flag)	printflag((var), ACPI_IORT_NC_## flag, #flag)
+	printf("\tNode Flags={PASID_BITS=%u",
+	    (ncomp->NodeFlags & ACPI_IORT_NC_PASID_BITS) >> 1);
+	pf_sep = ',';
+	PRINTFLAG(ncomp->NodeFlags, STALL_SUPPORTED);
+	PRINTFLAG_END();
+#undef PRINTFLAG
+	acpi_print_iort_memory_access(
+		(ACPI_IORT_MEMORY_ACCESS *)&ncomp->MemoryProperties);
+	printf("\tMemory address size=%hhu\n", ncomp->MemoryAddressLimit);
+	printf("\tDevice object Name=%s\n", ncomp->DeviceName);
+}
+
+static void
+acpi_print_iort_root_complex(ACPI_IORT_NODE *node)
+{
+	ACPI_IORT_ROOT_COMPLEX *rcmp
+	    = (ACPI_IORT_ROOT_COMPLEX *)node->NodeData;
+
+	acpi_print_iort_memory_access(
+		(ACPI_IORT_MEMORY_ACCESS *)&rcmp->MemoryProperties);
+	printf("\tATS Attribute=%s\n",
+	    (rcmp->AtsAttribute & ACPI_IORT_ATS_SUPPORTED)
+	    ? "supported" : "not supported");
+	printf("\tPCI Segment=%u\n", rcmp->PciSegmentNumber);
+	printf("\tMemory address size limit=%hhu\n", rcmp->MemoryAddressLimit);
+}
+
+static void
+acpi_print_iort_smmuv1v2_intflags(uint32_t flags)
+{
+
+	printf("{Mode=");
+	if (flags & 0x01)
+		printf("edge");
+	else
+		printf("level");
+	printf("}\n");
+}
+
+static void
+acpi_print_iort_smmuv1v2(ACPI_IORT_NODE *node)
+{
+	ACPI_IORT_SMMU *smmu = (ACPI_IORT_SMMU *)node->NodeData;
+	ACPI_IORT_SMMU_GSI *gsi;
+	uint64_t *iarray;
+	unsigned int i;
+
+	printf("\tBase Address=%016jx\n", (uintmax_t)smmu->BaseAddress);
+	printf("\tSpan=%016jx\n", (uintmax_t)smmu->Span);
+	printf("\tModel=");
+	switch (smmu->Model) {
+	case ACPI_IORT_SMMU_V1:
+		printf("Generic SMMUv1\n");
+		break;
+	case ACPI_IORT_SMMU_V2:
+		printf("Generic SMMUv2\n");
+		break;
+	case ACPI_IORT_SMMU_CORELINK_MMU400:
+		printf("Arm Corelink MMU-400\n");
+		break;
+	case ACPI_IORT_SMMU_CORELINK_MMU500:
+		printf("Arm Corelink MMU-500\n");
+		break;
+	case ACPI_IORT_SMMU_CORELINK_MMU401:
+		printf("Arm Corelink MMU-401\n");
+		break;
+	case ACPI_IORT_SMMU_CAVIUM_THUNDERX:
+		printf("Cavium ThunderX SMMUv2\n");
+		break;
+	default:
+		printf("reserved (%u)\n", smmu->Model);
+		break;
+	}
+#define	PRINTFLAG(var, flag)	printflag((var), ACPI_IORT_SMMU_## flag, #flag)
+	printf("\tFlags=");
+	PRINTFLAG(smmu->Flags, DVM_SUPPORTED);
+	PRINTFLAG(smmu->Flags, COHERENT_WALK);
+	PRINTFLAG_END();
+#undef PRINTFLAG
+
+	gsi = (ACPI_IORT_SMMU_GSI *)((vaddr_t)node
+	    + smmu->GlobalInterruptOffset);
+	printf("\tNSgIrpt=%u\n", gsi->NSgIrpt);
+	printf("\tNSgIrptFlags=");
+	acpi_print_iort_smmuv1v2_intflags(gsi->NSgIrptFlags);
+	printf("\tNSgCfgIrpt=%u\n", gsi->NSgCfgIrpt);
+	printf("\tNSgCfgIrptFlags=");
+	acpi_print_iort_smmuv1v2_intflags(gsi->NSgCfgIrptFlags);
+
+	if (smmu->ContextInterruptCount != 0) {
+		iarray = (uint64_t *)((vaddr_t)node
+		    + smmu->ContextInterruptOffset);
+		printf("\tContext Interrupts={\n");
+		for (i = 0; i < smmu->ContextInterruptCount; i++) {
+			printf("\t\tGSIV=%u\n",
+			    (uint32_t)(iarray[i] & 0xffffffff));
+			printf("\t\tFlags=%u\n", (uint32_t)(iarray[i] >> 32));
+		}
+	}
+	if (smmu->PmuInterruptCount != 0) {
+		iarray = (uint64_t *)((vaddr_t)node
+		    + smmu->PmuInterruptOffset);
+		printf("\tPmu Interrupts={\n");
+		for (i = 0; i < smmu->PmuInterruptCount; i++) {
+			printf("\t\tGSIV=%u\n",
+			    (uint32_t)(iarray[i] & 0xffffffff));
+			printf("\t\tFlags=%u\n", (uint32_t)(iarray[i] >> 32));
+		}
+	}
+}
+
+static void
+acpi_print_iort_smmuv3(ACPI_IORT_NODE *node)
+{
+	ACPI_IORT_SMMU_V3 *smmu = (ACPI_IORT_SMMU_V3 *)node->NodeData;
+	uint8_t httuo;
+	
+	printf("\tBase Address=%016jx\n", (uintmax_t)smmu->BaseAddress);
+#define	PRINTFLAG(var, flag)	printflag((var), ACPI_IORT_SMMU_V3_## flag, \
+	    #flag)
+	httuo = __SHIFTOUT(smmu->Flags, ACPI_IORT_SMMU_V3_HTTU_OVERRIDE);
+	printf("\tFlags={HTTU Override=%hhx", httuo);
+	pf_sep = ',';
+	PRINTFLAG(smmu->Flags, HTTU_OVERRIDE);
+	PRINTFLAG(smmu->Flags, COHACC_OVERRIDE);
+	PRINTFLAG(smmu->Flags, PXM_VALID);
+	PRINTFLAG_END();
+#undef PRINTFLAG
+	printf("\tVATOS Address=%016jx\n", (uintmax_t)smmu->VatosAddress);
+	printf("\tModel=");
+	switch (smmu->Model) {
+	case ACPI_IORT_SMMU_V3_GENERIC:
+		printf("Generic SMMUv3\n");
+		break;
+	case ACPI_IORT_SMMU_V3_HISILICON_HI161X:
+		printf("HiSilicon Hi161x SMMU-v3\n");
+		break;
+	case ACPI_IORT_SMMU_V3_CAVIUM_CN99XX:
+		printf("Cavium CN99xx SMMU-v3\n");
+		break;
+	default:
+		printf("reserved (%u)\n", smmu->Model);
+		break;
+	}
+
+	printf("\tEvent GSIV=%u\n", smmu->EventGsiv);
+	printf("\tPRI GSIV=%u\n", smmu->PriGsiv);
+	printf("\tGERR GSIV=%u\n", smmu->GerrGsiv);
+	printf("\tSync GSIV=%u\n", smmu->SyncGsiv);
+	printf("\tProximity domain=%u\n", smmu->Pxm);
+
+	/* XXX should we print the refered contents? */
+	printf("\tDevice ID mapping index=%u\n", smmu->IdMappingIndex);
+}
+
+static void
+acpi_print_iort_node(ACPI_IORT_NODE *node)
+{
+	ACPI_IORT_ID_MAPPING *mapping;
+	uint32_t offset;
+	int datasize;
+	bool dodump = false;
+	struct iort_node_list *list;
+	unsigned int i;
+
+	printf("\tLength=%hu\n", node->Length);
+	printf("\tRevision=%hhu\n", node->Revision);
+	printf("\tType=");
+
+	datasize = node->MappingOffset - offsetof(ACPI_IORT_NODE, NodeData);
+	if (datasize != 0)
+		dodump = true;
+
+	for (list = iort_node_list; list->gname != NULL; list++) {
+		if (node->Type == list->Type) {
+			printf("%s\n", list->gname);
+			if (dodump)
+				(*list->func)(node);
+			break;
+		}
+	}
+	if (list->gname == NULL)
+		printf("reserved (0x%hhx)\n", node->Type);
+
+	printf("\tMappingCount=%u\n", node->MappingCount);
+	if (node->MappingCount == 0)
+		return;
+
+	offset = node->MappingOffset;
+	printf("\tMapping offset=%u\n", offset);
+	for (i = 0; i < node->MappingCount; i++) {
+		mapping = (ACPI_IORT_ID_MAPPING *)((vaddr_t)node + offset);
+		printf("\tMapping={\n");
+		printf("\t\tInput base=%u\n", mapping->InputBase);
+		printf("\t\tCount=%u\n", mapping->IdCount);
+		printf("\t\tOutput base=%u\n", mapping->OutputBase);
+		printf("\t\tOutput reference offset=%u\n",
+		    mapping->OutputReference);
+#define	PRINTFLAG(var, flag)	printflag((var), ACPI_IORT_ID_## flag, #flag)
+		printf("\t\tFlags=");
+		PRINTFLAG(mapping->Flags, SINGLE_MAPPING);
+		PRINTFLAG_END();
+#undef PRINTFLAG
+		printf("\t}\n");
+		offset += sizeof(ACPI_IORT_ID_MAPPING);
+	}
+}
+
+static void
+acpi_handle_iort(ACPI_TABLE_HEADER *sdp)
+{
+	ACPI_TABLE_IORT *iort;
+	ACPI_IORT_NODE *node;
+	unsigned int i;
+
+	printf(BEGIN_COMMENT);
+	acpi_print_sdt(sdp);
+	iort = (ACPI_TABLE_IORT *)sdp;
+	printf("\tIORT Nodes=%u\n", iort->NodeCount);
+	printf("\tNode offset=%u\n", iort->NodeOffset);
+
+	node = (ACPI_IORT_NODE *)((vaddr_t)iort + iort->NodeOffset);
+	for (i = 0; i < iort->NodeCount; i++) {
+		printf("\n");
+		acpi_print_iort_node(node);
+
+		/* Next */
+		node = (ACPI_IORT_NODE *)((vaddr_t)node + node->Length);
+	}
+	
+	printf(END_COMMENT);
+}
+
 static void
 acpi_print_native_lpit(ACPI_LPIT_NATIVE *nl)
 {
@@ -3956,6 +4271,8 @@ acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp
 			acpi_handle_hest(sdp);
 		else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
 			acpi_handle_hpet(sdp);
+		else if (!memcmp(sdp->Signature, ACPI_SIG_IORT, 4))
+			acpi_handle_iort(sdp);
 		else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
 			acpi_handle_ecdt(sdp);
 		else if (!memcmp(sdp->Signature, ACPI_SIG_LPIT, 4))

Index: src/usr.sbin/acpitools/acpidump/acpidump.8
diff -u src/usr.sbin/acpitools/acpidump/acpidump.8:1.14 src/usr.sbin/acpitools/acpidump/acpidump.8:1.15
--- src/usr.sbin/acpitools/acpidump/acpidump.8:1.14	Mon Nov  5 07:39:57 2018
+++ src/usr.sbin/acpitools/acpidump/acpidump.8	Sun Dec  2 10:51:07 2018
@@ -1,4 +1,4 @@
-.\" $NetBSD: acpidump.8,v 1.14 2018/11/05 07:39:57 msaitoh Exp $
+.\" $NetBSD: acpidump.8,v 1.15 2018/12/02 10:51:07 msaitoh Exp $
 .\" ACPI (ACPI Package)
 .\"
 .\" Copyright (c) 1999 Doug Rabson <d...@freebsd.org>
@@ -30,7 +30,7 @@
 .\"
 .\" $FreeBSD: head/usr.sbin/acpi/acpidump/acpidump.8 267668 2014-06-20 09:57:27Z bapt $
 .\"
-.Dd November 5, 2018
+.Dd December 2, 2018
 .Dt ACPIDUMP 8
 .Os
 .Sh NAME
@@ -113,6 +113,7 @@ utility dumps contents of the following 
 .It GTDT
 .It HEST
 .It HPET
+.It IORT
 .It LPIT
 .It MADT
 .It MCFG

Reply via email to