diff options
Diffstat (limited to 'sys/contrib/dev/acpica/compiler/dttable1.c')
-rw-r--r-- | sys/contrib/dev/acpica/compiler/dttable1.c | 883 |
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); +} |