Home | History | Annotate | Line # | Download | only in compiler
      1 /******************************************************************************
      2  *
      3  * Module Name: dttable1.c - handling for specific ACPI tables
      4  *
      5  *****************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
     12  * All rights reserved.
     13  *
     14  * 2. License
     15  *
     16  * 2.1. This is your license from Intel Corp. under its intellectual property
     17  * rights. You may have additional license terms from the party that provided
     18  * you this software, covering your right to use that party's intellectual
     19  * property rights.
     20  *
     21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     22  * copy of the source code appearing in this file ("Covered Code") an
     23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     24  * base code distributed originally by Intel ("Original Intel Code") to copy,
     25  * make derivatives, distribute, use and display any portion of the Covered
     26  * Code in any form, with the right to sublicense such rights; and
     27  *
     28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     29  * license (with the right to sublicense), under only those claims of Intel
     30  * patents that are infringed by the Original Intel Code, to make, use, sell,
     31  * offer to sell, and import the Covered Code and derivative works thereof
     32  * solely to the minimum extent necessary to exercise the above copyright
     33  * license, and in no event shall the patent license extend to any additions
     34  * to or modifications of the Original Intel Code. No other license or right
     35  * is granted directly or by implication, estoppel or otherwise;
     36  *
     37  * The above copyright and patent license is granted only if the following
     38  * conditions are met:
     39  *
     40  * 3. Conditions
     41  *
     42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     43  * Redistribution of source code of any substantial portion of the Covered
     44  * Code or modification with rights to further distribute source must include
     45  * the above Copyright Notice, the above License, this list of Conditions,
     46  * and the following Disclaimer and Export Compliance provision. In addition,
     47  * Licensee must cause all Covered Code to which Licensee contributes to
     48  * contain a file documenting the changes Licensee made to create that Covered
     49  * Code and the date of any change. Licensee must include in that file the
     50  * documentation of any changes made by any predecessor Licensee. Licensee
     51  * must include a prominent statement that the modification is derived,
     52  * directly or indirectly, from Original Intel Code.
     53  *
     54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     55  * Redistribution of source code of any substantial portion of the Covered
     56  * Code or modification without rights to further distribute source must
     57  * include the following Disclaimer and Export Compliance provision in the
     58  * documentation and/or other materials provided with distribution. In
     59  * addition, Licensee may not authorize further sublicense of source of any
     60  * portion of the Covered Code, and must include terms to the effect that the
     61  * license from Licensee to its licensee is limited to the intellectual
     62  * property embodied in the software Licensee provides to its licensee, and
     63  * not to intellectual property embodied in modifications its licensee may
     64  * make.
     65  *
     66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     67  * substantial portion of the Covered Code or modification must reproduce the
     68  * above Copyright Notice, and the following Disclaimer and Export Compliance
     69  * provision in the documentation and/or other materials provided with the
     70  * distribution.
     71  *
     72  * 3.4. Intel retains all right, title, and interest in and to the Original
     73  * Intel Code.
     74  *
     75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     76  * Intel shall be used in advertising or otherwise to promote the sale, use or
     77  * other dealings in products derived from or relating to the Covered Code
     78  * without prior written authorization from Intel.
     79  *
     80  * 4. Disclaimer and Export Compliance
     81  *
     82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
     85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
     86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
     87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     88  * PARTICULAR PURPOSE.
     89  *
     90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
     96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     97  * LIMITED REMEDY.
     98  *
     99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    100  * software or system incorporating such software without first obtaining any
    101  * required license or other approval from the U. S. Department of Commerce or
    102  * any other agency or department of the United States Government. In the
    103  * event Licensee exports any such software from the United States or
    104  * re-exports any such software from a foreign destination, Licensee shall
    105  * ensure that the distribution and export/re-export of the software is in
    106  * compliance with all laws, regulations, orders, or other restrictions of the
    107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    108  * any of its subsidiaries will export/re-export any technical data, process,
    109  * software, or service, directly or indirectly, to any country for which the
    110  * United States government or any agency thereof requires an export license,
    111  * other governmental approval, or letter of assurance, without first obtaining
    112  * such license, approval or letter.
    113  *
    114  *****************************************************************************
    115  *
    116  * Alternatively, you may choose to be licensed under the terms of the
    117  * following license:
    118  *
    119  * Redistribution and use in source and binary forms, with or without
    120  * modification, are permitted provided that the following conditions
    121  * are met:
    122  * 1. Redistributions of source code must retain the above copyright
    123  *    notice, this list of conditions, and the following disclaimer,
    124  *    without modification.
    125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    126  *    substantially similar to the "NO WARRANTY" disclaimer below
    127  *    ("Disclaimer") and any redistribution must be conditioned upon
    128  *    including a substantially similar Disclaimer requirement for further
    129  *    binary redistribution.
    130  * 3. Neither the names of the above-listed copyright holders nor the names
    131  *    of any contributors may be used to endorse or promote products derived
    132  *    from this software without specific prior written permission.
    133  *
    134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    145  *
    146  * Alternatively, you may choose to be licensed under the terms of the
    147  * GNU General Public License ("GPL") version 2 as published by the Free
    148  * Software Foundation.
    149  *
    150  *****************************************************************************/
    151 
    152 /* Compile all complex data tables, signatures starting with A-I */
    153 
    154 #include "aslcompiler.h"
    155 
    156 #define _COMPONENT          DT_COMPILER
    157         ACPI_MODULE_NAME    ("dttable1")
    158 
    159 
    160 static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
    161 {
    162     {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
    163     {ACPI_DMT_EXIT,     0,               NULL, 0}
    164 };
    165 
    166 static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
    167 {
    168     {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
    169     {ACPI_DMT_EXIT,     0,               NULL, 0}
    170 };
    171 
    172 
    173 /******************************************************************************
    174  *
    175  * FUNCTION:    DtCompileAest
    176  *
    177  * PARAMETERS:  List                - Current field list pointer
    178  *
    179  * RETURN:      Status
    180  *
    181  * DESCRIPTION: Compile AEST.
    182  *
    183  * NOTE: Assumes the following table structure:
    184  *      For all AEST Error Nodes:
    185  *          1) An AEST Error Node, followed immediately by:
    186  *          2) Any node-specific data
    187  *          3) An Interface Structure (one)
    188  *          4) A list (array) of Interrupt Structures, the count as specified
    189  *              in the NodeInterruptCount field of the Error Node header.
    190  *
    191  * AEST - ARM Error Source table. Conforms to:
    192  * ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document Sep 2020
    193  *
    194  *****************************************************************************/
    195 
    196 ACPI_STATUS
    197 DtCompileAest (
    198     void                    **List)
    199 {
    200     ACPI_AEST_HEADER        *ErrorNodeHeader;
    201     ACPI_AEST_PROCESSOR     *AestProcessor;
    202     DT_SUBTABLE             *Subtable;
    203     DT_SUBTABLE             *ParentTable;
    204     ACPI_DMTABLE_INFO       *InfoTable;
    205     ACPI_STATUS             Status;
    206     UINT32                  i;
    207     UINT32                  Offset;
    208     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    209     ACPI_AEST_NODE_INTERFACE_HEADER *AestNodeHeader;
    210     UINT8                   Revision;
    211     ACPI_TABLE_HEADER       *Header;
    212 
    213     ParentTable = DtPeekSubtable ();
    214 
    215     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
    216     Revision = Header->Revision;
    217 
    218     while (*PFieldList)
    219     {
    220         /* Compile the common error node header */
    221 
    222         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestHdr,
    223             &Subtable);
    224         if (ACPI_FAILURE (Status))
    225         {
    226             return (Status);
    227         }
    228 
    229         ParentTable = DtPeekSubtable ();
    230         DtInsertSubtable (ParentTable, Subtable);
    231 
    232         /* Everything past the error node header will be a subtable */
    233 
    234         DtPushSubtable (Subtable);
    235 
    236         /*
    237          * Compile the node-specific structure (Based on the error
    238          * node header Type field)
    239          */
    240         ErrorNodeHeader = ACPI_CAST_PTR (ACPI_AEST_HEADER, Subtable->Buffer);
    241 
    242         /* Point past the common error node header */
    243 
    244         Offset = sizeof (ACPI_AEST_HEADER);
    245         ErrorNodeHeader->NodeSpecificOffset = Offset;
    246 
    247         /* Decode the error node type */
    248 
    249         switch (ErrorNodeHeader->Type)
    250         {
    251         case ACPI_AEST_PROCESSOR_ERROR_NODE:
    252 
    253             InfoTable = AcpiDmTableInfoAestProcError;
    254             break;
    255 
    256         case ACPI_AEST_MEMORY_ERROR_NODE:
    257 
    258             InfoTable = AcpiDmTableInfoAestMemError;
    259             break;
    260 
    261         case ACPI_AEST_SMMU_ERROR_NODE:
    262 
    263             InfoTable = AcpiDmTableInfoAestSmmuError;
    264             break;
    265 
    266         case ACPI_AEST_VENDOR_ERROR_NODE:
    267             switch (Revision)
    268             {
    269             case 1:
    270                 InfoTable = AcpiDmTableInfoAestVendorError;
    271                 break;
    272 
    273             case 2:
    274                 InfoTable = AcpiDmTableInfoAestVendorV2Error;
    275                 break;
    276 
    277             default:
    278                 AcpiOsPrintf ("Unknown AEST Vendor Error Revision: %X\n",
    279                     Revision);
    280                 return (AE_ERROR);
    281             }
    282             break;
    283 
    284         case ACPI_AEST_GIC_ERROR_NODE:
    285 
    286             InfoTable = AcpiDmTableInfoAestGicError;
    287             break;
    288 
    289         case ACPI_AEST_PCIE_ERROR_NODE:
    290 
    291             InfoTable = AcpiDmTableInfoAestPCIeError;
    292             break;
    293 
    294         case ACPI_AEST_PROXY_ERROR_NODE:
    295 
    296             InfoTable = AcpiDmTableInfoAestProxyError;
    297             break;
    298 
    299         /* Error case below */
    300         default:
    301             AcpiOsPrintf ("Unknown AEST Subtable Type: %X\n",
    302                 ErrorNodeHeader->Type);
    303             return (AE_ERROR);
    304         }
    305 
    306         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    307         if (ACPI_FAILURE (Status))
    308         {
    309             return (Status);
    310         }
    311 
    312         /* Point past the node-specific structure */
    313 
    314         Offset += Subtable->Length;
    315         ErrorNodeHeader->NodeInterfaceOffset = Offset;
    316 
    317         ParentTable = DtPeekSubtable ();
    318         DtInsertSubtable (ParentTable, Subtable);
    319 
    320         /* Compile any additional node-specific substructures */
    321 
    322         if (ErrorNodeHeader->Type == ACPI_AEST_PROCESSOR_ERROR_NODE)
    323         {
    324             /*
    325              * Special handling for PROCESSOR_ERROR_NODE subtables
    326              * (to handle the Resource Substructure via the ResourceType
    327              * field).
    328              */
    329             AestProcessor = ACPI_CAST_PTR (ACPI_AEST_PROCESSOR,
    330                 Subtable->Buffer);
    331 
    332             switch (AestProcessor->ResourceType)
    333             {
    334             case ACPI_AEST_CACHE_RESOURCE:
    335 
    336                 InfoTable = AcpiDmTableInfoAestCacheRsrc;
    337                 break;
    338 
    339             case ACPI_AEST_TLB_RESOURCE:
    340 
    341                 InfoTable = AcpiDmTableInfoAestTlbRsrc;
    342                 break;
    343 
    344             case ACPI_AEST_GENERIC_RESOURCE:
    345 
    346                 InfoTable = AcpiDmTableInfoAestGenRsrc;
    347                 AcpiOsPrintf ("Generic Resource Type (%X) is not supported at this time\n",
    348                     AestProcessor->ResourceType);
    349                 return (AE_ERROR);
    350 
    351             /* Error case below */
    352             default:
    353                 AcpiOsPrintf ("Unknown AEST Processor Resource Type: %X\n",
    354                     AestProcessor->ResourceType);
    355                 return (AE_ERROR);
    356             }
    357 
    358             Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    359             if (ACPI_FAILURE (Status))
    360             {
    361                 return (Status);
    362             }
    363 
    364             /* Point past the resource substructure subtable */
    365 
    366             Offset += Subtable->Length;
    367             ErrorNodeHeader->NodeInterfaceOffset = Offset;
    368 
    369             ParentTable = DtPeekSubtable ();
    370             DtInsertSubtable (ParentTable, Subtable);
    371         }
    372 
    373         /* Compile the (required) node interface structure */
    374         if (Revision == 1)
    375         {
    376             InfoTable = AcpiDmTableInfoAestXface;
    377         }
    378         else if (Revision == 2)
    379         {
    380             Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXfaceHeader,
    381                 &Subtable);
    382             if (ACPI_FAILURE (Status))
    383             {
    384                 return (Status);
    385             }
    386 
    387             ParentTable = DtPeekSubtable ();
    388             DtInsertSubtable (ParentTable, Subtable);
    389 
    390             Offset += Subtable->Length;
    391 
    392             AestNodeHeader = ACPI_CAST_PTR (ACPI_AEST_NODE_INTERFACE_HEADER,
    393                     Subtable->Buffer);
    394 
    395             switch (AestNodeHeader->GroupFormat)
    396             {
    397             case ACPI_AEST_NODE_GROUP_FORMAT_4K:
    398 
    399                 InfoTable = AcpiDmTableInfoAestXface4k;
    400                 break;
    401 
    402             case ACPI_AEST_NODE_GROUP_FORMAT_16K:
    403 
    404                 InfoTable = AcpiDmTableInfoAestXface16k;
    405                 break;
    406 
    407             case ACPI_AEST_NODE_GROUP_FORMAT_64K:
    408 
    409                 InfoTable = AcpiDmTableInfoAestXface64k;
    410                 break;
    411 
    412             /* Error case below */
    413             default:
    414                 AcpiOsPrintf ("Unknown AEST Interface Group Format: %X\n",
    415                     AestNodeHeader->GroupFormat);
    416                 return (AE_ERROR);
    417             }
    418         }
    419         else
    420         {
    421            AcpiOsPrintf ("Unknown AEST Revision: %X\n", Revision);
    422         }
    423 
    424         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    425         if (ACPI_FAILURE (Status))
    426         {
    427             return (Status);
    428         }
    429 
    430         ErrorNodeHeader->NodeInterruptOffset = 0;
    431         ParentTable = DtPeekSubtable ();
    432         DtInsertSubtable (ParentTable, Subtable);
    433 
    434         /* Compile each of the node interrupt structures */
    435 
    436         if (ErrorNodeHeader->NodeInterruptCount)
    437         {
    438             /* Point to the first interrupt structure */
    439 
    440             Offset += Subtable->Length;
    441             ErrorNodeHeader->NodeInterruptOffset = Offset;
    442         }
    443 
    444         /* Compile each of the interrupt structures */
    445 
    446         for (i = 0; i < ErrorNodeHeader->NodeInterruptCount; i++)
    447         {
    448             switch (Revision) {
    449             case 1:
    450 
    451                 InfoTable = AcpiDmTableInfoAestXrupt;
    452                 break;
    453 
    454             case 2:
    455 
    456                 InfoTable = AcpiDmTableInfoAestXruptV2;
    457                 break;
    458 
    459             default:
    460                 AcpiOsPrintf ("Unknown AEST Revision: %X\n", Revision);
    461                 return (AE_ERROR);
    462             }
    463             Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    464             if (ACPI_FAILURE (Status))
    465             {
    466                 return (Status);
    467             }
    468 
    469             ParentTable = DtPeekSubtable ();
    470             DtInsertSubtable (ParentTable, Subtable);
    471         }
    472 
    473         /* Prepare for the next AEST Error node */
    474 
    475         DtPopSubtable ();
    476     }
    477 
    478     return (AE_OK);
    479 }
    480 
    481 
    482 /******************************************************************************
    483  *
    484  * FUNCTION:    DtCompileApmt
    485  *
    486  * PARAMETERS:  List                - Current field list pointer
    487  *
    488  * RETURN:      Status
    489  *
    490  * DESCRIPTION: Compile APMT.
    491  *
    492  *****************************************************************************/
    493 
    494 ACPI_STATUS
    495 DtCompileApmt (
    496     void                    **List)
    497 {
    498     ACPI_STATUS             Status;
    499     ACPI_TABLE_HEADER       *Header;
    500     ACPI_APMT_NODE          *ApmtNode;
    501     ACPI_APMT_NODE          *PeerApmtNode;
    502     DT_SUBTABLE             *Subtable;
    503     DT_SUBTABLE             *PeerSubtable;
    504     DT_SUBTABLE             *ParentTable;
    505     DT_FIELD                **PFieldList = (DT_FIELD**)List;
    506     DT_FIELD                *SubtableStart;
    507     UINT32                  CurLength;
    508     char                    MsgBuffer[64] = "";
    509 
    510     ParentTable = DtPeekSubtable();
    511 
    512     Header = ACPI_CAST_PTR(ACPI_TABLE_HEADER, ParentTable->Buffer);
    513 
    514     CurLength = sizeof(ACPI_TABLE_HEADER);
    515 
    516     /* Walk the parse tree */
    517 
    518     while (*PFieldList)
    519     {
    520         /* APMT Node Subtable */
    521 
    522         SubtableStart = *PFieldList;
    523 
    524         Status = DtCompileTable(PFieldList, AcpiDmTableInfoApmtNode, &Subtable);
    525 
    526         if (ACPI_FAILURE(Status))
    527         {
    528             return (Status);
    529         }
    530 
    531         ApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, Subtable->Buffer);
    532 
    533         if (ApmtNode->Length != sizeof(ACPI_APMT_NODE))
    534         {
    535             DtFatal(ASL_MSG_INVALID_LENGTH, SubtableStart, "APMT");
    536             return (AE_ERROR);
    537         }
    538 
    539         if (ApmtNode->Type >= ACPI_APMT_NODE_TYPE_COUNT)
    540         {
    541             snprintf(MsgBuffer, 64, "Node Type : 0x%X", ApmtNode->Type);
    542             DtFatal(ASL_MSG_INVALID_TYPE, SubtableStart, MsgBuffer);
    543             return (AE_ERROR);
    544         }
    545 
    546         PeerSubtable = DtGetNextSubtable(ParentTable, NULL);
    547 
    548         /* Validate the node id needs to be unique. */
    549         while(PeerSubtable)
    550         {
    551             PeerApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, PeerSubtable->Buffer);
    552             if (PeerApmtNode->Id == ApmtNode->Id)
    553             {
    554                 snprintf(MsgBuffer, 64, "Node Id : 0x%X existed", ApmtNode->Id);
    555                 DtFatal(ASL_MSG_DUPLICATE_ITEM, SubtableStart, MsgBuffer);
    556                 return (AE_ERROR);
    557             }
    558 
    559             PeerSubtable = DtGetNextSubtable(ParentTable, PeerSubtable);
    560         }
    561 
    562         CurLength += ApmtNode->Length;
    563 
    564         DtInsertSubtable(ParentTable, Subtable);
    565     }
    566 
    567     if (Header->Length != CurLength)
    568     {
    569         snprintf(MsgBuffer, 64, " - APMT Length : %u (expected: %u)",
    570             Header->Length, CurLength);
    571         DtFatal(ASL_MSG_INVALID_LENGTH, NULL, MsgBuffer);
    572         return (AE_ERROR);
    573     }
    574 
    575     return (AE_OK);
    576 }
    577 
    578 /******************************************************************************
    579  *
    580  * FUNCTION:    DtCompileAsf
    581  *
    582  * PARAMETERS:  List                - Current field list pointer
    583  *
    584  * RETURN:      Status
    585  *
    586  * DESCRIPTION: Compile ASF!.
    587  *
    588  *****************************************************************************/
    589 
    590 ACPI_STATUS
    591 DtCompileAsf (
    592     void                    **List)
    593 {
    594     ACPI_ASF_INFO           *AsfTable;
    595     DT_SUBTABLE             *Subtable;
    596     DT_SUBTABLE             *ParentTable;
    597     ACPI_DMTABLE_INFO       *InfoTable;
    598     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
    599     UINT32                  DataCount = 0;
    600     ACPI_STATUS             Status;
    601     UINT32                  i;
    602     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    603     DT_FIELD                *SubtableStart;
    604 
    605 
    606     while (*PFieldList)
    607     {
    608         SubtableStart = *PFieldList;
    609         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
    610             &Subtable);
    611         if (ACPI_FAILURE (Status))
    612         {
    613             return (Status);
    614         }
    615 
    616         ParentTable = DtPeekSubtable ();
    617         DtInsertSubtable (ParentTable, Subtable);
    618         DtPushSubtable (Subtable);
    619 
    620         AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
    621 
    622         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
    623         {
    624         case ACPI_ASF_TYPE_INFO:
    625 
    626             InfoTable = AcpiDmTableInfoAsf0;
    627             break;
    628 
    629         case ACPI_ASF_TYPE_ALERT:
    630 
    631             InfoTable = AcpiDmTableInfoAsf1;
    632             break;
    633 
    634         case ACPI_ASF_TYPE_CONTROL:
    635 
    636             InfoTable = AcpiDmTableInfoAsf2;
    637             break;
    638 
    639         case ACPI_ASF_TYPE_BOOT:
    640 
    641             InfoTable = AcpiDmTableInfoAsf3;
    642             break;
    643 
    644         case ACPI_ASF_TYPE_ADDRESS:
    645 
    646             InfoTable = AcpiDmTableInfoAsf4;
    647             break;
    648 
    649         default:
    650 
    651             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
    652             return (AE_ERROR);
    653         }
    654 
    655         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    656         if (ACPI_FAILURE (Status))
    657         {
    658             return (Status);
    659         }
    660 
    661         ParentTable = DtPeekSubtable ();
    662         DtInsertSubtable (ParentTable, Subtable);
    663 
    664         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
    665         {
    666         case ACPI_ASF_TYPE_INFO:
    667 
    668             DataInfoTable = NULL;
    669             break;
    670 
    671         case ACPI_ASF_TYPE_ALERT:
    672 
    673             DataInfoTable = AcpiDmTableInfoAsf1a;
    674             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
    675                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
    676                     sizeof (ACPI_ASF_HEADER)))->Alerts;
    677             break;
    678 
    679         case ACPI_ASF_TYPE_CONTROL:
    680 
    681             DataInfoTable = AcpiDmTableInfoAsf2a;
    682             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
    683                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
    684                     sizeof (ACPI_ASF_HEADER)))->Controls;
    685             break;
    686 
    687         case ACPI_ASF_TYPE_BOOT:
    688 
    689             DataInfoTable = NULL;
    690             break;
    691 
    692         case ACPI_ASF_TYPE_ADDRESS:
    693 
    694             DataInfoTable = TableInfoAsfAddress;
    695             DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
    696                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
    697                     sizeof (ACPI_ASF_HEADER)))->Devices;
    698             break;
    699 
    700         default:
    701 
    702             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
    703             return (AE_ERROR);
    704         }
    705 
    706         if (DataInfoTable)
    707         {
    708             switch (AsfTable->Header.Type & 0x7F)
    709             {
    710             case ACPI_ASF_TYPE_ADDRESS:
    711 
    712                 while (DataCount > 0)
    713                 {
    714                     Status = DtCompileTable (PFieldList, DataInfoTable,
    715                         &Subtable);
    716                     if (ACPI_FAILURE (Status))
    717                     {
    718                         return (Status);
    719                     }
    720 
    721                     DtInsertSubtable (ParentTable, Subtable);
    722                     DataCount = DataCount - Subtable->Length;
    723                 }
    724                 break;
    725 
    726             default:
    727 
    728                 for (i = 0; i < DataCount; i++)
    729                 {
    730                     Status = DtCompileTable (PFieldList, DataInfoTable,
    731                         &Subtable);
    732                     if (ACPI_FAILURE (Status))
    733                     {
    734                         return (Status);
    735                     }
    736 
    737                     DtInsertSubtable (ParentTable, Subtable);
    738                 }
    739                 break;
    740             }
    741         }
    742 
    743         DtPopSubtable ();
    744     }
    745 
    746     return (AE_OK);
    747 }
    748 
    749 /******************************************************************************
    750  *
    751  * FUNCTION:    DtCompileAspt
    752  *
    753  * PARAMETERS:  List                - Current field list pointer
    754  *
    755  * RETURN:      Status
    756  *
    757  * DESCRIPTION: Compile ASPT.
    758  *
    759  *****************************************************************************/
    760 
    761 ACPI_STATUS
    762 DtCompileAspt (
    763     void                    **List)
    764 {
    765     ACPI_ASPT_HEADER        *AsptTable;
    766     DT_SUBTABLE             *Subtable;
    767     DT_SUBTABLE             *ParentTable;
    768     ACPI_DMTABLE_INFO       *InfoTable;
    769     ACPI_STATUS             Status;
    770     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    771     DT_FIELD                *SubtableStart;
    772 
    773     Status = DtCompileTable (PFieldList, AcpiDmTableInfoAspt, &Subtable);
    774     if (ACPI_FAILURE (Status))
    775     {
    776         return (Status);
    777     }
    778 
    779     ParentTable = DtPeekSubtable ();
    780     DtInsertSubtable (ParentTable, Subtable);
    781 
    782     while (*PFieldList)
    783     {
    784         SubtableStart = *PFieldList;
    785         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsptHdr,
    786             &Subtable);
    787         if (ACPI_FAILURE (Status))
    788         {
    789             return (Status);
    790         }
    791 
    792         ParentTable = DtPeekSubtable ();
    793         DtInsertSubtable (ParentTable, Subtable);
    794         DtPushSubtable (Subtable);
    795 
    796         AsptTable = ACPI_CAST_PTR (ACPI_ASPT_HEADER, Subtable->Buffer);
    797 
    798         switch (AsptTable->Type) /* Mask off top bit */
    799         {
    800         case ACPI_ASPT_TYPE_GLOBAL_REGS:
    801 
    802             InfoTable = AcpiDmTableInfoAspt0;
    803             break;
    804 
    805         case ACPI_ASPT_TYPE_SEV_MBOX_REGS:
    806 
    807             InfoTable = AcpiDmTableInfoAspt1;
    808             break;
    809 
    810         case ACPI_ASPT_TYPE_ACPI_MBOX_REGS:
    811 
    812             InfoTable = AcpiDmTableInfoAspt2;
    813             break;
    814 
    815         default:
    816 
    817             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASPT");
    818             return (AE_ERROR);
    819         }
    820 
    821         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    822         if (ACPI_FAILURE (Status))
    823         {
    824             return (Status);
    825         }
    826         ParentTable = DtPeekSubtable ();
    827         DtInsertSubtable (ParentTable, Subtable);
    828         DtPopSubtable ();
    829     }
    830 
    831     return (AE_OK);
    832 }
    833 
    834 
    835 /******************************************************************************
    836  *
    837  * FUNCTION:    DtCompileCdat
    838  *
    839  * PARAMETERS:  List                - Current field list pointer
    840  *
    841  * RETURN:      Status
    842  *
    843  * DESCRIPTION: Compile CDAT.
    844  *
    845  *****************************************************************************/
    846 
    847 ACPI_STATUS
    848 DtCompileCdat (
    849     void                    **List)
    850 {
    851     ACPI_STATUS             Status = AE_OK;
    852     DT_SUBTABLE             *Subtable;
    853     DT_SUBTABLE             *ParentTable;
    854     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    855     ACPI_CDAT_HEADER        *CdatHeader;
    856     ACPI_DMTABLE_INFO       *InfoTable = NULL;
    857     DT_FIELD                *SubtableStart;
    858 
    859 
    860     /* Walk the parse tree.
    861      *
    862      * Note: Main table consists of only the CDAT table header
    863      * (This is not the standard ACPI table header, however)--
    864      * Followed by some number of subtables.
    865      */
    866     while (*PFieldList)
    867     {
    868         SubtableStart = *PFieldList;
    869 
    870         /* Compile the expected CDAT Subtable header */
    871 
    872         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatHeader,
    873             &Subtable);
    874         if (ACPI_FAILURE (Status))
    875         {
    876             return (Status);
    877         }
    878 
    879         ParentTable = DtPeekSubtable ();
    880         DtInsertSubtable (ParentTable, Subtable);
    881         DtPushSubtable (Subtable);
    882 
    883         CdatHeader = ACPI_CAST_PTR (ACPI_CDAT_HEADER, Subtable->Buffer);
    884 
    885         /* Decode the subtable by type */
    886 
    887         switch (CdatHeader->Type)
    888         {
    889         case ACPI_CDAT_TYPE_DSMAS:
    890             InfoTable = AcpiDmTableInfoCdat0;
    891             break;
    892 
    893         case ACPI_CDAT_TYPE_DSLBIS:
    894             InfoTable = AcpiDmTableInfoCdat1;
    895             break;
    896 
    897         case ACPI_CDAT_TYPE_DSMSCIS:
    898             InfoTable = AcpiDmTableInfoCdat2;
    899             break;
    900 
    901         case ACPI_CDAT_TYPE_DSIS:
    902             InfoTable = AcpiDmTableInfoCdat3;
    903             break;
    904 
    905         case ACPI_CDAT_TYPE_DSEMTS:
    906             InfoTable = AcpiDmTableInfoCdat4;
    907             break;
    908 
    909         case ACPI_CDAT_TYPE_SSLBIS:
    910             InfoTable = AcpiDmTableInfoCdat5;
    911             break;
    912 
    913         default:
    914             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CDAT");
    915         }
    916 
    917         /* Compile the CDAT subtable */
    918 
    919         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    920         if (ACPI_FAILURE (Status))
    921         {
    922             return (Status);
    923         }
    924 
    925         ParentTable = DtPeekSubtable ();
    926         DtInsertSubtable (ParentTable, Subtable);
    927 
    928         switch (CdatHeader->Type)
    929         {
    930         /* Multiple entries supported for this type */
    931 
    932         case ACPI_CDAT_TYPE_SSLBIS:
    933 
    934             /*
    935              * Check for multiple SSLBEs
    936              */
    937             while (*PFieldList && !AcpiUtStricmp ((*PFieldList)->Name, "Port X ID"))
    938             {
    939                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatEntries, &Subtable);
    940                 if (ACPI_FAILURE (Status))
    941                 {
    942                     return (Status);
    943                 }
    944                 ParentTable = DtPeekSubtable ();
    945                 DtInsertSubtable (ParentTable, Subtable);
    946             }
    947             break;
    948 
    949         default:
    950              break;
    951         }
    952 
    953         /* Pop off the CDAT Subtable header subtree */
    954 
    955         DtPopSubtable ();
    956     }
    957 
    958     return (AE_OK);
    959 }
    960 
    961 
    962 /******************************************************************************
    963  *
    964  * FUNCTION:    DtCompileCedt
    965  *
    966  * PARAMETERS:  List                - Current field list pointer
    967  *
    968  * RETURN:      Status
    969  *
    970  * DESCRIPTION: Compile CEDT.
    971  *
    972  *****************************************************************************/
    973 
    974 ACPI_STATUS
    975 DtCompileCedt (
    976     void                    **List)
    977 {
    978     ACPI_STATUS             Status;
    979     DT_SUBTABLE             *Subtable;
    980     DT_SUBTABLE             *ParentTable;
    981     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    982     ACPI_CEDT_HEADER        *CedtHeader;
    983     DT_FIELD                *SubtableStart;
    984 
    985 
    986     /* Walk the parse tree */
    987 
    988     while (*PFieldList)
    989     {
    990         /* if CFMWS and has more than one target, then set to zero later */
    991 
    992         int InsertFlag = 1;
    993         SubtableStart = *PFieldList;
    994 
    995         /* CEDT Header */
    996 
    997         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr,
    998             &Subtable);
    999         if (ACPI_FAILURE (Status))
   1000         {
   1001             return (Status);
   1002         }
   1003 
   1004         ParentTable = DtPeekSubtable ();
   1005         DtInsertSubtable (ParentTable, Subtable);
   1006         DtPushSubtable (Subtable);
   1007 
   1008         CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer);
   1009 
   1010         switch (CedtHeader->Type)
   1011         {
   1012         case ACPI_CEDT_TYPE_CHBS:
   1013             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable);
   1014             if (ACPI_FAILURE (Status))
   1015             {
   1016                 return (Status);
   1017             }
   1018             break;
   1019         case ACPI_CEDT_TYPE_CFMWS: {
   1020             unsigned char *dump;
   1021             unsigned int idx, offset, max = 0;
   1022 
   1023             /* Compile table with first "Interleave target" */
   1024 
   1025             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1, &Subtable);
   1026             if (ACPI_FAILURE (Status))
   1027             {
   1028                 return (Status);
   1029             }
   1030 
   1031             /* Look in buffer for the number of targets */
   1032             offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CFMWS, InterleaveWays);
   1033             dump = (unsigned char *) Subtable->Buffer - 4;     /* place at beginning of cedt1 */
   1034             max = 0x01 << dump[offset];     /* 2^max, so 0=1, 1=2, 2=4, 3=8. 8 is MAX */
   1035             if (max > 8)    max=1;          /* Error in encoding Interleaving Ways. */
   1036             if (max == 1)                   /* if only one target, then break here. */
   1037                 break;                      /* break if only one target. */
   1038 
   1039             /* We need to add more interleave targets, so write the current Subtable. */
   1040 
   1041             ParentTable = DtPeekSubtable ();
   1042             DtInsertSubtable (ParentTable, Subtable);   /* Insert AcpiDmTableInfoCedt1 table so we can put in */
   1043             DtPushSubtable (Subtable);                  /* the targets > the first. */
   1044 
   1045             /* Now, find out all interleave targets beyond the first. */
   1046 
   1047             for (idx = 1; idx < max; idx++) {
   1048                 ParentTable = DtPeekSubtable ();
   1049 
   1050                 if (*PFieldList)
   1051                 {
   1052                     Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1_te, &Subtable);
   1053                     if (ACPI_FAILURE (Status))
   1054                     {
   1055                         return (Status);
   1056                     }
   1057                     if (Subtable)
   1058                     {
   1059                         DtInsertSubtable (ParentTable, Subtable);       /* got a target, so insert table. */
   1060                         InsertFlag = 0;
   1061                     }
   1062                 }
   1063             }
   1064 
   1065             DtPopSubtable ();
   1066             ParentTable = DtPeekSubtable ();
   1067             break;
   1068         }
   1069         case ACPI_CEDT_TYPE_CXIMS: {
   1070             unsigned char *dump;
   1071             unsigned int idx, offset, max = 0;
   1072 
   1073             /* Compile table with first "Xor map" */
   1074 
   1075             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt2, &Subtable);
   1076             if (ACPI_FAILURE (Status))
   1077             {
   1078                 return (Status);
   1079             }
   1080 
   1081             /* Look in buffer for the number of Xor maps */
   1082             offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CXIMS, NrXormaps);
   1083             dump = (unsigned char *) Subtable->Buffer - 4;     /* place at beginning of cedt2 */
   1084             max = dump[offset];
   1085 
   1086             /* We need to add more XOR maps, so write the current Subtable. */
   1087 
   1088             ParentTable = DtPeekSubtable ();
   1089             DtInsertSubtable (ParentTable, Subtable);   /* Insert AcpiDmTableInfoCedt2 table so we can put in */
   1090             DtPushSubtable (Subtable);
   1091 
   1092             /* Now, find out all Xor maps beyond the first. */
   1093 
   1094             for (idx = 1; idx < max; idx++) {
   1095                 ParentTable = DtPeekSubtable ();
   1096 
   1097                 if (*PFieldList)
   1098                 {
   1099                     Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt2_te, &Subtable);
   1100                     if (ACPI_FAILURE (Status))
   1101                     {
   1102                         return (Status);
   1103                     }
   1104                     if (Subtable)
   1105                     {
   1106                         DtInsertSubtable (ParentTable, Subtable);       /* got an Xor map, so insert table. */
   1107                         InsertFlag = 0;
   1108                     }
   1109                 }
   1110             }
   1111 
   1112             DtPopSubtable ();
   1113             ParentTable = DtPeekSubtable ();
   1114             break;
   1115         }
   1116 
   1117         default:
   1118             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT");
   1119             return (AE_ERROR);
   1120         }
   1121 
   1122         ParentTable = DtPeekSubtable ();
   1123         if (InsertFlag == 1) {
   1124                 DtInsertSubtable (ParentTable, Subtable);
   1125         }
   1126         DtPopSubtable ();
   1127     }
   1128 
   1129     return (AE_OK);
   1130 }
   1131 
   1132 
   1133 /******************************************************************************
   1134  *
   1135  * FUNCTION:    DtCompileCpep
   1136  *
   1137  * PARAMETERS:  List                - Current field list pointer
   1138  *
   1139  * RETURN:      Status
   1140  *
   1141  * DESCRIPTION: Compile CPEP.
   1142  *
   1143  *****************************************************************************/
   1144 
   1145 ACPI_STATUS
   1146 DtCompileCpep (
   1147     void                    **List)
   1148 {
   1149     ACPI_STATUS             Status;
   1150 
   1151 
   1152     Status = DtCompileTwoSubtables (List,
   1153         AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
   1154     return (Status);
   1155 }
   1156 
   1157 
   1158 /******************************************************************************
   1159  *
   1160  * FUNCTION:    DtCompileCsrt
   1161  *
   1162  * PARAMETERS:  List                - Current field list pointer
   1163  *
   1164  * RETURN:      Status
   1165  *
   1166  * DESCRIPTION: Compile CSRT.
   1167  *
   1168  *****************************************************************************/
   1169 
   1170 ACPI_STATUS
   1171 DtCompileCsrt (
   1172     void                    **List)
   1173 {
   1174     ACPI_STATUS             Status = AE_OK;
   1175     DT_SUBTABLE             *Subtable;
   1176     DT_SUBTABLE             *ParentTable;
   1177     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1178     UINT32                  DescriptorCount;
   1179     UINT32                  GroupLength;
   1180 
   1181 
   1182     /* Subtables (Resource Groups) */
   1183 
   1184     ParentTable = DtPeekSubtable ();
   1185     while (*PFieldList)
   1186     {
   1187         /* Resource group subtable */
   1188 
   1189         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
   1190             &Subtable);
   1191         if (ACPI_FAILURE (Status))
   1192         {
   1193             return (Status);
   1194         }
   1195 
   1196         /* Compute the number of resource descriptors */
   1197 
   1198         GroupLength =
   1199             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
   1200                 Subtable->Buffer))->Length -
   1201             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
   1202                 Subtable->Buffer))->SharedInfoLength -
   1203             sizeof (ACPI_CSRT_GROUP);
   1204 
   1205         DescriptorCount = (GroupLength  /
   1206             sizeof (ACPI_CSRT_DESCRIPTOR));
   1207 
   1208         DtInsertSubtable (ParentTable, Subtable);
   1209         DtPushSubtable (Subtable);
   1210         ParentTable = DtPeekSubtable ();
   1211 
   1212         /* Shared info subtable (One per resource group) */
   1213 
   1214         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
   1215             &Subtable);
   1216         if (ACPI_FAILURE (Status))
   1217         {
   1218             return (Status);
   1219         }
   1220 
   1221         DtInsertSubtable (ParentTable, Subtable);
   1222 
   1223         /* Sub-Subtables (Resource Descriptors) */
   1224 
   1225         while (*PFieldList && DescriptorCount)
   1226         {
   1227 
   1228             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
   1229                 &Subtable);
   1230             if (ACPI_FAILURE (Status))
   1231             {
   1232                 return (Status);
   1233             }
   1234 
   1235             DtInsertSubtable (ParentTable, Subtable);
   1236 
   1237             DtPushSubtable (Subtable);
   1238             ParentTable = DtPeekSubtable ();
   1239             if (*PFieldList)
   1240             {
   1241                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
   1242                     &Subtable);
   1243                 if (ACPI_FAILURE (Status))
   1244                 {
   1245                     return (Status);
   1246                 }
   1247                 if (Subtable)
   1248                 {
   1249                     DtInsertSubtable (ParentTable, Subtable);
   1250                 }
   1251             }
   1252 
   1253             DtPopSubtable ();
   1254             ParentTable = DtPeekSubtable ();
   1255             DescriptorCount--;
   1256         }
   1257 
   1258         DtPopSubtable ();
   1259         ParentTable = DtPeekSubtable ();
   1260     }
   1261 
   1262     return (Status);
   1263 }
   1264 
   1265 
   1266 /******************************************************************************
   1267  *
   1268  * FUNCTION:    DtCompileDbg2
   1269  *
   1270  * PARAMETERS:  List                - Current field list pointer
   1271  *
   1272  * RETURN:      Status
   1273  *
   1274  * DESCRIPTION: Compile DBG2.
   1275  *
   1276  *****************************************************************************/
   1277 
   1278 ACPI_STATUS
   1279 DtCompileDbg2 (
   1280     void                    **List)
   1281 {
   1282     ACPI_STATUS             Status;
   1283     DT_SUBTABLE             *Subtable;
   1284     DT_SUBTABLE             *ParentTable;
   1285     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1286     UINT32                  SubtableCount;
   1287     ACPI_DBG2_HEADER        *Dbg2Header;
   1288     ACPI_DBG2_DEVICE        *DeviceInfo;
   1289     UINT16                  CurrentOffset;
   1290     UINT32                  i;
   1291 
   1292 
   1293     /* Main table */
   1294 
   1295     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable);
   1296     if (ACPI_FAILURE (Status))
   1297     {
   1298         return (Status);
   1299     }
   1300 
   1301     ParentTable = DtPeekSubtable ();
   1302     DtInsertSubtable (ParentTable, Subtable);
   1303 
   1304     /* Main table fields */
   1305 
   1306     Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
   1307     Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
   1308         ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
   1309 
   1310     SubtableCount = Dbg2Header->InfoCount;
   1311     DtPushSubtable (Subtable);
   1312 
   1313     /* Process all Device Information subtables (Count = InfoCount) */
   1314 
   1315     while (*PFieldList && SubtableCount)
   1316     {
   1317         /* Subtable: Debug Device Information */
   1318 
   1319         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
   1320             &Subtable);
   1321         if (ACPI_FAILURE (Status))
   1322         {
   1323             return (Status);
   1324         }
   1325 
   1326         DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
   1327         CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
   1328 
   1329         ParentTable = DtPeekSubtable ();
   1330         DtInsertSubtable (ParentTable, Subtable);
   1331         DtPushSubtable (Subtable);
   1332 
   1333         ParentTable = DtPeekSubtable ();
   1334 
   1335         /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
   1336 
   1337         DeviceInfo->BaseAddressOffset = CurrentOffset;
   1338         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
   1339         {
   1340             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
   1341                 &Subtable);
   1342             if (ACPI_FAILURE (Status))
   1343             {
   1344                 return (Status);
   1345             }
   1346 
   1347             CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
   1348             DtInsertSubtable (ParentTable, Subtable);
   1349         }
   1350 
   1351         /* AddressSize array (Required, size = RegisterCount) */
   1352 
   1353         DeviceInfo->AddressSizeOffset = CurrentOffset;
   1354         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
   1355         {
   1356             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
   1357                 &Subtable);
   1358             if (ACPI_FAILURE (Status))
   1359             {
   1360                 return (Status);
   1361             }
   1362 
   1363             CurrentOffset += (UINT16) sizeof (UINT32);
   1364             DtInsertSubtable (ParentTable, Subtable);
   1365         }
   1366 
   1367         /* NamespaceString device identifier (Required, size = NamePathLength) */
   1368 
   1369         DeviceInfo->NamepathOffset = CurrentOffset;
   1370         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
   1371             &Subtable);
   1372         if (ACPI_FAILURE (Status))
   1373         {
   1374             return (Status);
   1375         }
   1376 
   1377         /* Update the device info header */
   1378 
   1379         DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
   1380         CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
   1381         DtInsertSubtable (ParentTable, Subtable);
   1382 
   1383         /* OemData - Variable-length data (Optional, size = OemDataLength) */
   1384 
   1385         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
   1386             &Subtable);
   1387         if (Status == AE_END_OF_TABLE)
   1388         {
   1389             /* optional field was not found and we're at the end of the file */
   1390 
   1391             goto subtableDone;
   1392         }
   1393         else if (ACPI_FAILURE (Status))
   1394         {
   1395             return (Status);
   1396         }
   1397 
   1398         /* Update the device info header (zeros if no OEM data present) */
   1399 
   1400         DeviceInfo->OemDataOffset = 0;
   1401         DeviceInfo->OemDataLength = 0;
   1402 
   1403         /* Optional subtable (OemData) */
   1404 
   1405         if (Subtable && Subtable->Length)
   1406         {
   1407             DeviceInfo->OemDataOffset = CurrentOffset;
   1408             DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
   1409 
   1410             DtInsertSubtable (ParentTable, Subtable);
   1411         }
   1412 subtableDone:
   1413         SubtableCount--;
   1414         DtPopSubtable (); /* Get next Device Information subtable */
   1415     }
   1416 
   1417     DtPopSubtable ();
   1418     return (AE_OK);
   1419 }
   1420 
   1421 
   1422 /******************************************************************************
   1423  *
   1424  * FUNCTION:    DtCompileDmar
   1425  *
   1426  * PARAMETERS:  List                - Current field list pointer
   1427  *
   1428  * RETURN:      Status
   1429  *
   1430  * DESCRIPTION: Compile DMAR.
   1431  *
   1432  *****************************************************************************/
   1433 
   1434 ACPI_STATUS
   1435 DtCompileDmar (
   1436     void                    **List)
   1437 {
   1438     ACPI_STATUS             Status;
   1439     DT_SUBTABLE             *Subtable;
   1440     DT_SUBTABLE             *ParentTable;
   1441     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1442     DT_FIELD                *SubtableStart;
   1443     ACPI_DMTABLE_INFO       *InfoTable;
   1444     ACPI_DMAR_HEADER        *DmarHeader;
   1445     ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
   1446     UINT32                  DeviceScopeLength;
   1447     UINT32                  PciPathLength;
   1448 
   1449 
   1450     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable);
   1451     if (ACPI_FAILURE (Status))
   1452     {
   1453         return (Status);
   1454     }
   1455 
   1456     ParentTable = DtPeekSubtable ();
   1457     DtInsertSubtable (ParentTable, Subtable);
   1458     DtPushSubtable (Subtable);
   1459 
   1460     while (*PFieldList)
   1461     {
   1462         /* DMAR Header */
   1463 
   1464         SubtableStart = *PFieldList;
   1465         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
   1466             &Subtable);
   1467         if (ACPI_FAILURE (Status))
   1468         {
   1469             return (Status);
   1470         }
   1471 
   1472         ParentTable = DtPeekSubtable ();
   1473         DtInsertSubtable (ParentTable, Subtable);
   1474         DtPushSubtable (Subtable);
   1475 
   1476         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
   1477 
   1478         switch (DmarHeader->Type)
   1479         {
   1480         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
   1481 
   1482             InfoTable = AcpiDmTableInfoDmar0;
   1483             break;
   1484 
   1485         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
   1486 
   1487             InfoTable = AcpiDmTableInfoDmar1;
   1488             break;
   1489 
   1490         case ACPI_DMAR_TYPE_ROOT_ATS:
   1491 
   1492             InfoTable = AcpiDmTableInfoDmar2;
   1493             break;
   1494 
   1495         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
   1496 
   1497             InfoTable = AcpiDmTableInfoDmar3;
   1498             break;
   1499 
   1500         case ACPI_DMAR_TYPE_NAMESPACE:
   1501 
   1502             InfoTable = AcpiDmTableInfoDmar4;
   1503             break;
   1504 
   1505         case ACPI_DMAR_TYPE_SATC:
   1506 
   1507             InfoTable = AcpiDmTableInfoDmar5;
   1508             break;
   1509 
   1510         case ACPI_DMAR_TYPE_SIDP:
   1511 
   1512             InfoTable = AcpiDmTableInfoDmar6;
   1513             break;
   1514 
   1515         default:
   1516 
   1517             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
   1518             return (AE_ERROR);
   1519         }
   1520 
   1521         /* DMAR Subtable */
   1522 
   1523         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1524         if (ACPI_FAILURE (Status))
   1525         {
   1526             return (Status);
   1527         }
   1528 
   1529         ParentTable = DtPeekSubtable ();
   1530         DtInsertSubtable (ParentTable, Subtable);
   1531 
   1532         /*
   1533          * Optional Device Scope subtables
   1534          */
   1535         if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
   1536             (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
   1537         {
   1538             /* These types do not support device scopes */
   1539 
   1540             DtPopSubtable ();
   1541             continue;
   1542         }
   1543 
   1544         DtPushSubtable (Subtable);
   1545         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
   1546             ParentTable->Length;
   1547         while (DeviceScopeLength)
   1548         {
   1549             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
   1550                 &Subtable);
   1551             if (Status == AE_NOT_FOUND)
   1552             {
   1553                 break;
   1554             }
   1555 
   1556             ParentTable = DtPeekSubtable ();
   1557             DtInsertSubtable (ParentTable, Subtable);
   1558             DtPushSubtable (Subtable);
   1559 
   1560             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
   1561 
   1562             /* Optional PCI Paths */
   1563 
   1564             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
   1565             while (PciPathLength)
   1566             {
   1567                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
   1568                     &Subtable);
   1569                 if (Status == AE_NOT_FOUND)
   1570                 {
   1571                     DtPopSubtable ();
   1572                     break;
   1573                 }
   1574 
   1575                 ParentTable = DtPeekSubtable ();
   1576                 DtInsertSubtable (ParentTable, Subtable);
   1577                 PciPathLength -= Subtable->Length;
   1578             }
   1579 
   1580             DtPopSubtable ();
   1581             DeviceScopeLength -= DmarDeviceScope->Length;
   1582         }
   1583 
   1584         DtPopSubtable ();
   1585         DtPopSubtable ();
   1586     }
   1587 
   1588     return (AE_OK);
   1589 }
   1590 
   1591 
   1592 /******************************************************************************
   1593  *
   1594  * FUNCTION:    DtCompileDrtm
   1595  *
   1596  * PARAMETERS:  List                - Current field list pointer
   1597  *
   1598  * RETURN:      Status
   1599  *
   1600  * DESCRIPTION: Compile DRTM.
   1601  *
   1602  *****************************************************************************/
   1603 
   1604 ACPI_STATUS
   1605 DtCompileDrtm (
   1606     void                    **List)
   1607 {
   1608     ACPI_STATUS             Status;
   1609     DT_SUBTABLE             *Subtable;
   1610     DT_SUBTABLE             *ParentTable;
   1611     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1612     UINT32                  Count;
   1613     /* ACPI_TABLE_DRTM         *Drtm; */
   1614     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
   1615     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
   1616     /* ACPI_DRTM_DPS_ID        *DrtmDps; */
   1617 
   1618 
   1619     ParentTable = DtPeekSubtable ();
   1620 
   1621     /* Compile DRTM header */
   1622 
   1623     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
   1624         &Subtable);
   1625     if (ACPI_FAILURE (Status))
   1626     {
   1627         return (Status);
   1628     }
   1629     DtInsertSubtable (ParentTable, Subtable);
   1630 
   1631     /*
   1632      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   1633      * should be taken to avoid accessing ACPI_TABLE_HADER fields.
   1634      */
   1635 #if 0
   1636     Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
   1637         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
   1638 #endif
   1639     /* Compile VTL */
   1640 
   1641     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
   1642         &Subtable);
   1643     if (ACPI_FAILURE (Status))
   1644     {
   1645         return (Status);
   1646     }
   1647 
   1648     DtInsertSubtable (ParentTable, Subtable);
   1649     DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
   1650 
   1651     DtPushSubtable (Subtable);
   1652     ParentTable = DtPeekSubtable ();
   1653     Count = 0;
   1654 
   1655     while (*PFieldList)
   1656     {
   1657         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
   1658             &Subtable);
   1659         if (ACPI_FAILURE (Status))
   1660         {
   1661             return (Status);
   1662         }
   1663         if (!Subtable)
   1664         {
   1665             break;
   1666         }
   1667         DtInsertSubtable (ParentTable, Subtable);
   1668         Count++;
   1669     }
   1670 
   1671     DrtmVtl->ValidatedTableCount = Count;
   1672     DtPopSubtable ();
   1673     ParentTable = DtPeekSubtable ();
   1674 
   1675     /* Compile RL */
   1676 
   1677     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
   1678         &Subtable);
   1679     if (ACPI_FAILURE (Status))
   1680     {
   1681         return (Status);
   1682     }
   1683 
   1684     DtInsertSubtable (ParentTable, Subtable);
   1685     DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
   1686 
   1687     DtPushSubtable (Subtable);
   1688     ParentTable = DtPeekSubtable ();
   1689     Count = 0;
   1690 
   1691     while (*PFieldList)
   1692     {
   1693         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
   1694             &Subtable);
   1695         if (ACPI_FAILURE (Status))
   1696         {
   1697             return (Status);
   1698         }
   1699 
   1700         if (!Subtable)
   1701         {
   1702             break;
   1703         }
   1704 
   1705         DtInsertSubtable (ParentTable, Subtable);
   1706         Count++;
   1707     }
   1708 
   1709     DrtmRl->ResourceCount = Count;
   1710     DtPopSubtable ();
   1711     ParentTable = DtPeekSubtable ();
   1712 
   1713     /* Compile DPS */
   1714 
   1715     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
   1716         &Subtable);
   1717     if (ACPI_FAILURE (Status))
   1718     {
   1719         return (Status);
   1720     }
   1721     DtInsertSubtable (ParentTable, Subtable);
   1722     /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
   1723 
   1724 
   1725     return (AE_OK);
   1726 }
   1727 
   1728 
   1729 /******************************************************************************
   1730  *
   1731  * FUNCTION:    DtCompileEinj
   1732  *
   1733  * PARAMETERS:  List                - Current field list pointer
   1734  *
   1735  * RETURN:      Status
   1736  *
   1737  * DESCRIPTION: Compile EINJ.
   1738  *
   1739  *****************************************************************************/
   1740 
   1741 ACPI_STATUS
   1742 DtCompileEinj (
   1743     void                    **List)
   1744 {
   1745     ACPI_STATUS             Status;
   1746 
   1747 
   1748     Status = DtCompileTwoSubtables (List,
   1749         AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
   1750     return (Status);
   1751 }
   1752 
   1753 
   1754 /******************************************************************************
   1755  *
   1756  * FUNCTION:    DtCompileErdt
   1757  *
   1758  * PARAMETERS:  List                - Current field list pointer
   1759  *
   1760  * RETURN:      Status
   1761  *
   1762  * DESCRIPTION: Compile ERST. Complex table with subtables and subsubtables.
   1763  *
   1764  *****************************************************************************/
   1765 
   1766 ACPI_STATUS
   1767 DtCompileErdt (
   1768     void                    **List)
   1769 {
   1770     ACPI_STATUS             Status;
   1771     DT_SUBTABLE             *Subtable, *RmddSubtable = NULL, *Subsubtable;
   1772     DT_SUBTABLE             *ParentTable;
   1773     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1774     DT_FIELD                *SubtableStart;
   1775     ACPI_SUBTBL_HDR_16      *ErdtHeader;
   1776     ACPI_DMTABLE_INFO       *InfoTable;
   1777     ACPI_ERDT_MMRC          *Mmrc;
   1778     ACPI_ERDT_IBRD          *Ibrd;
   1779     UINT32                  NumEntries;
   1780     BOOLEAN                 SeenRmdd = FALSE;
   1781     BOOLEAN                 SeenSubtable = FALSE;
   1782 
   1783     Status = DtCompileTable (PFieldList, AcpiDmTableInfoErdt,
   1784         &Subtable);
   1785     if (ACPI_FAILURE (Status))
   1786     {
   1787         return (Status);
   1788     }
   1789 
   1790     ParentTable = DtPeekSubtable ();
   1791     DtInsertSubtable (ParentTable, Subtable);
   1792 
   1793     while (*PFieldList)
   1794     {
   1795         SubtableStart = *PFieldList;
   1796         Status = DtCompileTable (PFieldList, AcpiDmTableInfoErdtHdr,
   1797             &Subtable);
   1798         if (ACPI_FAILURE (Status))
   1799         {
   1800             return (Status);
   1801         }
   1802 
   1803         ErdtHeader = ACPI_CAST_PTR (ACPI_SUBTBL_HDR_16, Subtable->Buffer);
   1804 
   1805         /* RMDD tables at top level. All others are subtables of preceeding RMDD */
   1806         if (ErdtHeader->Type == ACPI_ERDT_TYPE_RMDD)
   1807         {
   1808             if (SeenRmdd && SeenSubtable)
   1809                 DtPopSubtable ();
   1810             SeenRmdd = TRUE;
   1811             SeenSubtable = FALSE;
   1812             RmddSubtable = Subtable;
   1813         }
   1814         else
   1815         {
   1816             if (!SeenSubtable)
   1817             {
   1818                 DtPushSubtable (RmddSubtable);
   1819                 SeenSubtable = TRUE;
   1820             }
   1821         }
   1822 
   1823         ParentTable = DtPeekSubtable ();
   1824         DtInsertSubtable (ParentTable, Subtable);
   1825         DtPushSubtable (Subtable);
   1826 
   1827         switch (ErdtHeader->Type)
   1828         {
   1829         case ACPI_ERDT_TYPE_RMDD:
   1830             InfoTable = AcpiDmTableInfoErdtRmdd;
   1831             break;
   1832 
   1833         case ACPI_ERDT_TYPE_CACD:
   1834              InfoTable = AcpiDmTableInfoErdtCacd;
   1835              break;
   1836 
   1837         case ACPI_ERDT_TYPE_DACD:
   1838              InfoTable = AcpiDmTableInfoErdtDacd;
   1839              break;
   1840 
   1841         case ACPI_ERDT_TYPE_CMRC:
   1842              InfoTable = AcpiDmTableInfoErdtCmrc;
   1843              break;
   1844 
   1845         case ACPI_ERDT_TYPE_MMRC:
   1846              InfoTable = AcpiDmTableInfoErdtMmrc;
   1847              break;
   1848 
   1849         case ACPI_ERDT_TYPE_MARC:
   1850              InfoTable = AcpiDmTableInfoErdtMarc;
   1851              break;
   1852 
   1853         case ACPI_ERDT_TYPE_CARC:
   1854              InfoTable = AcpiDmTableInfoErdtCarc;
   1855              break;
   1856 
   1857         case ACPI_ERDT_TYPE_CMRD:
   1858              InfoTable = AcpiDmTableInfoErdtCmrd;
   1859              break;
   1860 
   1861         case ACPI_ERDT_TYPE_IBRD:
   1862              InfoTable = AcpiDmTableInfoErdtIbrd;
   1863              break;
   1864 
   1865         case ACPI_ERDT_TYPE_IBAD:
   1866              InfoTable = AcpiDmTableInfoErdtIbad;
   1867              break;
   1868 
   1869         case ACPI_ERDT_TYPE_CARD:
   1870              InfoTable = AcpiDmTableInfoErdtCard;
   1871              break;
   1872 
   1873         default:
   1874             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ERDT");
   1875             return (AE_ERROR);
   1876         }
   1877 
   1878         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1879         if (ACPI_FAILURE (Status))
   1880         {
   1881             return (Status);
   1882         }
   1883 
   1884         ParentTable = DtPeekSubtable ();
   1885         DtInsertSubtable (ParentTable, Subtable);
   1886 
   1887         /* Some subtable types end with flex arrays */
   1888 
   1889         switch (ErdtHeader->Type)
   1890         {
   1891         case ACPI_ERDT_TYPE_CACD:
   1892             while (*PFieldList)
   1893             {
   1894                 Status = DtCompileTable (PFieldList,
   1895                     AcpiDmTableInfoErdtCacdX2apic, &Subtable);
   1896                 if (ACPI_FAILURE (Status))
   1897                 {
   1898                     return (Status);
   1899                 }
   1900                 if (!Subtable)
   1901                 {
   1902                     break;
   1903                 }
   1904 
   1905                 ParentTable = DtPeekSubtable ();
   1906                 DtInsertSubtable (ParentTable, Subtable);
   1907             }
   1908             break;
   1909 
   1910         case ACPI_ERDT_TYPE_DACD:
   1911             while (*PFieldList)
   1912             {
   1913                 Status = DtCompileTable (PFieldList,
   1914                     AcpiDmTableInfoErdtDacdScope, &Subtable);
   1915                 if (ACPI_FAILURE (Status))
   1916                 {
   1917                     return (Status);
   1918                 }
   1919                 if (!Subtable)
   1920                 {
   1921                     break;
   1922                 }
   1923 
   1924                 DtPushSubtable (Subtable);
   1925                 while (*PFieldList)
   1926                 {
   1927                     Status = DtCompileTable (PFieldList,
   1928                         AcpiDmTableInfoErdtDacdPath, &Subsubtable);
   1929                     if (ACPI_FAILURE (Status))
   1930                     {
   1931                         return (Status);
   1932                     }
   1933                     if (!Subsubtable)
   1934                     {
   1935                         break;
   1936                     }
   1937 
   1938                     ParentTable = DtPeekSubtable ();
   1939                     DtInsertSubtable (ParentTable, Subsubtable);
   1940                 }
   1941                 DtPopSubtable ();
   1942 
   1943                 ParentTable = DtPeekSubtable ();
   1944                 DtInsertSubtable (ParentTable, Subtable);
   1945             }
   1946             break;
   1947 
   1948         case ACPI_ERDT_TYPE_MMRC:
   1949             Mmrc = ACPI_SUB_PTR (ACPI_ERDT_MMRC, Subtable->Buffer,
   1950                 sizeof(ACPI_SUBTBL_HDR_16));
   1951             NumEntries = 0;
   1952             while (*PFieldList)
   1953             {
   1954                 Status = DtCompileTable (PFieldList,
   1955                     AcpiDmTableInfoErdtMmrcCorrFactor, &Subtable);
   1956                 if (ACPI_FAILURE (Status))
   1957                 {
   1958                     return (Status);
   1959                 }
   1960                 if (!Subtable)
   1961                 {
   1962                     break;
   1963                 }
   1964 
   1965                 ParentTable = DtPeekSubtable ();
   1966                 DtInsertSubtable (ParentTable, Subtable);
   1967                 NumEntries++;
   1968             }
   1969             Mmrc->CorrFactorListLen = NumEntries;
   1970             break;
   1971 
   1972         case ACPI_ERDT_TYPE_IBRD:
   1973             Ibrd = ACPI_SUB_PTR (ACPI_ERDT_IBRD, Subtable->Buffer,
   1974                 sizeof(ACPI_SUBTBL_HDR_16));
   1975             NumEntries = 0;
   1976             while (*PFieldList)
   1977             {
   1978                 Status = DtCompileTable (PFieldList,
   1979                     AcpiDmTableInfoErdtIbrdCorrFactor, &Subtable);
   1980                 if (ACPI_FAILURE (Status))
   1981                 {
   1982                     return (Status);
   1983                 }
   1984                 if (!Subtable)
   1985                 {
   1986                     break;
   1987                 }
   1988 
   1989                 ParentTable = DtPeekSubtable ();
   1990                 DtInsertSubtable (ParentTable, Subtable);
   1991                 NumEntries++;
   1992             }
   1993             Ibrd->CorrFactorListLen = NumEntries;
   1994             break;
   1995 
   1996         default:
   1997             /* Already checked for valid subtable type above */
   1998 
   1999             break;
   2000         }
   2001         DtPopSubtable ();
   2002     }
   2003 
   2004     if (SeenSubtable)
   2005     {
   2006         DtPopSubtable ();
   2007     }
   2008 
   2009     return (AE_OK);
   2010 }
   2011 
   2012 
   2013 /******************************************************************************
   2014  *
   2015  * FUNCTION:    DtCompileErst
   2016  *
   2017  * PARAMETERS:  List                - Current field list pointer
   2018  *
   2019  * RETURN:      Status
   2020  *
   2021  * DESCRIPTION: Compile ERST.
   2022  *
   2023  *****************************************************************************/
   2024 
   2025 ACPI_STATUS
   2026 DtCompileErst (
   2027     void                    **List)
   2028 {
   2029     ACPI_STATUS             Status;
   2030 
   2031 
   2032     Status = DtCompileTwoSubtables (List,
   2033         AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
   2034     return (Status);
   2035 }
   2036 
   2037 
   2038 /******************************************************************************
   2039  *
   2040  * FUNCTION:    DtCompileGtdt
   2041  *
   2042  * PARAMETERS:  List                - Current field list pointer
   2043  *
   2044  * RETURN:      Status
   2045  *
   2046  * DESCRIPTION: Compile GTDT.
   2047  *
   2048  *****************************************************************************/
   2049 
   2050 ACPI_STATUS
   2051 DtCompileGtdt (
   2052     void                    **List)
   2053 {
   2054     ACPI_STATUS             Status;
   2055     DT_SUBTABLE             *Subtable;
   2056     DT_SUBTABLE             *ParentTable;
   2057     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2058     DT_FIELD                *SubtableStart;
   2059     ACPI_SUBTABLE_HEADER    *GtdtHeader;
   2060     ACPI_DMTABLE_INFO       *InfoTable;
   2061     UINT32                  GtCount;
   2062     ACPI_TABLE_HEADER       *Header;
   2063 
   2064 
   2065     ParentTable = DtPeekSubtable ();
   2066 
   2067     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   2068 
   2069     /* Compile the main table */
   2070 
   2071     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
   2072         &Subtable);
   2073     if (ACPI_FAILURE (Status))
   2074     {
   2075         return (Status);
   2076     }
   2077 
   2078     /* GTDT revision 3 later contains 2 extra fields before subtables */
   2079 
   2080     if (Header->Revision > 2)
   2081     {
   2082         ParentTable = DtPeekSubtable ();
   2083         DtInsertSubtable (ParentTable, Subtable);
   2084 
   2085         Status = DtCompileTable (PFieldList,
   2086             AcpiDmTableInfoGtdtEl2, &Subtable);
   2087         if (ACPI_FAILURE (Status))
   2088         {
   2089             return (Status);
   2090         }
   2091     }
   2092 
   2093     ParentTable = DtPeekSubtable ();
   2094     DtInsertSubtable (ParentTable, Subtable);
   2095 
   2096     while (*PFieldList)
   2097     {
   2098         SubtableStart = *PFieldList;
   2099         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
   2100             &Subtable);
   2101         if (ACPI_FAILURE (Status))
   2102         {
   2103             return (Status);
   2104         }
   2105 
   2106         ParentTable = DtPeekSubtable ();
   2107         DtInsertSubtable (ParentTable, Subtable);
   2108         DtPushSubtable (Subtable);
   2109 
   2110         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
   2111 
   2112         switch (GtdtHeader->Type)
   2113         {
   2114         case ACPI_GTDT_TYPE_TIMER_BLOCK:
   2115 
   2116             InfoTable = AcpiDmTableInfoGtdt0;
   2117             break;
   2118 
   2119         case ACPI_GTDT_TYPE_WATCHDOG:
   2120 
   2121             InfoTable = AcpiDmTableInfoGtdt1;
   2122             break;
   2123 
   2124         default:
   2125 
   2126             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
   2127             return (AE_ERROR);
   2128         }
   2129 
   2130         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   2131         if (ACPI_FAILURE (Status))
   2132         {
   2133             return (Status);
   2134         }
   2135 
   2136         ParentTable = DtPeekSubtable ();
   2137         DtInsertSubtable (ParentTable, Subtable);
   2138 
   2139         /*
   2140          * Additional GT block subtable data
   2141          */
   2142 
   2143         switch (GtdtHeader->Type)
   2144         {
   2145         case ACPI_GTDT_TYPE_TIMER_BLOCK:
   2146 
   2147             DtPushSubtable (Subtable);
   2148             ParentTable = DtPeekSubtable ();
   2149 
   2150             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
   2151                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
   2152 
   2153             while (GtCount)
   2154             {
   2155                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
   2156                     &Subtable);
   2157                 if (ACPI_FAILURE (Status))
   2158                 {
   2159                     return (Status);
   2160                 }
   2161 
   2162                 DtInsertSubtable (ParentTable, Subtable);
   2163                 GtCount--;
   2164             }
   2165 
   2166             DtPopSubtable ();
   2167             break;
   2168 
   2169         default:
   2170 
   2171             break;
   2172         }
   2173 
   2174         DtPopSubtable ();
   2175     }
   2176 
   2177     return (AE_OK);
   2178 }
   2179 
   2180 
   2181 /******************************************************************************
   2182  *
   2183  * FUNCTION:    DtCompileFpdt
   2184  *
   2185  * PARAMETERS:  List                - Current field list pointer
   2186  *
   2187  * RETURN:      Status
   2188  *
   2189  * DESCRIPTION: Compile FPDT.
   2190  *
   2191  *****************************************************************************/
   2192 
   2193 ACPI_STATUS
   2194 DtCompileFpdt (
   2195     void                    **List)
   2196 {
   2197     ACPI_STATUS             Status;
   2198     ACPI_FPDT_HEADER        *FpdtHeader;
   2199     DT_SUBTABLE             *Subtable;
   2200     DT_SUBTABLE             *ParentTable;
   2201     ACPI_DMTABLE_INFO       *InfoTable;
   2202     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2203     DT_FIELD                *SubtableStart;
   2204 
   2205 
   2206     while (*PFieldList)
   2207     {
   2208         SubtableStart = *PFieldList;
   2209         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
   2210             &Subtable);
   2211         if (ACPI_FAILURE (Status))
   2212         {
   2213             return (Status);
   2214         }
   2215 
   2216         ParentTable = DtPeekSubtable ();
   2217         DtInsertSubtable (ParentTable, Subtable);
   2218         DtPushSubtable (Subtable);
   2219 
   2220         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
   2221 
   2222         switch (FpdtHeader->Type)
   2223         {
   2224         case ACPI_FPDT_TYPE_BOOT:
   2225 
   2226             InfoTable = AcpiDmTableInfoFpdt0;
   2227             break;
   2228 
   2229         case ACPI_FPDT_TYPE_S3PERF:
   2230 
   2231             InfoTable = AcpiDmTableInfoFpdt1;
   2232             break;
   2233 
   2234         default:
   2235 
   2236             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
   2237             return (AE_ERROR);
   2238             break;
   2239         }
   2240 
   2241         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   2242         if (ACPI_FAILURE (Status))
   2243         {
   2244             return (Status);
   2245         }
   2246 
   2247         ParentTable = DtPeekSubtable ();
   2248         DtInsertSubtable (ParentTable, Subtable);
   2249         DtPopSubtable ();
   2250     }
   2251 
   2252     return (AE_OK);
   2253 }
   2254 
   2255 
   2256 /******************************************************************************
   2257  *
   2258  * FUNCTION:    DtCompileHest
   2259  *
   2260  * PARAMETERS:  List                - Current field list pointer
   2261  *
   2262  * RETURN:      Status
   2263  *
   2264  * DESCRIPTION: Compile HEST.
   2265  *
   2266  *****************************************************************************/
   2267 
   2268 ACPI_STATUS
   2269 DtCompileHest (
   2270     void                    **List)
   2271 {
   2272     ACPI_STATUS             Status;
   2273     DT_SUBTABLE             *Subtable;
   2274     DT_SUBTABLE             *ParentTable;
   2275     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2276     DT_FIELD                *SubtableStart;
   2277     ACPI_DMTABLE_INFO       *InfoTable;
   2278     UINT16                  Type;
   2279     UINT32                  BankCount;
   2280 
   2281 
   2282     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
   2283         &Subtable);
   2284     if (ACPI_FAILURE (Status))
   2285     {
   2286         return (Status);
   2287     }
   2288 
   2289     ParentTable = DtPeekSubtable ();
   2290     DtInsertSubtable (ParentTable, Subtable);
   2291 
   2292     while (*PFieldList)
   2293     {
   2294         /* Get subtable type */
   2295 
   2296         SubtableStart = *PFieldList;
   2297         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
   2298 
   2299         switch (Type)
   2300         {
   2301         case ACPI_HEST_TYPE_IA32_CHECK:
   2302 
   2303             InfoTable = AcpiDmTableInfoHest0;
   2304             break;
   2305 
   2306         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   2307 
   2308             InfoTable = AcpiDmTableInfoHest1;
   2309             break;
   2310 
   2311         case ACPI_HEST_TYPE_IA32_NMI:
   2312 
   2313             InfoTable = AcpiDmTableInfoHest2;
   2314             break;
   2315 
   2316         case ACPI_HEST_TYPE_AER_ROOT_PORT:
   2317 
   2318             InfoTable = AcpiDmTableInfoHest6;
   2319             break;
   2320 
   2321         case ACPI_HEST_TYPE_AER_ENDPOINT:
   2322 
   2323             InfoTable = AcpiDmTableInfoHest7;
   2324             break;
   2325 
   2326         case ACPI_HEST_TYPE_AER_BRIDGE:
   2327 
   2328             InfoTable = AcpiDmTableInfoHest8;
   2329             break;
   2330 
   2331         case ACPI_HEST_TYPE_GENERIC_ERROR:
   2332 
   2333             InfoTable = AcpiDmTableInfoHest9;
   2334             break;
   2335 
   2336         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
   2337 
   2338             InfoTable = AcpiDmTableInfoHest10;
   2339             break;
   2340 
   2341         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   2342 
   2343             InfoTable = AcpiDmTableInfoHest11;
   2344             break;
   2345 
   2346         default:
   2347 
   2348             /* Cannot continue on unknown type */
   2349 
   2350             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
   2351             return (AE_ERROR);
   2352         }
   2353 
   2354         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   2355         if (ACPI_FAILURE (Status))
   2356         {
   2357             return (Status);
   2358         }
   2359 
   2360         DtInsertSubtable (ParentTable, Subtable);
   2361 
   2362         /*
   2363          * Additional subtable data - IA32 Error Bank(s)
   2364          */
   2365         BankCount = 0;
   2366         switch (Type)
   2367         {
   2368         case ACPI_HEST_TYPE_IA32_CHECK:
   2369 
   2370             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
   2371                 Subtable->Buffer))->NumHardwareBanks;
   2372             break;
   2373 
   2374         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   2375 
   2376             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
   2377                 Subtable->Buffer))->NumHardwareBanks;
   2378             break;
   2379 
   2380         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   2381 
   2382             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
   2383                 Subtable->Buffer))->NumHardwareBanks;
   2384             break;
   2385 
   2386         default:
   2387 
   2388             break;
   2389         }
   2390 
   2391         while (BankCount)
   2392         {
   2393             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
   2394                 &Subtable);
   2395             if (ACPI_FAILURE (Status))
   2396             {
   2397                 return (Status);
   2398             }
   2399 
   2400             DtInsertSubtable (ParentTable, Subtable);
   2401             BankCount--;
   2402         }
   2403     }
   2404 
   2405     return (AE_OK);
   2406 }
   2407 
   2408 
   2409 /******************************************************************************
   2410  *
   2411  * FUNCTION:    DtCompileHmat
   2412  *
   2413  * PARAMETERS:  List                - Current field list pointer
   2414  *
   2415  * RETURN:      Status
   2416  *
   2417  * DESCRIPTION: Compile HMAT.
   2418  *
   2419  *****************************************************************************/
   2420 
   2421 ACPI_STATUS
   2422 DtCompileHmat (
   2423     void                    **List)
   2424 {
   2425     ACPI_STATUS             Status;
   2426     DT_SUBTABLE             *Subtable;
   2427     DT_SUBTABLE             *ParentTable;
   2428     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2429     DT_FIELD                *SubtableStart;
   2430     DT_FIELD                *EntryStart;
   2431     ACPI_HMAT_STRUCTURE     *HmatStruct;
   2432     ACPI_HMAT_LOCALITY      *HmatLocality;
   2433     ACPI_HMAT_CACHE         *HmatCache;
   2434     ACPI_DMTABLE_INFO       *InfoTable;
   2435     UINT32                  IntPDNumber;
   2436     UINT32                  TgtPDNumber;
   2437     UINT64                  EntryNumber;
   2438     UINT16                  SMBIOSHandleNumber;
   2439 
   2440 
   2441     ParentTable = DtPeekSubtable ();
   2442 
   2443     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
   2444         &Subtable);
   2445     if (ACPI_FAILURE (Status))
   2446     {
   2447         return (Status);
   2448     }
   2449     DtInsertSubtable (ParentTable, Subtable);
   2450 
   2451     while (*PFieldList)
   2452     {
   2453         /* Compile HMAT structure header */
   2454 
   2455         SubtableStart = *PFieldList;
   2456         Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
   2457             &Subtable);
   2458         if (ACPI_FAILURE (Status))
   2459         {
   2460             return (Status);
   2461         }
   2462         DtInsertSubtable (ParentTable, Subtable);
   2463 
   2464         HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
   2465         HmatStruct->Length = Subtable->Length;
   2466 
   2467         /* Compile HMAT structure body */
   2468 
   2469         switch (HmatStruct->Type)
   2470         {
   2471         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
   2472 
   2473             InfoTable = AcpiDmTableInfoHmat0;
   2474             break;
   2475 
   2476         case ACPI_HMAT_TYPE_LOCALITY:
   2477 
   2478             InfoTable = AcpiDmTableInfoHmat1;
   2479             break;
   2480 
   2481         case ACPI_HMAT_TYPE_CACHE:
   2482 
   2483             InfoTable = AcpiDmTableInfoHmat2;
   2484             break;
   2485 
   2486         default:
   2487 
   2488             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
   2489             return (AE_ERROR);
   2490         }
   2491 
   2492         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   2493         if (ACPI_FAILURE (Status))
   2494         {
   2495             return (Status);
   2496         }
   2497         DtInsertSubtable (ParentTable, Subtable);
   2498         HmatStruct->Length += Subtable->Length;
   2499 
   2500         /* Compile HMAT structure additional */
   2501 
   2502         switch (HmatStruct->Type)
   2503         {
   2504         case ACPI_HMAT_TYPE_LOCALITY:
   2505 
   2506             HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
   2507                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   2508 
   2509             /* Compile initiator proximity domain list */
   2510 
   2511             IntPDNumber = 0;
   2512             while (*PFieldList)
   2513             {
   2514                 Status = DtCompileTable (PFieldList,
   2515                     AcpiDmTableInfoHmat1a, &Subtable);
   2516                 if (ACPI_FAILURE (Status))
   2517                 {
   2518                     return (Status);
   2519                 }
   2520                 if (!Subtable)
   2521                 {
   2522                     break;
   2523                 }
   2524                 DtInsertSubtable (ParentTable, Subtable);
   2525                 HmatStruct->Length += Subtable->Length;
   2526                 IntPDNumber++;
   2527             }
   2528             HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
   2529 
   2530             /* Compile target proximity domain list */
   2531 
   2532             TgtPDNumber = 0;
   2533             while (*PFieldList)
   2534             {
   2535                 Status = DtCompileTable (PFieldList,
   2536                     AcpiDmTableInfoHmat1b, &Subtable);
   2537                 if (ACPI_FAILURE (Status))
   2538                 {
   2539                     return (Status);
   2540                 }
   2541                 if (!Subtable)
   2542                 {
   2543                     break;
   2544                 }
   2545                 DtInsertSubtable (ParentTable, Subtable);
   2546                 HmatStruct->Length += Subtable->Length;
   2547                 TgtPDNumber++;
   2548             }
   2549             HmatLocality->NumberOfTargetPDs = TgtPDNumber;
   2550 
   2551             /* Save start of the entries for reporting errors */
   2552 
   2553             EntryStart = *PFieldList;
   2554 
   2555             /* Compile latency/bandwidth entries */
   2556 
   2557             EntryNumber = 0;
   2558             while (*PFieldList)
   2559             {
   2560                 Status = DtCompileTable (PFieldList,
   2561                     AcpiDmTableInfoHmat1c, &Subtable);
   2562                 if (ACPI_FAILURE (Status))
   2563                 {
   2564                     return (Status);
   2565                 }
   2566                 if (!Subtable)
   2567                 {
   2568                     break;
   2569                 }
   2570                 DtInsertSubtable (ParentTable, Subtable);
   2571                 HmatStruct->Length += Subtable->Length;
   2572                 EntryNumber++;
   2573             }
   2574 
   2575             /* Validate number of entries */
   2576 
   2577             if (EntryNumber !=
   2578                 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
   2579             {
   2580                 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
   2581                 return (AE_ERROR);
   2582             }
   2583             break;
   2584 
   2585         case ACPI_HMAT_TYPE_CACHE:
   2586 
   2587             /* Compile SMBIOS handles */
   2588 
   2589             HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
   2590                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   2591             SMBIOSHandleNumber = 0;
   2592             while (*PFieldList)
   2593             {
   2594                 Status = DtCompileTable (PFieldList,
   2595                     AcpiDmTableInfoHmat2a, &Subtable);
   2596                 if (ACPI_FAILURE (Status))
   2597                 {
   2598                     return (Status);
   2599                 }
   2600                 if (!Subtable)
   2601                 {
   2602                     break;
   2603                 }
   2604                 DtInsertSubtable (ParentTable, Subtable);
   2605                 HmatStruct->Length += Subtable->Length;
   2606                 SMBIOSHandleNumber++;
   2607             }
   2608             HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
   2609             break;
   2610 
   2611         default:
   2612 
   2613             break;
   2614         }
   2615     }
   2616 
   2617     return (AE_OK);
   2618 }
   2619 
   2620 
   2621 /******************************************************************************
   2622  *
   2623  * FUNCTION:    DtCompileIort
   2624  *
   2625  * PARAMETERS:  List                - Current field list pointer
   2626  *
   2627  * RETURN:      Status
   2628  *
   2629  * DESCRIPTION: Compile IORT.
   2630  *
   2631  *****************************************************************************/
   2632 
   2633 ACPI_STATUS
   2634 DtCompileIort (
   2635     void                    **List)
   2636 {
   2637     ACPI_STATUS             Status;
   2638     DT_SUBTABLE             *Subtable;
   2639     DT_SUBTABLE             *ParentTable;
   2640     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2641     DT_FIELD                *SubtableStart;
   2642     ACPI_TABLE_HEADER       *Table;
   2643     ACPI_TABLE_IORT         *Iort;
   2644     ACPI_IORT_NODE          *IortNode;
   2645     ACPI_IORT_ITS_GROUP     *IortItsGroup;
   2646     ACPI_IORT_SMMU          *IortSmmu;
   2647     ACPI_IORT_RMR           *IortRmr;
   2648     UINT32                  NodeNumber;
   2649     UINT32                  NodeLength;
   2650     UINT32                  IdMappingNumber;
   2651     UINT32                  ItsNumber;
   2652     UINT32                  ContextIrptNumber;
   2653     UINT32                  PmuIrptNumber;
   2654     UINT32                  PaddingLength;
   2655     UINT8                   Revision;
   2656     UINT32                  RmrCount;
   2657 
   2658 
   2659     ParentTable = DtPeekSubtable ();
   2660 
   2661     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
   2662         &Subtable);
   2663     if (ACPI_FAILURE (Status))
   2664     {
   2665         return (Status);
   2666     }
   2667     DtInsertSubtable (ParentTable, Subtable);
   2668 
   2669     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   2670     Revision = Table->Revision;
   2671 
   2672     /* IORT Revisions E, E.a & E.c have known issues and are not supported */
   2673 
   2674     if (Revision == 1 || Revision == 2 || Revision == 4)
   2675     {
   2676         DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision");
   2677         return (AE_ERROR);
   2678     }
   2679 
   2680     /*
   2681      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   2682      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
   2683      */
   2684     Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
   2685         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
   2686 
   2687     /*
   2688      * OptionalPadding - Variable-length data
   2689      * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
   2690      * Optionally allows the generic data types to be used for filling
   2691      * this field.
   2692      */
   2693     Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
   2694     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
   2695         &Subtable);
   2696     if (ACPI_FAILURE (Status))
   2697     {
   2698         return (Status);
   2699     }
   2700     if (Subtable)
   2701     {
   2702         DtInsertSubtable (ParentTable, Subtable);
   2703         Iort->NodeOffset += Subtable->Length;
   2704     }
   2705     else
   2706     {
   2707         Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
   2708             AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
   2709         if (ACPI_FAILURE (Status))
   2710         {
   2711             return (Status);
   2712         }
   2713         Iort->NodeOffset += PaddingLength;
   2714     }
   2715 
   2716     NodeNumber = 0;
   2717     while (*PFieldList)
   2718     {
   2719         SubtableStart = *PFieldList;
   2720         if (Revision == 0)
   2721         {
   2722             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
   2723                 &Subtable);
   2724         }
   2725         else if (Revision >= 3)
   2726         {
   2727             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3,
   2728                 &Subtable);
   2729         }
   2730 
   2731         if (ACPI_FAILURE (Status))
   2732         {
   2733             return (Status);
   2734         }
   2735 
   2736         DtInsertSubtable (ParentTable, Subtable);
   2737         IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
   2738         NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
   2739 
   2740         DtPushSubtable (Subtable);
   2741         ParentTable = DtPeekSubtable ();
   2742 
   2743         switch (IortNode->Type)
   2744         {
   2745         case ACPI_IORT_NODE_ITS_GROUP:
   2746 
   2747             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
   2748                 &Subtable);
   2749             if (ACPI_FAILURE (Status))
   2750             {
   2751                 return (Status);
   2752             }
   2753 
   2754             DtInsertSubtable (ParentTable, Subtable);
   2755             IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
   2756             NodeLength += Subtable->Length;
   2757 
   2758             ItsNumber = 0;
   2759             while (*PFieldList)
   2760             {
   2761                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
   2762                     &Subtable);
   2763                 if (ACPI_FAILURE (Status))
   2764                 {
   2765                     return (Status);
   2766                 }
   2767                 if (!Subtable)
   2768                 {
   2769                     break;
   2770                 }
   2771 
   2772                 DtInsertSubtable (ParentTable, Subtable);
   2773                 NodeLength += Subtable->Length;
   2774                 ItsNumber++;
   2775             }
   2776 
   2777             IortItsGroup->ItsCount = ItsNumber;
   2778             break;
   2779 
   2780         case ACPI_IORT_NODE_NAMED_COMPONENT:
   2781 
   2782             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
   2783                 &Subtable);
   2784             if (ACPI_FAILURE (Status))
   2785             {
   2786                 return (Status);
   2787             }
   2788 
   2789             DtInsertSubtable (ParentTable, Subtable);
   2790             NodeLength += Subtable->Length;
   2791 
   2792             /*
   2793              * Padding - Variable-length data
   2794              * Optionally allows the offset of the ID mappings to be used
   2795              * for filling this field.
   2796              */
   2797             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
   2798                 &Subtable);
   2799             if (ACPI_FAILURE (Status))
   2800             {
   2801                 return (Status);
   2802             }
   2803 
   2804             if (Subtable)
   2805             {
   2806                 DtInsertSubtable (ParentTable, Subtable);
   2807                 NodeLength += Subtable->Length;
   2808             }
   2809             else
   2810             {
   2811                 if (NodeLength > IortNode->MappingOffset)
   2812                 {
   2813                     return (AE_BAD_DATA);
   2814                 }
   2815 
   2816                 if (NodeLength < IortNode->MappingOffset)
   2817                 {
   2818                     Status = DtCompilePadding (
   2819                         IortNode->MappingOffset - NodeLength,
   2820                         &Subtable);
   2821                     if (ACPI_FAILURE (Status))
   2822                     {
   2823                         return (Status);
   2824                     }
   2825 
   2826                     DtInsertSubtable (ParentTable, Subtable);
   2827                     NodeLength = IortNode->MappingOffset;
   2828                 }
   2829             }
   2830             break;
   2831 
   2832         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
   2833 
   2834             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
   2835                 &Subtable);
   2836             if (ACPI_FAILURE (Status))
   2837             {
   2838                 return (Status);
   2839             }
   2840 
   2841             DtInsertSubtable (ParentTable, Subtable);
   2842             NodeLength += Subtable->Length;
   2843             break;
   2844 
   2845         case ACPI_IORT_NODE_SMMU:
   2846 
   2847             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
   2848                 &Subtable);
   2849             if (ACPI_FAILURE (Status))
   2850             {
   2851                 return (Status);
   2852             }
   2853 
   2854             DtInsertSubtable (ParentTable, Subtable);
   2855             IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
   2856             NodeLength += Subtable->Length;
   2857 
   2858             /* Compile global interrupt array */
   2859 
   2860             IortSmmu->GlobalInterruptOffset = NodeLength;
   2861             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
   2862                 &Subtable);
   2863             if (ACPI_FAILURE (Status))
   2864             {
   2865                 return (Status);
   2866             }
   2867 
   2868             DtInsertSubtable (ParentTable, Subtable);
   2869             NodeLength += Subtable->Length;
   2870 
   2871             /* Compile context interrupt array */
   2872 
   2873             ContextIrptNumber = 0;
   2874             IortSmmu->ContextInterruptOffset = NodeLength;
   2875             while (*PFieldList)
   2876             {
   2877                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
   2878                     &Subtable);
   2879                 if (ACPI_FAILURE (Status))
   2880                 {
   2881                     return (Status);
   2882                 }
   2883 
   2884                 if (!Subtable)
   2885                 {
   2886                     break;
   2887                 }
   2888 
   2889                 DtInsertSubtable (ParentTable, Subtable);
   2890                 NodeLength += Subtable->Length;
   2891                 ContextIrptNumber++;
   2892             }
   2893 
   2894             IortSmmu->ContextInterruptCount = ContextIrptNumber;
   2895 
   2896             /* Compile PMU interrupt array */
   2897 
   2898             PmuIrptNumber = 0;
   2899             IortSmmu->PmuInterruptOffset = NodeLength;
   2900             while (*PFieldList)
   2901             {
   2902                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
   2903                     &Subtable);
   2904                 if (ACPI_FAILURE (Status))
   2905                 {
   2906                     return (Status);
   2907                 }
   2908 
   2909                 if (!Subtable)
   2910                 {
   2911                     break;
   2912                 }
   2913 
   2914                 DtInsertSubtable (ParentTable, Subtable);
   2915                 NodeLength += Subtable->Length;
   2916                 PmuIrptNumber++;
   2917             }
   2918 
   2919             IortSmmu->PmuInterruptCount = PmuIrptNumber;
   2920             break;
   2921 
   2922         case ACPI_IORT_NODE_SMMU_V3:
   2923 
   2924             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
   2925                 &Subtable);
   2926             if (ACPI_FAILURE (Status))
   2927             {
   2928                 return (Status);
   2929             }
   2930 
   2931             DtInsertSubtable (ParentTable, Subtable);
   2932             NodeLength += Subtable->Length;
   2933             break;
   2934 
   2935         case ACPI_IORT_NODE_PMCG:
   2936 
   2937             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
   2938                 &Subtable);
   2939             if (ACPI_FAILURE (Status))
   2940             {
   2941                 return (Status);
   2942             }
   2943 
   2944             DtInsertSubtable (ParentTable, Subtable);
   2945             NodeLength += Subtable->Length;
   2946             break;
   2947 
   2948         case ACPI_IORT_NODE_RMR:
   2949 
   2950             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6,
   2951                 &Subtable);
   2952             if (ACPI_FAILURE (Status))
   2953             {
   2954                 return (Status);
   2955             }
   2956 
   2957             DtInsertSubtable (ParentTable, Subtable);
   2958             IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer);
   2959             NodeLength += Subtable->Length;
   2960 
   2961             /* Compile RMR Descriptors */
   2962 
   2963             RmrCount = 0;
   2964             IortRmr->RmrOffset = NodeLength;
   2965             while (*PFieldList)
   2966             {
   2967                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a,
   2968                     &Subtable);
   2969                 if (ACPI_FAILURE (Status))
   2970                 {
   2971                     return (Status);
   2972                 }
   2973 
   2974                 if (!Subtable)
   2975                 {
   2976                     break;
   2977                 }
   2978 
   2979                 DtInsertSubtable (ParentTable, Subtable);
   2980                 NodeLength += sizeof (ACPI_IORT_RMR_DESC);
   2981                 RmrCount++;
   2982             }
   2983 
   2984             IortRmr->RmrCount = RmrCount;
   2985             break;
   2986 
   2987         default:
   2988 
   2989             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
   2990             return (AE_ERROR);
   2991         }
   2992 
   2993         /* Compile Array of ID mappings */
   2994 
   2995         IortNode->MappingOffset = NodeLength;
   2996         IdMappingNumber = 0;
   2997         while (*PFieldList)
   2998         {
   2999             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
   3000                 &Subtable);
   3001             if (ACPI_FAILURE (Status))
   3002             {
   3003                 return (Status);
   3004             }
   3005 
   3006             if (!Subtable)
   3007             {
   3008                 break;
   3009             }
   3010 
   3011             DtInsertSubtable (ParentTable, Subtable);
   3012             NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
   3013             IdMappingNumber++;
   3014         }
   3015 
   3016         IortNode->MappingCount = IdMappingNumber;
   3017         if (!IdMappingNumber)
   3018         {
   3019             IortNode->MappingOffset = 0;
   3020         }
   3021 
   3022         /*
   3023          * Node length can be determined by DT_LENGTH option
   3024          * IortNode->Length = NodeLength;
   3025          */
   3026         DtPopSubtable ();
   3027         ParentTable = DtPeekSubtable ();
   3028         NodeNumber++;
   3029     }
   3030 
   3031     Iort->NodeCount = NodeNumber;
   3032     return (AE_OK);
   3033 }
   3034 
   3035 
   3036 /******************************************************************************
   3037  *
   3038  * FUNCTION:    DtCompileIvrs
   3039  *
   3040  * PARAMETERS:  List                - Current field list pointer
   3041  *
   3042  * RETURN:      Status
   3043  *
   3044  * DESCRIPTION: Compile IVRS. Notes:
   3045  *              The IVRS is essentially a flat table, with the following
   3046  *              structure:
   3047  *              <Main ACPI Table Header>
   3048  *              <Main subtable - virtualization info>
   3049  *              <IVHD>
   3050  *                  <Device Entries>
   3051  *              ...
   3052  *              <IVHD>
   3053  *                  <Device Entries>
   3054  *              <IVMD>
   3055  *              ...
   3056  *
   3057  *****************************************************************************/
   3058 
   3059 ACPI_STATUS
   3060 DtCompileIvrs (
   3061     void                    **List)
   3062 {
   3063     ACPI_STATUS             Status;
   3064     DT_SUBTABLE             *Subtable;
   3065     DT_SUBTABLE             *ParentTable;
   3066     DT_SUBTABLE             *MainSubtable;
   3067     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   3068     DT_FIELD                *SubtableStart;
   3069     ACPI_DMTABLE_INFO       *InfoTable = NULL;
   3070     UINT8                   SubtableType;
   3071     UINT8                   Temp64[16];
   3072     UINT8                   Temp8;
   3073 
   3074 
   3075     /* Main table */
   3076 
   3077     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
   3078         &Subtable);
   3079     if (ACPI_FAILURE (Status))
   3080     {
   3081         return (Status);
   3082     }
   3083 
   3084     ParentTable = DtPeekSubtable ();
   3085     DtInsertSubtable (ParentTable, Subtable);
   3086     DtPushSubtable (Subtable);
   3087 
   3088     /* Save a pointer to the main subtable */
   3089 
   3090     MainSubtable = Subtable;
   3091 
   3092     while (*PFieldList)
   3093     {
   3094         SubtableStart = *PFieldList;
   3095 
   3096         /* Compile the SubtableType integer */
   3097 
   3098         DtCompileInteger (&SubtableType, *PFieldList, 1, 0);
   3099 
   3100         switch (SubtableType)
   3101         {
   3102 
   3103         /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */
   3104 
   3105         case ACPI_IVRS_TYPE_HARDWARE1:
   3106 
   3107             InfoTable = AcpiDmTableInfoIvrsHware1;
   3108             break;
   3109 
   3110         /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */
   3111 
   3112         case ACPI_IVRS_TYPE_HARDWARE2:
   3113         case ACPI_IVRS_TYPE_HARDWARE3:
   3114 
   3115             InfoTable = AcpiDmTableInfoIvrsHware23;
   3116             break;
   3117 
   3118         /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */
   3119 
   3120         case ACPI_IVRS_TYPE_MEMORY1:
   3121         case ACPI_IVRS_TYPE_MEMORY2:
   3122         case ACPI_IVRS_TYPE_MEMORY3:
   3123 
   3124             InfoTable = AcpiDmTableInfoIvrsMemory;
   3125             break;
   3126 
   3127         /* 4-byte device entries */
   3128 
   3129         case ACPI_IVRS_TYPE_PAD4:
   3130         case ACPI_IVRS_TYPE_ALL:
   3131         case ACPI_IVRS_TYPE_SELECT:
   3132         case ACPI_IVRS_TYPE_START:
   3133         case ACPI_IVRS_TYPE_END:
   3134 
   3135             InfoTable = AcpiDmTableInfoIvrs4;
   3136             break;
   3137 
   3138         /* 8-byte device entries, type A */
   3139 
   3140         case ACPI_IVRS_TYPE_ALIAS_SELECT:
   3141         case ACPI_IVRS_TYPE_ALIAS_START:
   3142 
   3143             InfoTable = AcpiDmTableInfoIvrs8a;
   3144             break;
   3145 
   3146         /* 8-byte device entries, type B */
   3147 
   3148         case ACPI_IVRS_TYPE_EXT_SELECT:
   3149         case ACPI_IVRS_TYPE_EXT_START:
   3150 
   3151             InfoTable = AcpiDmTableInfoIvrs8b;
   3152             break;
   3153 
   3154         /* 8-byte device entries, type C */
   3155 
   3156         case ACPI_IVRS_TYPE_SPECIAL:
   3157 
   3158             InfoTable = AcpiDmTableInfoIvrs8c;
   3159             break;
   3160 
   3161         /* Variable device entries, type F0h */
   3162 
   3163         case ACPI_IVRS_TYPE_HID:
   3164 
   3165             InfoTable = AcpiDmTableInfoIvrsHid;
   3166             break;
   3167 
   3168         default:
   3169 
   3170             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
   3171                 "IVRS Device Entry");
   3172             return (AE_ERROR);
   3173         }
   3174 
   3175         /* Compile the InfoTable from above */
   3176 
   3177         Status = DtCompileTable (PFieldList, InfoTable,
   3178             &Subtable);
   3179         if (ACPI_FAILURE (Status))
   3180         {
   3181             return (Status);
   3182         }
   3183 
   3184         ParentTable = DtPeekSubtable ();
   3185         if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 &&
   3186             SubtableType != ACPI_IVRS_TYPE_HARDWARE2 &&
   3187             SubtableType != ACPI_IVRS_TYPE_HARDWARE3 &&
   3188             SubtableType != ACPI_IVRS_TYPE_HID &&
   3189             SubtableType != ACPI_IVRS_TYPE_MEMORY1 &&
   3190             SubtableType != ACPI_IVRS_TYPE_MEMORY2 &&
   3191             SubtableType != ACPI_IVRS_TYPE_MEMORY3)
   3192         {
   3193             if (ParentTable)
   3194                 DtInsertSubtable (ParentTable, Subtable);
   3195         }
   3196 
   3197         switch (SubtableType)
   3198         {
   3199         case ACPI_IVRS_TYPE_HARDWARE1:
   3200         case ACPI_IVRS_TYPE_HARDWARE2:
   3201         case ACPI_IVRS_TYPE_HARDWARE3:
   3202         case ACPI_IVRS_TYPE_MEMORY1:
   3203         case ACPI_IVRS_TYPE_MEMORY2:
   3204         case ACPI_IVRS_TYPE_MEMORY3:
   3205 
   3206             /* Insert these IVHDs/IVMDs at the root subtable */
   3207 
   3208             DtInsertSubtable (MainSubtable, Subtable);
   3209             DtPushSubtable (Subtable);
   3210             break;
   3211 
   3212         case ACPI_IVRS_TYPE_HID:
   3213 
   3214             /* Special handling for the HID named device entry (0xF0) */
   3215 
   3216             if (ParentTable)
   3217             {
   3218                 DtInsertSubtable (ParentTable, Subtable);
   3219             }
   3220 
   3221             /*
   3222              * Process the HID value. First, get the HID value as a string.
   3223              */
   3224             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
   3225 
   3226                /*
   3227                 * Determine if the HID is an integer or a string.
   3228                 * An integer is defined to be 32 bits, with the upper 32 bits
   3229                 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit
   3230                 * integer or a character string. If an integer, the lower
   3231                 * 4 bytes of the field contain the integer and the upper
   3232                 * 4 bytes are padded with 0".
   3233                 */
   3234             if (UtIsIdInteger ((UINT8 *) &Temp64))
   3235             {
   3236                 /* Compile the HID value as an integer */
   3237 
   3238                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
   3239 
   3240                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger,
   3241                     &Subtable);
   3242                 if (ACPI_FAILURE (Status))
   3243                 {
   3244                     return (Status);
   3245                 }
   3246             }
   3247             else
   3248             {
   3249                 /* Compile the HID value as a string */
   3250 
   3251                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString,
   3252                     &Subtable);
   3253                 if (ACPI_FAILURE (Status))
   3254                 {
   3255                     return (Status);
   3256                 }
   3257             }
   3258 
   3259             DtInsertSubtable (ParentTable, Subtable);
   3260 
   3261             /*
   3262              * Process the CID value. First, get the CID value as a string.
   3263              */
   3264             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
   3265 
   3266             if (UtIsIdInteger ((UINT8 *) &Temp64))
   3267             {
   3268                 /* Compile the CID value as an integer */
   3269 
   3270                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
   3271 
   3272                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger,
   3273                     &Subtable);
   3274                 if (ACPI_FAILURE (Status))
   3275                 {
   3276                     return (Status);
   3277                 }
   3278             }
   3279             else
   3280             {
   3281                 /* Compile the CID value as a string */
   3282 
   3283                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString,
   3284                     &Subtable);
   3285                 if (ACPI_FAILURE (Status))
   3286                 {
   3287                     return (Status);
   3288                 }
   3289             }
   3290 
   3291             DtInsertSubtable (ParentTable, Subtable);
   3292 
   3293             /*
   3294              * Process the UID value. First, get and decode the "UID Format" field (Integer).
   3295              */
   3296             if (!*PFieldList)
   3297             {
   3298                 return (AE_OK);
   3299             }
   3300 
   3301             DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0);
   3302 
   3303             switch (Temp8)
   3304             {
   3305             case ACPI_IVRS_UID_NOT_PRESENT:
   3306                 break;
   3307 
   3308             case ACPI_IVRS_UID_IS_INTEGER:
   3309 
   3310                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger,
   3311                     &Subtable);
   3312                 if (ACPI_FAILURE (Status))
   3313                 {
   3314                     return (Status);
   3315                 }
   3316                 DtInsertSubtable (ParentTable, Subtable);
   3317                 break;
   3318 
   3319             case ACPI_IVRS_UID_IS_STRING:
   3320 
   3321                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString,
   3322                     &Subtable);
   3323                 if (ACPI_FAILURE (Status))
   3324                 {
   3325                     return (Status);
   3326                 }
   3327                 DtInsertSubtable (ParentTable, Subtable);
   3328                 break;
   3329 
   3330             default:
   3331 
   3332                 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart,
   3333                     "IVRS Device Entry");
   3334                 return (AE_ERROR);
   3335             }
   3336 
   3337         default:
   3338 
   3339             /* All other subtable types come through here */
   3340             break;
   3341         }
   3342     }
   3343 
   3344     return (AE_OK);
   3345 }
   3346 
   3347 
   3348 /******************************************************************************
   3349  *
   3350  * FUNCTION:    DtCompileRimt
   3351  *
   3352  * PARAMETERS:  List                - Current field list pointer
   3353  *
   3354  * RETURN:      Status
   3355  *
   3356  * DESCRIPTION: Compile RIMT.
   3357  *
   3358  *****************************************************************************/
   3359 
   3360 ACPI_STATUS
   3361 DtCompileRimt (
   3362     void                    **List)
   3363 {
   3364     ACPI_RIMT_PLATFORM_DEVICE  *PlatDevNode;
   3365     ACPI_RIMT_PCIE_RC          *PcieRcNode;
   3366     ACPI_TABLE_RIMT            *Rimt;
   3367     ACPI_RIMT_IOMMU            *IommuNode;
   3368     ACPI_RIMT_NODE             *RimtNode;
   3369     ACPI_STATUS                Status;
   3370     DT_SUBTABLE                *Subtable;
   3371     DT_SUBTABLE                *ParentTable;
   3372     DT_FIELD                   **PFieldList = (DT_FIELD **) List;
   3373     DT_FIELD                   *SubtableStart;
   3374     UINT32                     NodeNumber;
   3375     UINT32                     NodeLength;
   3376     UINT16                     IdMappingNumber;
   3377     UINT32                     i;
   3378 
   3379 
   3380     ParentTable = DtPeekSubtable ();
   3381 
   3382     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimt, &Subtable);
   3383     if (ACPI_FAILURE (Status))
   3384     {
   3385         return (Status);
   3386     }
   3387 
   3388     DtInsertSubtable (ParentTable, Subtable);
   3389 
   3390     /*
   3391      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   3392      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
   3393      */
   3394     Rimt = ACPI_SUB_PTR (ACPI_TABLE_RIMT, Subtable->Buffer,
   3395                          sizeof (ACPI_TABLE_HEADER));
   3396 
   3397     NodeNumber = 0;
   3398     while (*PFieldList)
   3399     {
   3400         SubtableStart = *PFieldList;
   3401         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtNodeHdr, &Subtable);
   3402 
   3403         if (ACPI_FAILURE (Status))
   3404         {
   3405             return (Status);
   3406         }
   3407 
   3408         DtInsertSubtable (ParentTable, Subtable);
   3409         RimtNode = ACPI_CAST_PTR (ACPI_RIMT_NODE, Subtable->Buffer);
   3410         NodeLength = ACPI_OFFSET (ACPI_RIMT_NODE, NodeData);
   3411 
   3412         DtPushSubtable (Subtable);
   3413         ParentTable = DtPeekSubtable ();
   3414 
   3415         switch (RimtNode->Type)
   3416         {
   3417         case ACPI_RIMT_NODE_TYPE_IOMMU:
   3418 
   3419             Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtIommu,
   3420                                      &Subtable);
   3421             if (ACPI_FAILURE (Status))
   3422             {
   3423                 return (Status);
   3424             }
   3425 
   3426             IommuNode = ACPI_CAST_PTR (ACPI_RIMT_IOMMU, Subtable->Buffer);
   3427             DtInsertSubtable (ParentTable, Subtable);
   3428             NodeLength += Subtable->Length;
   3429 
   3430             for (i = 0; i < IommuNode->NumInterruptWires; i++)
   3431             {
   3432                 while (*PFieldList)
   3433                 {
   3434                     Status = DtCompileTable (PFieldList,
   3435                                              AcpiDmTableInfoRimtIommuWire,
   3436                                              &Subtable);
   3437                     if (ACPI_FAILURE (Status))
   3438                     {
   3439                         return (Status);
   3440                     }
   3441                     if (!Subtable)
   3442                     {
   3443                         break;
   3444                     }
   3445 
   3446                     DtInsertSubtable (ParentTable, Subtable);
   3447                     NodeLength += Subtable->Length;
   3448                 }
   3449             }
   3450 
   3451             break;
   3452 
   3453         case ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX:
   3454 
   3455             Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPcieRc,
   3456                                      &Subtable);
   3457             if (ACPI_FAILURE (Status))
   3458             {
   3459                 return (Status);
   3460             }
   3461 
   3462             DtInsertSubtable (ParentTable, Subtable);
   3463             PcieRcNode = ACPI_CAST_PTR (ACPI_RIMT_PCIE_RC, Subtable->Buffer);
   3464             NodeLength += Subtable->Length;
   3465 
   3466             /* Compile Array of ID mappings */
   3467 
   3468             PcieRcNode->IdMappingOffset = (UINT16) NodeLength;
   3469             IdMappingNumber = 0;
   3470             while (*PFieldList)
   3471             {
   3472                 Status = DtCompileTable (PFieldList,
   3473                                          AcpiDmTableInfoRimtIdMapping,
   3474                                          &Subtable);
   3475                 if (ACPI_FAILURE (Status))
   3476                 {
   3477                     return (Status);
   3478                 }
   3479 
   3480                 if (!Subtable)
   3481                 {
   3482                     break;
   3483                 }
   3484 
   3485                 DtInsertSubtable (ParentTable, Subtable);
   3486                 NodeLength += sizeof (ACPI_RIMT_ID_MAPPING);
   3487                 IdMappingNumber++;
   3488             }
   3489 
   3490             PcieRcNode->NumIdMappings = IdMappingNumber;
   3491             if (!IdMappingNumber)
   3492             {
   3493                 PcieRcNode->IdMappingOffset = 0;
   3494             }
   3495 
   3496             break;
   3497 
   3498         case ACPI_RIMT_NODE_TYPE_PLAT_DEVICE:
   3499 
   3500             Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPlatDev,
   3501                                      &Subtable);
   3502             if (ACPI_FAILURE (Status))
   3503             {
   3504                 return (Status);
   3505             }
   3506 
   3507             DtInsertSubtable (ParentTable, Subtable);
   3508             PlatDevNode = ACPI_CAST_PTR (ACPI_RIMT_PLATFORM_DEVICE, Subtable->Buffer);
   3509             NodeLength += Subtable->Length;
   3510 
   3511             /*
   3512              * Padding - Variable-length data
   3513              * Optionally allows the offset of the ID mappings to be used
   3514              * for filling this field.
   3515              */
   3516             Status = DtCompileTable (PFieldList, AcpiDmTableInfoRimtPlatDevPad,
   3517                                      &Subtable);
   3518             if (ACPI_FAILURE (Status))
   3519             {
   3520                 return (Status);
   3521             }
   3522 
   3523             if (Subtable)
   3524             {
   3525                 DtInsertSubtable (ParentTable, Subtable);
   3526                 NodeLength += Subtable->Length;
   3527             }
   3528             else
   3529             {
   3530                 if (NodeLength > PlatDevNode->IdMappingOffset)
   3531                 {
   3532                     return (AE_BAD_DATA);
   3533                 }
   3534 
   3535                 if (NodeLength < PlatDevNode->IdMappingOffset)
   3536                 {
   3537                     Status = DtCompilePadding (
   3538                         PlatDevNode->IdMappingOffset - (UINT16) NodeLength,
   3539                         &Subtable);
   3540                     if (ACPI_FAILURE (Status))
   3541                     {
   3542                         return (Status);
   3543                     }
   3544 
   3545                     DtInsertSubtable (ParentTable, Subtable);
   3546                     NodeLength = PlatDevNode->IdMappingOffset;
   3547                 }
   3548             }
   3549 
   3550             /* Compile Array of ID mappings */
   3551 
   3552             PlatDevNode->IdMappingOffset = (UINT16) NodeLength;
   3553             IdMappingNumber = 0;
   3554             while (*PFieldList)
   3555             {
   3556                 Status = DtCompileTable (PFieldList,
   3557                                          AcpiDmTableInfoRimtIdMapping,
   3558                                          &Subtable);
   3559                 if (ACPI_FAILURE (Status))
   3560                 {
   3561                     return (Status);
   3562                 }
   3563 
   3564                 if (!Subtable)
   3565                 {
   3566                     break;
   3567                 }
   3568 
   3569                 DtInsertSubtable (ParentTable, Subtable);
   3570                 NodeLength += sizeof (ACPI_RIMT_ID_MAPPING);
   3571                 IdMappingNumber++;
   3572             }
   3573 
   3574             PlatDevNode->NumIdMappings = IdMappingNumber;
   3575             if (!IdMappingNumber)
   3576             {
   3577                 PlatDevNode->IdMappingOffset = 0;
   3578             }
   3579 
   3580             break;
   3581 
   3582 
   3583         default:
   3584 
   3585             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RIMT");
   3586             return (AE_ERROR);
   3587         }
   3588 
   3589         DtPopSubtable ();
   3590         ParentTable = DtPeekSubtable ();
   3591         NodeNumber++;
   3592     }
   3593 
   3594     Rimt->NumNodes = NodeNumber;
   3595     return (AE_OK);
   3596 }
   3597