aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/dev/acpica/compiler/dttable1.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/compiler/dttable1.c')
-rw-r--r--sys/contrib/dev/acpica/compiler/dttable1.c883
1 files changed, 874 insertions, 9 deletions
diff --git a/sys/contrib/dev/acpica/compiler/dttable1.c b/sys/contrib/dev/acpica/compiler/dttable1.c
index 0fab7d880724..391bff98210d 100644
--- a/sys/contrib/dev/acpica/compiler/dttable1.c
+++ b/sys/contrib/dev/acpica/compiler/dttable1.c
@@ -8,7 +8,7 @@
*
* 1. Copyright Notice
*
- * Some or all of this work - Copyright (c) 1999 - 2022, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
* All rights reserved.
*
* 2. License
@@ -206,7 +206,14 @@ DtCompileAest (
UINT32 i;
UINT32 Offset;
DT_FIELD **PFieldList = (DT_FIELD **) List;
+ ACPI_AEST_NODE_INTERFACE_HEADER *AestNodeHeader;
+ UINT8 Revision;
+ ACPI_TABLE_HEADER *Header;
+ ParentTable = DtPeekSubtable ();
+
+ Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
+ Revision = Header->Revision;
while (*PFieldList)
{
@@ -257,8 +264,21 @@ DtCompileAest (
break;
case ACPI_AEST_VENDOR_ERROR_NODE:
+ switch (Revision)
+ {
+ case 1:
+ InfoTable = AcpiDmTableInfoAestVendorError;
+ break;
- InfoTable = AcpiDmTableInfoAestVendorError;
+ case 2:
+ InfoTable = AcpiDmTableInfoAestVendorV2Error;
+ break;
+
+ default:
+ AcpiOsPrintf ("Unknown AEST Vendor Error Revision: %X\n",
+ Revision);
+ return (AE_ERROR);
+ }
break;
case ACPI_AEST_GIC_ERROR_NODE:
@@ -266,6 +286,16 @@ DtCompileAest (
InfoTable = AcpiDmTableInfoAestGicError;
break;
+ case ACPI_AEST_PCIE_ERROR_NODE:
+
+ InfoTable = AcpiDmTableInfoAestPCIeError;
+ break;
+
+ case ACPI_AEST_PROXY_ERROR_NODE:
+
+ InfoTable = AcpiDmTableInfoAestProxyError;
+ break;
+
/* Error case below */
default:
AcpiOsPrintf ("Unknown AEST Subtable Type: %X\n",
@@ -341,9 +371,57 @@ DtCompileAest (
}
/* Compile the (required) node interface structure */
+ if (Revision == 1)
+ {
+ InfoTable = AcpiDmTableInfoAestXface;
+ }
+ else if (Revision == 2)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXfaceHeader,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
- Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXface,
- &Subtable);
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ Offset += Subtable->Length;
+
+ AestNodeHeader = ACPI_CAST_PTR (ACPI_AEST_NODE_INTERFACE_HEADER,
+ Subtable->Buffer);
+
+ switch (AestNodeHeader->GroupFormat)
+ {
+ case ACPI_AEST_NODE_GROUP_FORMAT_4K:
+
+ InfoTable = AcpiDmTableInfoAestXface4k;
+ break;
+
+ case ACPI_AEST_NODE_GROUP_FORMAT_16K:
+
+ InfoTable = AcpiDmTableInfoAestXface16k;
+ break;
+
+ case ACPI_AEST_NODE_GROUP_FORMAT_64K:
+
+ InfoTable = AcpiDmTableInfoAestXface64k;
+ break;
+
+ /* Error case below */
+ default:
+ AcpiOsPrintf ("Unknown AEST Interface Group Format: %X\n",
+ AestNodeHeader->GroupFormat);
+ return (AE_ERROR);
+ }
+ }
+ else
+ {
+ AcpiOsPrintf ("Unknown AEST Revision: %X\n", Revision);
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
@@ -367,8 +445,22 @@ DtCompileAest (
for (i = 0; i < ErrorNodeHeader->NodeInterruptCount; i++)
{
- Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXrupt,
- &Subtable);
+ switch (Revision) {
+ case 1:
+
+ InfoTable = AcpiDmTableInfoAestXrupt;
+ break;
+
+ case 2:
+
+ InfoTable = AcpiDmTableInfoAestXruptV2;
+ break;
+
+ default:
+ AcpiOsPrintf ("Unknown AEST Revision: %X\n", Revision);
+ return (AE_ERROR);
+ }
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
@@ -654,6 +746,218 @@ DtCompileAsf (
return (AE_OK);
}
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileAspt
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile ASPT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileAspt (
+ void **List)
+{
+ ACPI_ASPT_HEADER *AsptTable;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ ACPI_DMTABLE_INFO *InfoTable;
+ ACPI_STATUS Status;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoAspt, &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsptHdr,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ AsptTable = ACPI_CAST_PTR (ACPI_ASPT_HEADER, Subtable->Buffer);
+
+ switch (AsptTable->Type) /* Mask off top bit */
+ {
+ case ACPI_ASPT_TYPE_GLOBAL_REGS:
+
+ InfoTable = AcpiDmTableInfoAspt0;
+ break;
+
+ case ACPI_ASPT_TYPE_SEV_MBOX_REGS:
+
+ InfoTable = AcpiDmTableInfoAspt1;
+ break;
+
+ case ACPI_ASPT_TYPE_ACPI_MBOX_REGS:
+
+ InfoTable = AcpiDmTableInfoAspt2;
+ break;
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASPT");
+ return (AE_ERROR);
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileCdat
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile CDAT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileCdat (
+ void **List)
+{
+ ACPI_STATUS Status = AE_OK;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ ACPI_CDAT_HEADER *CdatHeader;
+ ACPI_DMTABLE_INFO *InfoTable = NULL;
+ DT_FIELD *SubtableStart;
+
+
+ /* Walk the parse tree.
+ *
+ * Note: Main table consists of only the CDAT table header
+ * (This is not the standard ACPI table header, however)--
+ * Followed by some number of subtables.
+ */
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+
+ /* Compile the expected CDAT Subtable header */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatHeader,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ CdatHeader = ACPI_CAST_PTR (ACPI_CDAT_HEADER, Subtable->Buffer);
+
+ /* Decode the subtable by type */
+
+ switch (CdatHeader->Type)
+ {
+ case ACPI_CDAT_TYPE_DSMAS:
+ InfoTable = AcpiDmTableInfoCdat0;
+ break;
+
+ case ACPI_CDAT_TYPE_DSLBIS:
+ InfoTable = AcpiDmTableInfoCdat1;
+ break;
+
+ case ACPI_CDAT_TYPE_DSMSCIS:
+ InfoTable = AcpiDmTableInfoCdat2;
+ break;
+
+ case ACPI_CDAT_TYPE_DSIS:
+ InfoTable = AcpiDmTableInfoCdat3;
+ break;
+
+ case ACPI_CDAT_TYPE_DSEMTS:
+ InfoTable = AcpiDmTableInfoCdat4;
+ break;
+
+ case ACPI_CDAT_TYPE_SSLBIS:
+ InfoTable = AcpiDmTableInfoCdat5;
+ break;
+
+ default:
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CDAT");
+ }
+
+ /* Compile the CDAT subtable */
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ switch (CdatHeader->Type)
+ {
+ /* Multiple entries supported for this type */
+
+ case ACPI_CDAT_TYPE_SSLBIS:
+
+ /*
+ * Check for multiple SSLBEs
+ */
+ while (*PFieldList && !AcpiUtStricmp ((*PFieldList)->Name, "Port X ID"))
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatEntries, &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Pop off the CDAT Subtable header subtree */
+
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
/******************************************************************************
*
@@ -727,7 +1031,7 @@ DtCompileCedt (
/* Look in buffer for the number of targets */
offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CFMWS, InterleaveWays);
dump = (unsigned char *) Subtable->Buffer - 4; /* place at beginning of cedt1 */
- max = 0x01 << dump[offset]; /* 2^max, so 0=1, 1=2, 2=4, 3=8. 8 is MAX */
+ max = 0x01 << dump[offset]; /* 2^max, so 0=1, 1=2, 2=4, 3=8. 8 is MAX */
if (max > 8) max=1; /* Error in encoding Interleaving Ways. */
if (max == 1) /* if only one target, then break here. */
break; /* break if only one target. */
@@ -762,6 +1066,53 @@ DtCompileCedt (
ParentTable = DtPeekSubtable ();
break;
}
+ case ACPI_CEDT_TYPE_CXIMS: {
+ unsigned char *dump;
+ unsigned int idx, offset, max = 0;
+
+ /* Compile table with first "Xor map" */
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt2, &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Look in buffer for the number of Xor maps */
+ offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CXIMS, NrXormaps);
+ dump = (unsigned char *) Subtable->Buffer - 4; /* place at beginning of cedt2 */
+ max = dump[offset];
+
+ /* We need to add more XOR maps, so write the current Subtable. */
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable); /* Insert AcpiDmTableInfoCedt2 table so we can put in */
+ DtPushSubtable (Subtable);
+
+ /* Now, find out all Xor maps beyond the first. */
+
+ for (idx = 1; idx < max; idx++) {
+ ParentTable = DtPeekSubtable ();
+
+ if (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt2_te, &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (Subtable)
+ {
+ DtInsertSubtable (ParentTable, Subtable); /* got an Xor map, so insert table. */
+ InsertFlag = 0;
+ }
+ }
+ }
+
+ DtPopSubtable ();
+ ParentTable = DtPeekSubtable ();
+ break;
+ }
default:
DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT");
@@ -1156,6 +1507,11 @@ DtCompileDmar (
InfoTable = AcpiDmTableInfoDmar5;
break;
+ case ACPI_DMAR_TYPE_SIDP:
+
+ InfoTable = AcpiDmTableInfoDmar6;
+ break;
+
default:
DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
@@ -1397,6 +1753,265 @@ DtCompileEinj (
/******************************************************************************
*
+ * FUNCTION: DtCompileErdt
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile ERST. Complex table with subtables and subsubtables.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileErdt (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable, *RmddSubtable = NULL, *Subsubtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ ACPI_SUBTBL_HDR_16 *ErdtHeader;
+ ACPI_DMTABLE_INFO *InfoTable;
+ ACPI_ERDT_MMRC *Mmrc;
+ ACPI_ERDT_IBRD *Ibrd;
+ UINT32 NumEntries;
+ BOOLEAN SeenRmdd = FALSE;
+ BOOLEAN SeenSubtable = FALSE;
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoErdt,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoErdtHdr,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ErdtHeader = ACPI_CAST_PTR (ACPI_SUBTBL_HDR_16, Subtable->Buffer);
+
+ /* RMDD tables at top level. All others are subtables of preceeding RMDD */
+ if (ErdtHeader->Type == ACPI_ERDT_TYPE_RMDD)
+ {
+ if (SeenRmdd && SeenSubtable)
+ DtPopSubtable ();
+ SeenRmdd = TRUE;
+ SeenSubtable = FALSE;
+ RmddSubtable = Subtable;
+ }
+ else
+ {
+ if (!SeenSubtable)
+ {
+ DtPushSubtable (RmddSubtable);
+ SeenSubtable = TRUE;
+ }
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ switch (ErdtHeader->Type)
+ {
+ case ACPI_ERDT_TYPE_RMDD:
+ InfoTable = AcpiDmTableInfoErdtRmdd;
+ break;
+
+ case ACPI_ERDT_TYPE_CACD:
+ InfoTable = AcpiDmTableInfoErdtCacd;
+ break;
+
+ case ACPI_ERDT_TYPE_DACD:
+ InfoTable = AcpiDmTableInfoErdtDacd;
+ break;
+
+ case ACPI_ERDT_TYPE_CMRC:
+ InfoTable = AcpiDmTableInfoErdtCmrc;
+ break;
+
+ case ACPI_ERDT_TYPE_MMRC:
+ InfoTable = AcpiDmTableInfoErdtMmrc;
+ break;
+
+ case ACPI_ERDT_TYPE_MARC:
+ InfoTable = AcpiDmTableInfoErdtMarc;
+ break;
+
+ case ACPI_ERDT_TYPE_CARC:
+ InfoTable = AcpiDmTableInfoErdtCarc;
+ break;
+
+ case ACPI_ERDT_TYPE_CMRD:
+ InfoTable = AcpiDmTableInfoErdtCmrd;
+ break;
+
+ case ACPI_ERDT_TYPE_IBRD:
+ InfoTable = AcpiDmTableInfoErdtIbrd;
+ break;
+
+ case ACPI_ERDT_TYPE_IBAD:
+ InfoTable = AcpiDmTableInfoErdtIbad;
+ break;
+
+ case ACPI_ERDT_TYPE_CARD:
+ InfoTable = AcpiDmTableInfoErdtCard;
+ break;
+
+ default:
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ERDT");
+ return (AE_ERROR);
+ }
+
+ Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /* Some subtable types end with flex arrays */
+
+ switch (ErdtHeader->Type)
+ {
+ case ACPI_ERDT_TYPE_CACD:
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList,
+ AcpiDmTableInfoErdtCacdX2apic, &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subtable)
+ {
+ break;
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+ break;
+
+ case ACPI_ERDT_TYPE_DACD:
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList,
+ AcpiDmTableInfoErdtDacdScope, &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subtable)
+ {
+ break;
+ }
+
+ DtPushSubtable (Subtable);
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList,
+ AcpiDmTableInfoErdtDacdPath, &Subsubtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subsubtable)
+ {
+ break;
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subsubtable);
+ }
+ DtPopSubtable ();
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+ break;
+
+ case ACPI_ERDT_TYPE_MMRC:
+ Mmrc = ACPI_SUB_PTR (ACPI_ERDT_MMRC, Subtable->Buffer,
+ sizeof(ACPI_SUBTBL_HDR_16));
+ NumEntries = 0;
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList,
+ AcpiDmTableInfoErdtMmrcCorrFactor, &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subtable)
+ {
+ break;
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ NumEntries++;
+ }
+ Mmrc->CorrFactorListLen = NumEntries;
+ break;
+
+ case ACPI_ERDT_TYPE_IBRD:
+ Ibrd = ACPI_SUB_PTR (ACPI_ERDT_IBRD, Subtable->Buffer,
+ sizeof(ACPI_SUBTBL_HDR_16));
+ NumEntries = 0;
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList,
+ AcpiDmTableInfoErdtIbrdCorrFactor, &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subtable)
+ {
+ break;
+ }
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ NumEntries++;
+ }
+ Ibrd->CorrFactorListLen = NumEntries;
+ break;
+
+ default:
+ /* Already checked for valid subtable type above */
+
+ break;
+ }
+ DtPopSubtable ();
+ }
+
+ if (SeenSubtable)
+ {
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
* FUNCTION: DtCompileErst
*
* PARAMETERS: List - Current field list pointer
@@ -1882,7 +2497,7 @@ DtCompileHmat (
DtInsertSubtable (ParentTable, Subtable);
HmatStruct->Length += Subtable->Length;
- /* Compile HMAT structure additionals */
+ /* Compile HMAT structure additional */
switch (HmatStruct->Type)
{
@@ -2592,7 +3207,6 @@ DtCompileIvrs (
DtInsertSubtable (MainSubtable, Subtable);
DtPushSubtable (Subtable);
- ParentTable = MainSubtable;
break;
case ACPI_IVRS_TYPE_HID:
@@ -2729,3 +3343,254 @@ DtCompileIvrs (
return (AE_OK);
}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileRimt
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile RIMT.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileRimt (
+ void **List)
+{
+ ACPI_RIMT_PLATFORM_DEVICE *PlatDevNode;
+ ACPI_RIMT_PCIE_RC *PcieRcNode;
+ ACPI_TABLE_RIMT *Rimt;
+ ACPI_RIMT_IOMMU *IommuNode;
+ ACPI_RIMT_NODE *RimtNode;
+ ACPI_STATUS Status;
+ DT_SUBTABLE *Subtable;
+ DT_SUBTABLE *ParentTable;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ DT_FIELD *SubtableStart;
+ UINT32 NodeNumber;
+ UINT32 NodeLength;
+ UINT16 IdMappingNumber;
+ UINT32 i;
+
+
+ ParentTable = DtPeekSubtable ();
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimt, &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /*
+ * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
+ * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
+ */
+ Rimt = ACPI_SUB_PTR (ACPI_TABLE_RIMT, Subtable->Buffer,
+ sizeof (ACPI_TABLE_HEADER));
+
+ NodeNumber = 0;
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtNodeHdr, &Subtable);
+
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ RimtNode = ACPI_CAST_PTR (ACPI_RIMT_NODE, Subtable->Buffer);
+ NodeLength = ACPI_OFFSET (ACPI_RIMT_NODE, NodeData);
+
+ DtPushSubtable (Subtable);
+ ParentTable = DtPeekSubtable ();
+
+ switch (RimtNode->Type)
+ {
+ case ACPI_RIMT_NODE_TYPE_IOMMU:
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtIommu,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ IommuNode = ACPI_CAST_PTR (ACPI_RIMT_IOMMU, Subtable->Buffer);
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength += Subtable->Length;
+
+ for (i = 0; i < IommuNode->NumInterruptWires; i++)
+ {
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList,
+ AcpiDmTableInfoRimtIommuWire,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (!Subtable)
+ {
+ break;
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength += Subtable->Length;
+ }
+ }
+
+ break;
+
+ case ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX:
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPcieRc,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ PcieRcNode = ACPI_CAST_PTR (ACPI_RIMT_PCIE_RC, Subtable->Buffer);
+ NodeLength += Subtable->Length;
+
+ /* Compile Array of ID mappings */
+
+ PcieRcNode->IdMappingOffset = (UINT16) NodeLength;
+ IdMappingNumber = 0;
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList,
+ AcpiDmTableInfoRimtIdMapping,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (!Subtable)
+ {
+ break;
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength += sizeof (ACPI_RIMT_ID_MAPPING);
+ IdMappingNumber++;
+ }
+
+ PcieRcNode->NumIdMappings = IdMappingNumber;
+ if (!IdMappingNumber)
+ {
+ PcieRcNode->IdMappingOffset = 0;
+ }
+
+ break;
+
+ case ACPI_RIMT_NODE_TYPE_PLAT_DEVICE:
+
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPlatDev,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ PlatDevNode = ACPI_CAST_PTR (ACPI_RIMT_PLATFORM_DEVICE, Subtable->Buffer);
+ NodeLength += Subtable->Length;
+
+ /*
+ * Padding - Variable-length data
+ * Optionally allows the offset of the ID mappings to be used
+ * for filling this field.
+ */
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPlatDevPad,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (Subtable)
+ {
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength += Subtable->Length;
+ }
+ else
+ {
+ if (NodeLength > PlatDevNode->IdMappingOffset)
+ {
+ return (AE_BAD_DATA);
+ }
+
+ if (NodeLength < PlatDevNode->IdMappingOffset)
+ {
+ Status = DtCompilePadding (
+ PlatDevNode->IdMappingOffset - (UINT16) NodeLength,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength = PlatDevNode->IdMappingOffset;
+ }
+ }
+
+ /* Compile Array of ID mappings */
+
+ PlatDevNode->IdMappingOffset = (UINT16) NodeLength;
+ IdMappingNumber = 0;
+ while (*PFieldList)
+ {
+ Status = DtCompileTable (PFieldList,
+ AcpiDmTableInfoRimtIdMapping,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ if (!Subtable)
+ {
+ break;
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ NodeLength += sizeof (ACPI_RIMT_ID_MAPPING);
+ IdMappingNumber++;
+ }
+
+ PlatDevNode->NumIdMappings = IdMappingNumber;
+ if (!IdMappingNumber)
+ {
+ PlatDevNode->IdMappingOffset = 0;
+ }
+
+ break;
+
+
+ default:
+
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RIMT");
+ return (AE_ERROR);
+ }
+
+ DtPopSubtable ();
+ ParentTable = DtPeekSubtable ();
+ NodeNumber++;
+ }
+
+ Rimt->NumNodes = NodeNumber;
+ return (AE_OK);
+}