Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/acpitools/acpidump Decode IO Remapping Table.



details:   https://anonhg.NetBSD.org/src/rev/af2065952b6f
branches:  trunk
changeset: 446361:af2065952b6f
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Sun Dec 02 10:51:07 2018 +0000

description:
Decode IO Remapping Table.

diffstat:

 usr.sbin/acpitools/acpidump/acpi.c     |  321 ++++++++++++++++++++++++++++++++-
 usr.sbin/acpitools/acpidump/acpidump.8 |    5 +-
 2 files changed, 322 insertions(+), 4 deletions(-)

diffs (truncated from 382 to 300 lines):

diff -r 3124b87d9c33 -r af2065952b6f usr.sbin/acpitools/acpidump/acpi.c
--- a/usr.sbin/acpitools/acpidump/acpi.c        Sun Dec 02 10:27:58 2018 +0000
+++ b/usr.sbin/acpitools/acpidump/acpi.c        Sun Dec 02 10:51:07 2018 +0000
@@ -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_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 @@
        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;



Home | Main Index | Thread Index | Old Index