Home | History | Annotate | Line # | Download | only in compiler
dttable1.c revision 1.1.1.18
      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 - 2024, 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         default:
   1511 
   1512             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
   1513             return (AE_ERROR);
   1514         }
   1515 
   1516         /* DMAR Subtable */
   1517 
   1518         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1519         if (ACPI_FAILURE (Status))
   1520         {
   1521             return (Status);
   1522         }
   1523 
   1524         ParentTable = DtPeekSubtable ();
   1525         DtInsertSubtable (ParentTable, Subtable);
   1526 
   1527         /*
   1528          * Optional Device Scope subtables
   1529          */
   1530         if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
   1531             (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
   1532         {
   1533             /* These types do not support device scopes */
   1534 
   1535             DtPopSubtable ();
   1536             continue;
   1537         }
   1538 
   1539         DtPushSubtable (Subtable);
   1540         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
   1541             ParentTable->Length;
   1542         while (DeviceScopeLength)
   1543         {
   1544             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
   1545                 &Subtable);
   1546             if (Status == AE_NOT_FOUND)
   1547             {
   1548                 break;
   1549             }
   1550 
   1551             ParentTable = DtPeekSubtable ();
   1552             DtInsertSubtable (ParentTable, Subtable);
   1553             DtPushSubtable (Subtable);
   1554 
   1555             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
   1556 
   1557             /* Optional PCI Paths */
   1558 
   1559             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
   1560             while (PciPathLength)
   1561             {
   1562                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
   1563                     &Subtable);
   1564                 if (Status == AE_NOT_FOUND)
   1565                 {
   1566                     DtPopSubtable ();
   1567                     break;
   1568                 }
   1569 
   1570                 ParentTable = DtPeekSubtable ();
   1571                 DtInsertSubtable (ParentTable, Subtable);
   1572                 PciPathLength -= Subtable->Length;
   1573             }
   1574 
   1575             DtPopSubtable ();
   1576             DeviceScopeLength -= DmarDeviceScope->Length;
   1577         }
   1578 
   1579         DtPopSubtable ();
   1580         DtPopSubtable ();
   1581     }
   1582 
   1583     return (AE_OK);
   1584 }
   1585 
   1586 
   1587 /******************************************************************************
   1588  *
   1589  * FUNCTION:    DtCompileDrtm
   1590  *
   1591  * PARAMETERS:  List                - Current field list pointer
   1592  *
   1593  * RETURN:      Status
   1594  *
   1595  * DESCRIPTION: Compile DRTM.
   1596  *
   1597  *****************************************************************************/
   1598 
   1599 ACPI_STATUS
   1600 DtCompileDrtm (
   1601     void                    **List)
   1602 {
   1603     ACPI_STATUS             Status;
   1604     DT_SUBTABLE             *Subtable;
   1605     DT_SUBTABLE             *ParentTable;
   1606     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1607     UINT32                  Count;
   1608     /* ACPI_TABLE_DRTM         *Drtm; */
   1609     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
   1610     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
   1611     /* ACPI_DRTM_DPS_ID        *DrtmDps; */
   1612 
   1613 
   1614     ParentTable = DtPeekSubtable ();
   1615 
   1616     /* Compile DRTM header */
   1617 
   1618     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
   1619         &Subtable);
   1620     if (ACPI_FAILURE (Status))
   1621     {
   1622         return (Status);
   1623     }
   1624     DtInsertSubtable (ParentTable, Subtable);
   1625 
   1626     /*
   1627      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   1628      * should be taken to avoid accessing ACPI_TABLE_HADER fields.
   1629      */
   1630 #if 0
   1631     Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
   1632         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
   1633 #endif
   1634     /* Compile VTL */
   1635 
   1636     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
   1637         &Subtable);
   1638     if (ACPI_FAILURE (Status))
   1639     {
   1640         return (Status);
   1641     }
   1642 
   1643     DtInsertSubtable (ParentTable, Subtable);
   1644     DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
   1645 
   1646     DtPushSubtable (Subtable);
   1647     ParentTable = DtPeekSubtable ();
   1648     Count = 0;
   1649 
   1650     while (*PFieldList)
   1651     {
   1652         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
   1653             &Subtable);
   1654         if (ACPI_FAILURE (Status))
   1655         {
   1656             return (Status);
   1657         }
   1658         if (!Subtable)
   1659         {
   1660             break;
   1661         }
   1662         DtInsertSubtable (ParentTable, Subtable);
   1663         Count++;
   1664     }
   1665 
   1666     DrtmVtl->ValidatedTableCount = Count;
   1667     DtPopSubtable ();
   1668     ParentTable = DtPeekSubtable ();
   1669 
   1670     /* Compile RL */
   1671 
   1672     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
   1673         &Subtable);
   1674     if (ACPI_FAILURE (Status))
   1675     {
   1676         return (Status);
   1677     }
   1678 
   1679     DtInsertSubtable (ParentTable, Subtable);
   1680     DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
   1681 
   1682     DtPushSubtable (Subtable);
   1683     ParentTable = DtPeekSubtable ();
   1684     Count = 0;
   1685 
   1686     while (*PFieldList)
   1687     {
   1688         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
   1689             &Subtable);
   1690         if (ACPI_FAILURE (Status))
   1691         {
   1692             return (Status);
   1693         }
   1694 
   1695         if (!Subtable)
   1696         {
   1697             break;
   1698         }
   1699 
   1700         DtInsertSubtable (ParentTable, Subtable);
   1701         Count++;
   1702     }
   1703 
   1704     DrtmRl->ResourceCount = Count;
   1705     DtPopSubtable ();
   1706     ParentTable = DtPeekSubtable ();
   1707 
   1708     /* Compile DPS */
   1709 
   1710     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
   1711         &Subtable);
   1712     if (ACPI_FAILURE (Status))
   1713     {
   1714         return (Status);
   1715     }
   1716     DtInsertSubtable (ParentTable, Subtable);
   1717     /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
   1718 
   1719 
   1720     return (AE_OK);
   1721 }
   1722 
   1723 
   1724 /******************************************************************************
   1725  *
   1726  * FUNCTION:    DtCompileEinj
   1727  *
   1728  * PARAMETERS:  List                - Current field list pointer
   1729  *
   1730  * RETURN:      Status
   1731  *
   1732  * DESCRIPTION: Compile EINJ.
   1733  *
   1734  *****************************************************************************/
   1735 
   1736 ACPI_STATUS
   1737 DtCompileEinj (
   1738     void                    **List)
   1739 {
   1740     ACPI_STATUS             Status;
   1741 
   1742 
   1743     Status = DtCompileTwoSubtables (List,
   1744         AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
   1745     return (Status);
   1746 }
   1747 
   1748 
   1749 /******************************************************************************
   1750  *
   1751  * FUNCTION:    DtCompileErst
   1752  *
   1753  * PARAMETERS:  List                - Current field list pointer
   1754  *
   1755  * RETURN:      Status
   1756  *
   1757  * DESCRIPTION: Compile ERST.
   1758  *
   1759  *****************************************************************************/
   1760 
   1761 ACPI_STATUS
   1762 DtCompileErst (
   1763     void                    **List)
   1764 {
   1765     ACPI_STATUS             Status;
   1766 
   1767 
   1768     Status = DtCompileTwoSubtables (List,
   1769         AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
   1770     return (Status);
   1771 }
   1772 
   1773 
   1774 /******************************************************************************
   1775  *
   1776  * FUNCTION:    DtCompileGtdt
   1777  *
   1778  * PARAMETERS:  List                - Current field list pointer
   1779  *
   1780  * RETURN:      Status
   1781  *
   1782  * DESCRIPTION: Compile GTDT.
   1783  *
   1784  *****************************************************************************/
   1785 
   1786 ACPI_STATUS
   1787 DtCompileGtdt (
   1788     void                    **List)
   1789 {
   1790     ACPI_STATUS             Status;
   1791     DT_SUBTABLE             *Subtable;
   1792     DT_SUBTABLE             *ParentTable;
   1793     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1794     DT_FIELD                *SubtableStart;
   1795     ACPI_SUBTABLE_HEADER    *GtdtHeader;
   1796     ACPI_DMTABLE_INFO       *InfoTable;
   1797     UINT32                  GtCount;
   1798     ACPI_TABLE_HEADER       *Header;
   1799 
   1800 
   1801     ParentTable = DtPeekSubtable ();
   1802 
   1803     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   1804 
   1805     /* Compile the main table */
   1806 
   1807     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
   1808         &Subtable);
   1809     if (ACPI_FAILURE (Status))
   1810     {
   1811         return (Status);
   1812     }
   1813 
   1814     /* GTDT revision 3 later contains 2 extra fields before subtables */
   1815 
   1816     if (Header->Revision > 2)
   1817     {
   1818         ParentTable = DtPeekSubtable ();
   1819         DtInsertSubtable (ParentTable, Subtable);
   1820 
   1821         Status = DtCompileTable (PFieldList,
   1822             AcpiDmTableInfoGtdtEl2, &Subtable);
   1823         if (ACPI_FAILURE (Status))
   1824         {
   1825             return (Status);
   1826         }
   1827     }
   1828 
   1829     ParentTable = DtPeekSubtable ();
   1830     DtInsertSubtable (ParentTable, Subtable);
   1831 
   1832     while (*PFieldList)
   1833     {
   1834         SubtableStart = *PFieldList;
   1835         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
   1836             &Subtable);
   1837         if (ACPI_FAILURE (Status))
   1838         {
   1839             return (Status);
   1840         }
   1841 
   1842         ParentTable = DtPeekSubtable ();
   1843         DtInsertSubtable (ParentTable, Subtable);
   1844         DtPushSubtable (Subtable);
   1845 
   1846         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
   1847 
   1848         switch (GtdtHeader->Type)
   1849         {
   1850         case ACPI_GTDT_TYPE_TIMER_BLOCK:
   1851 
   1852             InfoTable = AcpiDmTableInfoGtdt0;
   1853             break;
   1854 
   1855         case ACPI_GTDT_TYPE_WATCHDOG:
   1856 
   1857             InfoTable = AcpiDmTableInfoGtdt1;
   1858             break;
   1859 
   1860         default:
   1861 
   1862             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
   1863             return (AE_ERROR);
   1864         }
   1865 
   1866         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1867         if (ACPI_FAILURE (Status))
   1868         {
   1869             return (Status);
   1870         }
   1871 
   1872         ParentTable = DtPeekSubtable ();
   1873         DtInsertSubtable (ParentTable, Subtable);
   1874 
   1875         /*
   1876          * Additional GT block subtable data
   1877          */
   1878 
   1879         switch (GtdtHeader->Type)
   1880         {
   1881         case ACPI_GTDT_TYPE_TIMER_BLOCK:
   1882 
   1883             DtPushSubtable (Subtable);
   1884             ParentTable = DtPeekSubtable ();
   1885 
   1886             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
   1887                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
   1888 
   1889             while (GtCount)
   1890             {
   1891                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
   1892                     &Subtable);
   1893                 if (ACPI_FAILURE (Status))
   1894                 {
   1895                     return (Status);
   1896                 }
   1897 
   1898                 DtInsertSubtable (ParentTable, Subtable);
   1899                 GtCount--;
   1900             }
   1901 
   1902             DtPopSubtable ();
   1903             break;
   1904 
   1905         default:
   1906 
   1907             break;
   1908         }
   1909 
   1910         DtPopSubtable ();
   1911     }
   1912 
   1913     return (AE_OK);
   1914 }
   1915 
   1916 
   1917 /******************************************************************************
   1918  *
   1919  * FUNCTION:    DtCompileFpdt
   1920  *
   1921  * PARAMETERS:  List                - Current field list pointer
   1922  *
   1923  * RETURN:      Status
   1924  *
   1925  * DESCRIPTION: Compile FPDT.
   1926  *
   1927  *****************************************************************************/
   1928 
   1929 ACPI_STATUS
   1930 DtCompileFpdt (
   1931     void                    **List)
   1932 {
   1933     ACPI_STATUS             Status;
   1934     ACPI_FPDT_HEADER        *FpdtHeader;
   1935     DT_SUBTABLE             *Subtable;
   1936     DT_SUBTABLE             *ParentTable;
   1937     ACPI_DMTABLE_INFO       *InfoTable;
   1938     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1939     DT_FIELD                *SubtableStart;
   1940 
   1941 
   1942     while (*PFieldList)
   1943     {
   1944         SubtableStart = *PFieldList;
   1945         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
   1946             &Subtable);
   1947         if (ACPI_FAILURE (Status))
   1948         {
   1949             return (Status);
   1950         }
   1951 
   1952         ParentTable = DtPeekSubtable ();
   1953         DtInsertSubtable (ParentTable, Subtable);
   1954         DtPushSubtable (Subtable);
   1955 
   1956         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
   1957 
   1958         switch (FpdtHeader->Type)
   1959         {
   1960         case ACPI_FPDT_TYPE_BOOT:
   1961 
   1962             InfoTable = AcpiDmTableInfoFpdt0;
   1963             break;
   1964 
   1965         case ACPI_FPDT_TYPE_S3PERF:
   1966 
   1967             InfoTable = AcpiDmTableInfoFpdt1;
   1968             break;
   1969 
   1970         default:
   1971 
   1972             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
   1973             return (AE_ERROR);
   1974             break;
   1975         }
   1976 
   1977         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1978         if (ACPI_FAILURE (Status))
   1979         {
   1980             return (Status);
   1981         }
   1982 
   1983         ParentTable = DtPeekSubtable ();
   1984         DtInsertSubtable (ParentTable, Subtable);
   1985         DtPopSubtable ();
   1986     }
   1987 
   1988     return (AE_OK);
   1989 }
   1990 
   1991 
   1992 /******************************************************************************
   1993  *
   1994  * FUNCTION:    DtCompileHest
   1995  *
   1996  * PARAMETERS:  List                - Current field list pointer
   1997  *
   1998  * RETURN:      Status
   1999  *
   2000  * DESCRIPTION: Compile HEST.
   2001  *
   2002  *****************************************************************************/
   2003 
   2004 ACPI_STATUS
   2005 DtCompileHest (
   2006     void                    **List)
   2007 {
   2008     ACPI_STATUS             Status;
   2009     DT_SUBTABLE             *Subtable;
   2010     DT_SUBTABLE             *ParentTable;
   2011     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2012     DT_FIELD                *SubtableStart;
   2013     ACPI_DMTABLE_INFO       *InfoTable;
   2014     UINT16                  Type;
   2015     UINT32                  BankCount;
   2016 
   2017 
   2018     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
   2019         &Subtable);
   2020     if (ACPI_FAILURE (Status))
   2021     {
   2022         return (Status);
   2023     }
   2024 
   2025     ParentTable = DtPeekSubtable ();
   2026     DtInsertSubtable (ParentTable, Subtable);
   2027 
   2028     while (*PFieldList)
   2029     {
   2030         /* Get subtable type */
   2031 
   2032         SubtableStart = *PFieldList;
   2033         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
   2034 
   2035         switch (Type)
   2036         {
   2037         case ACPI_HEST_TYPE_IA32_CHECK:
   2038 
   2039             InfoTable = AcpiDmTableInfoHest0;
   2040             break;
   2041 
   2042         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   2043 
   2044             InfoTable = AcpiDmTableInfoHest1;
   2045             break;
   2046 
   2047         case ACPI_HEST_TYPE_IA32_NMI:
   2048 
   2049             InfoTable = AcpiDmTableInfoHest2;
   2050             break;
   2051 
   2052         case ACPI_HEST_TYPE_AER_ROOT_PORT:
   2053 
   2054             InfoTable = AcpiDmTableInfoHest6;
   2055             break;
   2056 
   2057         case ACPI_HEST_TYPE_AER_ENDPOINT:
   2058 
   2059             InfoTable = AcpiDmTableInfoHest7;
   2060             break;
   2061 
   2062         case ACPI_HEST_TYPE_AER_BRIDGE:
   2063 
   2064             InfoTable = AcpiDmTableInfoHest8;
   2065             break;
   2066 
   2067         case ACPI_HEST_TYPE_GENERIC_ERROR:
   2068 
   2069             InfoTable = AcpiDmTableInfoHest9;
   2070             break;
   2071 
   2072         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
   2073 
   2074             InfoTable = AcpiDmTableInfoHest10;
   2075             break;
   2076 
   2077         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   2078 
   2079             InfoTable = AcpiDmTableInfoHest11;
   2080             break;
   2081 
   2082         default:
   2083 
   2084             /* Cannot continue on unknown type */
   2085 
   2086             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
   2087             return (AE_ERROR);
   2088         }
   2089 
   2090         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   2091         if (ACPI_FAILURE (Status))
   2092         {
   2093             return (Status);
   2094         }
   2095 
   2096         DtInsertSubtable (ParentTable, Subtable);
   2097 
   2098         /*
   2099          * Additional subtable data - IA32 Error Bank(s)
   2100          */
   2101         BankCount = 0;
   2102         switch (Type)
   2103         {
   2104         case ACPI_HEST_TYPE_IA32_CHECK:
   2105 
   2106             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
   2107                 Subtable->Buffer))->NumHardwareBanks;
   2108             break;
   2109 
   2110         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   2111 
   2112             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
   2113                 Subtable->Buffer))->NumHardwareBanks;
   2114             break;
   2115 
   2116         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   2117 
   2118             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
   2119                 Subtable->Buffer))->NumHardwareBanks;
   2120             break;
   2121 
   2122         default:
   2123 
   2124             break;
   2125         }
   2126 
   2127         while (BankCount)
   2128         {
   2129             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
   2130                 &Subtable);
   2131             if (ACPI_FAILURE (Status))
   2132             {
   2133                 return (Status);
   2134             }
   2135 
   2136             DtInsertSubtable (ParentTable, Subtable);
   2137             BankCount--;
   2138         }
   2139     }
   2140 
   2141     return (AE_OK);
   2142 }
   2143 
   2144 
   2145 /******************************************************************************
   2146  *
   2147  * FUNCTION:    DtCompileHmat
   2148  *
   2149  * PARAMETERS:  List                - Current field list pointer
   2150  *
   2151  * RETURN:      Status
   2152  *
   2153  * DESCRIPTION: Compile HMAT.
   2154  *
   2155  *****************************************************************************/
   2156 
   2157 ACPI_STATUS
   2158 DtCompileHmat (
   2159     void                    **List)
   2160 {
   2161     ACPI_STATUS             Status;
   2162     DT_SUBTABLE             *Subtable;
   2163     DT_SUBTABLE             *ParentTable;
   2164     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2165     DT_FIELD                *SubtableStart;
   2166     DT_FIELD                *EntryStart;
   2167     ACPI_HMAT_STRUCTURE     *HmatStruct;
   2168     ACPI_HMAT_LOCALITY      *HmatLocality;
   2169     ACPI_HMAT_CACHE         *HmatCache;
   2170     ACPI_DMTABLE_INFO       *InfoTable;
   2171     UINT32                  IntPDNumber;
   2172     UINT32                  TgtPDNumber;
   2173     UINT64                  EntryNumber;
   2174     UINT16                  SMBIOSHandleNumber;
   2175 
   2176 
   2177     ParentTable = DtPeekSubtable ();
   2178 
   2179     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
   2180         &Subtable);
   2181     if (ACPI_FAILURE (Status))
   2182     {
   2183         return (Status);
   2184     }
   2185     DtInsertSubtable (ParentTable, Subtable);
   2186 
   2187     while (*PFieldList)
   2188     {
   2189         /* Compile HMAT structure header */
   2190 
   2191         SubtableStart = *PFieldList;
   2192         Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
   2193             &Subtable);
   2194         if (ACPI_FAILURE (Status))
   2195         {
   2196             return (Status);
   2197         }
   2198         DtInsertSubtable (ParentTable, Subtable);
   2199 
   2200         HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
   2201         HmatStruct->Length = Subtable->Length;
   2202 
   2203         /* Compile HMAT structure body */
   2204 
   2205         switch (HmatStruct->Type)
   2206         {
   2207         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
   2208 
   2209             InfoTable = AcpiDmTableInfoHmat0;
   2210             break;
   2211 
   2212         case ACPI_HMAT_TYPE_LOCALITY:
   2213 
   2214             InfoTable = AcpiDmTableInfoHmat1;
   2215             break;
   2216 
   2217         case ACPI_HMAT_TYPE_CACHE:
   2218 
   2219             InfoTable = AcpiDmTableInfoHmat2;
   2220             break;
   2221 
   2222         default:
   2223 
   2224             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
   2225             return (AE_ERROR);
   2226         }
   2227 
   2228         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   2229         if (ACPI_FAILURE (Status))
   2230         {
   2231             return (Status);
   2232         }
   2233         DtInsertSubtable (ParentTable, Subtable);
   2234         HmatStruct->Length += Subtable->Length;
   2235 
   2236         /* Compile HMAT structure additional */
   2237 
   2238         switch (HmatStruct->Type)
   2239         {
   2240         case ACPI_HMAT_TYPE_LOCALITY:
   2241 
   2242             HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
   2243                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   2244 
   2245             /* Compile initiator proximity domain list */
   2246 
   2247             IntPDNumber = 0;
   2248             while (*PFieldList)
   2249             {
   2250                 Status = DtCompileTable (PFieldList,
   2251                     AcpiDmTableInfoHmat1a, &Subtable);
   2252                 if (ACPI_FAILURE (Status))
   2253                 {
   2254                     return (Status);
   2255                 }
   2256                 if (!Subtable)
   2257                 {
   2258                     break;
   2259                 }
   2260                 DtInsertSubtable (ParentTable, Subtable);
   2261                 HmatStruct->Length += Subtable->Length;
   2262                 IntPDNumber++;
   2263             }
   2264             HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
   2265 
   2266             /* Compile target proximity domain list */
   2267 
   2268             TgtPDNumber = 0;
   2269             while (*PFieldList)
   2270             {
   2271                 Status = DtCompileTable (PFieldList,
   2272                     AcpiDmTableInfoHmat1b, &Subtable);
   2273                 if (ACPI_FAILURE (Status))
   2274                 {
   2275                     return (Status);
   2276                 }
   2277                 if (!Subtable)
   2278                 {
   2279                     break;
   2280                 }
   2281                 DtInsertSubtable (ParentTable, Subtable);
   2282                 HmatStruct->Length += Subtable->Length;
   2283                 TgtPDNumber++;
   2284             }
   2285             HmatLocality->NumberOfTargetPDs = TgtPDNumber;
   2286 
   2287             /* Save start of the entries for reporting errors */
   2288 
   2289             EntryStart = *PFieldList;
   2290 
   2291             /* Compile latency/bandwidth entries */
   2292 
   2293             EntryNumber = 0;
   2294             while (*PFieldList)
   2295             {
   2296                 Status = DtCompileTable (PFieldList,
   2297                     AcpiDmTableInfoHmat1c, &Subtable);
   2298                 if (ACPI_FAILURE (Status))
   2299                 {
   2300                     return (Status);
   2301                 }
   2302                 if (!Subtable)
   2303                 {
   2304                     break;
   2305                 }
   2306                 DtInsertSubtable (ParentTable, Subtable);
   2307                 HmatStruct->Length += Subtable->Length;
   2308                 EntryNumber++;
   2309             }
   2310 
   2311             /* Validate number of entries */
   2312 
   2313             if (EntryNumber !=
   2314                 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
   2315             {
   2316                 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
   2317                 return (AE_ERROR);
   2318             }
   2319             break;
   2320 
   2321         case ACPI_HMAT_TYPE_CACHE:
   2322 
   2323             /* Compile SMBIOS handles */
   2324 
   2325             HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
   2326                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   2327             SMBIOSHandleNumber = 0;
   2328             while (*PFieldList)
   2329             {
   2330                 Status = DtCompileTable (PFieldList,
   2331                     AcpiDmTableInfoHmat2a, &Subtable);
   2332                 if (ACPI_FAILURE (Status))
   2333                 {
   2334                     return (Status);
   2335                 }
   2336                 if (!Subtable)
   2337                 {
   2338                     break;
   2339                 }
   2340                 DtInsertSubtable (ParentTable, Subtable);
   2341                 HmatStruct->Length += Subtable->Length;
   2342                 SMBIOSHandleNumber++;
   2343             }
   2344             HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
   2345             break;
   2346 
   2347         default:
   2348 
   2349             break;
   2350         }
   2351     }
   2352 
   2353     return (AE_OK);
   2354 }
   2355 
   2356 
   2357 /******************************************************************************
   2358  *
   2359  * FUNCTION:    DtCompileIort
   2360  *
   2361  * PARAMETERS:  List                - Current field list pointer
   2362  *
   2363  * RETURN:      Status
   2364  *
   2365  * DESCRIPTION: Compile IORT.
   2366  *
   2367  *****************************************************************************/
   2368 
   2369 ACPI_STATUS
   2370 DtCompileIort (
   2371     void                    **List)
   2372 {
   2373     ACPI_STATUS             Status;
   2374     DT_SUBTABLE             *Subtable;
   2375     DT_SUBTABLE             *ParentTable;
   2376     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2377     DT_FIELD                *SubtableStart;
   2378     ACPI_TABLE_HEADER       *Table;
   2379     ACPI_TABLE_IORT         *Iort;
   2380     ACPI_IORT_NODE          *IortNode;
   2381     ACPI_IORT_ITS_GROUP     *IortItsGroup;
   2382     ACPI_IORT_SMMU          *IortSmmu;
   2383     ACPI_IORT_RMR           *IortRmr;
   2384     UINT32                  NodeNumber;
   2385     UINT32                  NodeLength;
   2386     UINT32                  IdMappingNumber;
   2387     UINT32                  ItsNumber;
   2388     UINT32                  ContextIrptNumber;
   2389     UINT32                  PmuIrptNumber;
   2390     UINT32                  PaddingLength;
   2391     UINT8                   Revision;
   2392     UINT32                  RmrCount;
   2393 
   2394 
   2395     ParentTable = DtPeekSubtable ();
   2396 
   2397     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
   2398         &Subtable);
   2399     if (ACPI_FAILURE (Status))
   2400     {
   2401         return (Status);
   2402     }
   2403     DtInsertSubtable (ParentTable, Subtable);
   2404 
   2405     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   2406     Revision = Table->Revision;
   2407 
   2408     /* IORT Revisions E, E.a & E.c have known issues and are not supported */
   2409 
   2410     if (Revision == 1 || Revision == 2 || Revision == 4)
   2411     {
   2412         DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision");
   2413         return (AE_ERROR);
   2414     }
   2415 
   2416     /*
   2417      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   2418      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
   2419      */
   2420     Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
   2421         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
   2422 
   2423     /*
   2424      * OptionalPadding - Variable-length data
   2425      * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
   2426      * Optionally allows the generic data types to be used for filling
   2427      * this field.
   2428      */
   2429     Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
   2430     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
   2431         &Subtable);
   2432     if (ACPI_FAILURE (Status))
   2433     {
   2434         return (Status);
   2435     }
   2436     if (Subtable)
   2437     {
   2438         DtInsertSubtable (ParentTable, Subtable);
   2439         Iort->NodeOffset += Subtable->Length;
   2440     }
   2441     else
   2442     {
   2443         Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
   2444             AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
   2445         if (ACPI_FAILURE (Status))
   2446         {
   2447             return (Status);
   2448         }
   2449         Iort->NodeOffset += PaddingLength;
   2450     }
   2451 
   2452     NodeNumber = 0;
   2453     while (*PFieldList)
   2454     {
   2455         SubtableStart = *PFieldList;
   2456         if (Revision == 0)
   2457         {
   2458             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
   2459                 &Subtable);
   2460         }
   2461         else if (Revision >= 3)
   2462         {
   2463             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3,
   2464                 &Subtable);
   2465         }
   2466 
   2467         if (ACPI_FAILURE (Status))
   2468         {
   2469             return (Status);
   2470         }
   2471 
   2472         DtInsertSubtable (ParentTable, Subtable);
   2473         IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
   2474         NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
   2475 
   2476         DtPushSubtable (Subtable);
   2477         ParentTable = DtPeekSubtable ();
   2478 
   2479         switch (IortNode->Type)
   2480         {
   2481         case ACPI_IORT_NODE_ITS_GROUP:
   2482 
   2483             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
   2484                 &Subtable);
   2485             if (ACPI_FAILURE (Status))
   2486             {
   2487                 return (Status);
   2488             }
   2489 
   2490             DtInsertSubtable (ParentTable, Subtable);
   2491             IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
   2492             NodeLength += Subtable->Length;
   2493 
   2494             ItsNumber = 0;
   2495             while (*PFieldList)
   2496             {
   2497                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
   2498                     &Subtable);
   2499                 if (ACPI_FAILURE (Status))
   2500                 {
   2501                     return (Status);
   2502                 }
   2503                 if (!Subtable)
   2504                 {
   2505                     break;
   2506                 }
   2507 
   2508                 DtInsertSubtable (ParentTable, Subtable);
   2509                 NodeLength += Subtable->Length;
   2510                 ItsNumber++;
   2511             }
   2512 
   2513             IortItsGroup->ItsCount = ItsNumber;
   2514             break;
   2515 
   2516         case ACPI_IORT_NODE_NAMED_COMPONENT:
   2517 
   2518             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
   2519                 &Subtable);
   2520             if (ACPI_FAILURE (Status))
   2521             {
   2522                 return (Status);
   2523             }
   2524 
   2525             DtInsertSubtable (ParentTable, Subtable);
   2526             NodeLength += Subtable->Length;
   2527 
   2528             /*
   2529              * Padding - Variable-length data
   2530              * Optionally allows the offset of the ID mappings to be used
   2531              * for filling this field.
   2532              */
   2533             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
   2534                 &Subtable);
   2535             if (ACPI_FAILURE (Status))
   2536             {
   2537                 return (Status);
   2538             }
   2539 
   2540             if (Subtable)
   2541             {
   2542                 DtInsertSubtable (ParentTable, Subtable);
   2543                 NodeLength += Subtable->Length;
   2544             }
   2545             else
   2546             {
   2547                 if (NodeLength > IortNode->MappingOffset)
   2548                 {
   2549                     return (AE_BAD_DATA);
   2550                 }
   2551 
   2552                 if (NodeLength < IortNode->MappingOffset)
   2553                 {
   2554                     Status = DtCompilePadding (
   2555                         IortNode->MappingOffset - NodeLength,
   2556                         &Subtable);
   2557                     if (ACPI_FAILURE (Status))
   2558                     {
   2559                         return (Status);
   2560                     }
   2561 
   2562                     DtInsertSubtable (ParentTable, Subtable);
   2563                     NodeLength = IortNode->MappingOffset;
   2564                 }
   2565             }
   2566             break;
   2567 
   2568         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
   2569 
   2570             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
   2571                 &Subtable);
   2572             if (ACPI_FAILURE (Status))
   2573             {
   2574                 return (Status);
   2575             }
   2576 
   2577             DtInsertSubtable (ParentTable, Subtable);
   2578             NodeLength += Subtable->Length;
   2579             break;
   2580 
   2581         case ACPI_IORT_NODE_SMMU:
   2582 
   2583             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
   2584                 &Subtable);
   2585             if (ACPI_FAILURE (Status))
   2586             {
   2587                 return (Status);
   2588             }
   2589 
   2590             DtInsertSubtable (ParentTable, Subtable);
   2591             IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
   2592             NodeLength += Subtable->Length;
   2593 
   2594             /* Compile global interrupt array */
   2595 
   2596             IortSmmu->GlobalInterruptOffset = NodeLength;
   2597             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
   2598                 &Subtable);
   2599             if (ACPI_FAILURE (Status))
   2600             {
   2601                 return (Status);
   2602             }
   2603 
   2604             DtInsertSubtable (ParentTable, Subtable);
   2605             NodeLength += Subtable->Length;
   2606 
   2607             /* Compile context interrupt array */
   2608 
   2609             ContextIrptNumber = 0;
   2610             IortSmmu->ContextInterruptOffset = NodeLength;
   2611             while (*PFieldList)
   2612             {
   2613                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
   2614                     &Subtable);
   2615                 if (ACPI_FAILURE (Status))
   2616                 {
   2617                     return (Status);
   2618                 }
   2619 
   2620                 if (!Subtable)
   2621                 {
   2622                     break;
   2623                 }
   2624 
   2625                 DtInsertSubtable (ParentTable, Subtable);
   2626                 NodeLength += Subtable->Length;
   2627                 ContextIrptNumber++;
   2628             }
   2629 
   2630             IortSmmu->ContextInterruptCount = ContextIrptNumber;
   2631 
   2632             /* Compile PMU interrupt array */
   2633 
   2634             PmuIrptNumber = 0;
   2635             IortSmmu->PmuInterruptOffset = NodeLength;
   2636             while (*PFieldList)
   2637             {
   2638                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
   2639                     &Subtable);
   2640                 if (ACPI_FAILURE (Status))
   2641                 {
   2642                     return (Status);
   2643                 }
   2644 
   2645                 if (!Subtable)
   2646                 {
   2647                     break;
   2648                 }
   2649 
   2650                 DtInsertSubtable (ParentTable, Subtable);
   2651                 NodeLength += Subtable->Length;
   2652                 PmuIrptNumber++;
   2653             }
   2654 
   2655             IortSmmu->PmuInterruptCount = PmuIrptNumber;
   2656             break;
   2657 
   2658         case ACPI_IORT_NODE_SMMU_V3:
   2659 
   2660             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
   2661                 &Subtable);
   2662             if (ACPI_FAILURE (Status))
   2663             {
   2664                 return (Status);
   2665             }
   2666 
   2667             DtInsertSubtable (ParentTable, Subtable);
   2668             NodeLength += Subtable->Length;
   2669             break;
   2670 
   2671         case ACPI_IORT_NODE_PMCG:
   2672 
   2673             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
   2674                 &Subtable);
   2675             if (ACPI_FAILURE (Status))
   2676             {
   2677                 return (Status);
   2678             }
   2679 
   2680             DtInsertSubtable (ParentTable, Subtable);
   2681             NodeLength += Subtable->Length;
   2682             break;
   2683 
   2684         case ACPI_IORT_NODE_RMR:
   2685 
   2686             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6,
   2687                 &Subtable);
   2688             if (ACPI_FAILURE (Status))
   2689             {
   2690                 return (Status);
   2691             }
   2692 
   2693             DtInsertSubtable (ParentTable, Subtable);
   2694             IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer);
   2695             NodeLength += Subtable->Length;
   2696 
   2697             /* Compile RMR Descriptors */
   2698 
   2699             RmrCount = 0;
   2700             IortRmr->RmrOffset = NodeLength;
   2701             while (*PFieldList)
   2702             {
   2703                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a,
   2704                     &Subtable);
   2705                 if (ACPI_FAILURE (Status))
   2706                 {
   2707                     return (Status);
   2708                 }
   2709 
   2710                 if (!Subtable)
   2711                 {
   2712                     break;
   2713                 }
   2714 
   2715                 DtInsertSubtable (ParentTable, Subtable);
   2716                 NodeLength += sizeof (ACPI_IORT_RMR_DESC);
   2717                 RmrCount++;
   2718             }
   2719 
   2720             IortRmr->RmrCount = RmrCount;
   2721             break;
   2722 
   2723         default:
   2724 
   2725             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
   2726             return (AE_ERROR);
   2727         }
   2728 
   2729         /* Compile Array of ID mappings */
   2730 
   2731         IortNode->MappingOffset = NodeLength;
   2732         IdMappingNumber = 0;
   2733         while (*PFieldList)
   2734         {
   2735             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
   2736                 &Subtable);
   2737             if (ACPI_FAILURE (Status))
   2738             {
   2739                 return (Status);
   2740             }
   2741 
   2742             if (!Subtable)
   2743             {
   2744                 break;
   2745             }
   2746 
   2747             DtInsertSubtable (ParentTable, Subtable);
   2748             NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
   2749             IdMappingNumber++;
   2750         }
   2751 
   2752         IortNode->MappingCount = IdMappingNumber;
   2753         if (!IdMappingNumber)
   2754         {
   2755             IortNode->MappingOffset = 0;
   2756         }
   2757 
   2758         /*
   2759          * Node length can be determined by DT_LENGTH option
   2760          * IortNode->Length = NodeLength;
   2761          */
   2762         DtPopSubtable ();
   2763         ParentTable = DtPeekSubtable ();
   2764         NodeNumber++;
   2765     }
   2766 
   2767     Iort->NodeCount = NodeNumber;
   2768     return (AE_OK);
   2769 }
   2770 
   2771 
   2772 /******************************************************************************
   2773  *
   2774  * FUNCTION:    DtCompileIvrs
   2775  *
   2776  * PARAMETERS:  List                - Current field list pointer
   2777  *
   2778  * RETURN:      Status
   2779  *
   2780  * DESCRIPTION: Compile IVRS. Notes:
   2781  *              The IVRS is essentially a flat table, with the following
   2782  *              structure:
   2783  *              <Main ACPI Table Header>
   2784  *              <Main subtable - virtualization info>
   2785  *              <IVHD>
   2786  *                  <Device Entries>
   2787  *              ...
   2788  *              <IVHD>
   2789  *                  <Device Entries>
   2790  *              <IVMD>
   2791  *              ...
   2792  *
   2793  *****************************************************************************/
   2794 
   2795 ACPI_STATUS
   2796 DtCompileIvrs (
   2797     void                    **List)
   2798 {
   2799     ACPI_STATUS             Status;
   2800     DT_SUBTABLE             *Subtable;
   2801     DT_SUBTABLE             *ParentTable;
   2802     DT_SUBTABLE             *MainSubtable;
   2803     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2804     DT_FIELD                *SubtableStart;
   2805     ACPI_DMTABLE_INFO       *InfoTable = NULL;
   2806     UINT8                   SubtableType;
   2807     UINT8                   Temp64[16];
   2808     UINT8                   Temp8;
   2809 
   2810 
   2811     /* Main table */
   2812 
   2813     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
   2814         &Subtable);
   2815     if (ACPI_FAILURE (Status))
   2816     {
   2817         return (Status);
   2818     }
   2819 
   2820     ParentTable = DtPeekSubtable ();
   2821     DtInsertSubtable (ParentTable, Subtable);
   2822     DtPushSubtable (Subtable);
   2823 
   2824     /* Save a pointer to the main subtable */
   2825 
   2826     MainSubtable = Subtable;
   2827 
   2828     while (*PFieldList)
   2829     {
   2830         SubtableStart = *PFieldList;
   2831 
   2832         /* Compile the SubtableType integer */
   2833 
   2834         DtCompileInteger (&SubtableType, *PFieldList, 1, 0);
   2835 
   2836         switch (SubtableType)
   2837         {
   2838 
   2839         /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */
   2840 
   2841         case ACPI_IVRS_TYPE_HARDWARE1:
   2842 
   2843             InfoTable = AcpiDmTableInfoIvrsHware1;
   2844             break;
   2845 
   2846         /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */
   2847 
   2848         case ACPI_IVRS_TYPE_HARDWARE2:
   2849         case ACPI_IVRS_TYPE_HARDWARE3:
   2850 
   2851             InfoTable = AcpiDmTableInfoIvrsHware23;
   2852             break;
   2853 
   2854         /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */
   2855 
   2856         case ACPI_IVRS_TYPE_MEMORY1:
   2857         case ACPI_IVRS_TYPE_MEMORY2:
   2858         case ACPI_IVRS_TYPE_MEMORY3:
   2859 
   2860             InfoTable = AcpiDmTableInfoIvrsMemory;
   2861             break;
   2862 
   2863         /* 4-byte device entries */
   2864 
   2865         case ACPI_IVRS_TYPE_PAD4:
   2866         case ACPI_IVRS_TYPE_ALL:
   2867         case ACPI_IVRS_TYPE_SELECT:
   2868         case ACPI_IVRS_TYPE_START:
   2869         case ACPI_IVRS_TYPE_END:
   2870 
   2871             InfoTable = AcpiDmTableInfoIvrs4;
   2872             break;
   2873 
   2874         /* 8-byte device entries, type A */
   2875 
   2876         case ACPI_IVRS_TYPE_ALIAS_SELECT:
   2877         case ACPI_IVRS_TYPE_ALIAS_START:
   2878 
   2879             InfoTable = AcpiDmTableInfoIvrs8a;
   2880             break;
   2881 
   2882         /* 8-byte device entries, type B */
   2883 
   2884         case ACPI_IVRS_TYPE_EXT_SELECT:
   2885         case ACPI_IVRS_TYPE_EXT_START:
   2886 
   2887             InfoTable = AcpiDmTableInfoIvrs8b;
   2888             break;
   2889 
   2890         /* 8-byte device entries, type C */
   2891 
   2892         case ACPI_IVRS_TYPE_SPECIAL:
   2893 
   2894             InfoTable = AcpiDmTableInfoIvrs8c;
   2895             break;
   2896 
   2897         /* Variable device entries, type F0h */
   2898 
   2899         case ACPI_IVRS_TYPE_HID:
   2900 
   2901             InfoTable = AcpiDmTableInfoIvrsHid;
   2902             break;
   2903 
   2904         default:
   2905 
   2906             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
   2907                 "IVRS Device Entry");
   2908             return (AE_ERROR);
   2909         }
   2910 
   2911         /* Compile the InfoTable from above */
   2912 
   2913         Status = DtCompileTable (PFieldList, InfoTable,
   2914             &Subtable);
   2915         if (ACPI_FAILURE (Status))
   2916         {
   2917             return (Status);
   2918         }
   2919 
   2920         ParentTable = DtPeekSubtable ();
   2921         if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 &&
   2922             SubtableType != ACPI_IVRS_TYPE_HARDWARE2 &&
   2923             SubtableType != ACPI_IVRS_TYPE_HARDWARE3 &&
   2924             SubtableType != ACPI_IVRS_TYPE_HID &&
   2925             SubtableType != ACPI_IVRS_TYPE_MEMORY1 &&
   2926             SubtableType != ACPI_IVRS_TYPE_MEMORY2 &&
   2927             SubtableType != ACPI_IVRS_TYPE_MEMORY3)
   2928         {
   2929             if (ParentTable)
   2930                 DtInsertSubtable (ParentTable, Subtable);
   2931         }
   2932 
   2933         switch (SubtableType)
   2934         {
   2935         case ACPI_IVRS_TYPE_HARDWARE1:
   2936         case ACPI_IVRS_TYPE_HARDWARE2:
   2937         case ACPI_IVRS_TYPE_HARDWARE3:
   2938         case ACPI_IVRS_TYPE_MEMORY1:
   2939         case ACPI_IVRS_TYPE_MEMORY2:
   2940         case ACPI_IVRS_TYPE_MEMORY3:
   2941 
   2942             /* Insert these IVHDs/IVMDs at the root subtable */
   2943 
   2944             DtInsertSubtable (MainSubtable, Subtable);
   2945             DtPushSubtable (Subtable);
   2946             break;
   2947 
   2948         case ACPI_IVRS_TYPE_HID:
   2949 
   2950             /* Special handling for the HID named device entry (0xF0) */
   2951 
   2952             if (ParentTable)
   2953             {
   2954                 DtInsertSubtable (ParentTable, Subtable);
   2955             }
   2956 
   2957             /*
   2958              * Process the HID value. First, get the HID value as a string.
   2959              */
   2960             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
   2961 
   2962                /*
   2963                 * Determine if the HID is an integer or a string.
   2964                 * An integer is defined to be 32 bits, with the upper 32 bits
   2965                 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit
   2966                 * integer or a character string. If an integer, the lower
   2967                 * 4 bytes of the field contain the integer and the upper
   2968                 * 4 bytes are padded with 0".
   2969                 */
   2970             if (UtIsIdInteger ((UINT8 *) &Temp64))
   2971             {
   2972                 /* Compile the HID value as an integer */
   2973 
   2974                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
   2975 
   2976                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger,
   2977                     &Subtable);
   2978                 if (ACPI_FAILURE (Status))
   2979                 {
   2980                     return (Status);
   2981                 }
   2982             }
   2983             else
   2984             {
   2985                 /* Compile the HID value as a string */
   2986 
   2987                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString,
   2988                     &Subtable);
   2989                 if (ACPI_FAILURE (Status))
   2990                 {
   2991                     return (Status);
   2992                 }
   2993             }
   2994 
   2995             DtInsertSubtable (ParentTable, Subtable);
   2996 
   2997             /*
   2998              * Process the CID value. First, get the CID value as a string.
   2999              */
   3000             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
   3001 
   3002             if (UtIsIdInteger ((UINT8 *) &Temp64))
   3003             {
   3004                 /* Compile the CID value as an integer */
   3005 
   3006                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
   3007 
   3008                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger,
   3009                     &Subtable);
   3010                 if (ACPI_FAILURE (Status))
   3011                 {
   3012                     return (Status);
   3013                 }
   3014             }
   3015             else
   3016             {
   3017                 /* Compile the CID value as a string */
   3018 
   3019                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString,
   3020                     &Subtable);
   3021                 if (ACPI_FAILURE (Status))
   3022                 {
   3023                     return (Status);
   3024                 }
   3025             }
   3026 
   3027             DtInsertSubtable (ParentTable, Subtable);
   3028 
   3029             /*
   3030              * Process the UID value. First, get and decode the "UID Format" field (Integer).
   3031              */
   3032             if (!*PFieldList)
   3033             {
   3034                 return (AE_OK);
   3035             }
   3036 
   3037             DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0);
   3038 
   3039             switch (Temp8)
   3040             {
   3041             case ACPI_IVRS_UID_NOT_PRESENT:
   3042                 break;
   3043 
   3044             case ACPI_IVRS_UID_IS_INTEGER:
   3045 
   3046                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger,
   3047                     &Subtable);
   3048                 if (ACPI_FAILURE (Status))
   3049                 {
   3050                     return (Status);
   3051                 }
   3052                 DtInsertSubtable (ParentTable, Subtable);
   3053                 break;
   3054 
   3055             case ACPI_IVRS_UID_IS_STRING:
   3056 
   3057                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString,
   3058                     &Subtable);
   3059                 if (ACPI_FAILURE (Status))
   3060                 {
   3061                     return (Status);
   3062                 }
   3063                 DtInsertSubtable (ParentTable, Subtable);
   3064                 break;
   3065 
   3066             default:
   3067 
   3068                 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart,
   3069                     "IVRS Device Entry");
   3070                 return (AE_ERROR);
   3071             }
   3072 
   3073         default:
   3074 
   3075             /* All other subtable types come through here */
   3076             break;
   3077         }
   3078     }
   3079 
   3080     return (AE_OK);
   3081 }
   3082