Home | History | Annotate | Line # | Download | only in compiler
dttable1.c revision 1.1.1.15
      1 /******************************************************************************
      2  *
      3  * Module Name: dttable1.c - handling for specific ACPI tables
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2022, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 /* Compile all complex data tables, signatures starting with A-I */
     45 
     46 #include "aslcompiler.h"
     47 
     48 #define _COMPONENT          DT_COMPILER
     49         ACPI_MODULE_NAME    ("dttable1")
     50 
     51 
     52 static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] =
     53 {
     54     {ACPI_DMT_BUFFER,   0,               "Addresses", 0},
     55     {ACPI_DMT_EXIT,     0,               NULL, 0}
     56 };
     57 
     58 static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] =
     59 {
     60     {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0},
     61     {ACPI_DMT_EXIT,     0,               NULL, 0}
     62 };
     63 
     64 
     65 /******************************************************************************
     66  *
     67  * FUNCTION:    DtCompileAest
     68  *
     69  * PARAMETERS:  List                - Current field list pointer
     70  *
     71  * RETURN:      Status
     72  *
     73  * DESCRIPTION: Compile AEST.
     74  *
     75  * NOTE: Assumes the following table structure:
     76  *      For all AEST Error Nodes:
     77  *          1) An AEST Error Node, followed immediately by:
     78  *          2) Any node-specific data
     79  *          3) An Interface Structure (one)
     80  *          4) A list (array) of Interrupt Structures, the count as specified
     81  *              in the NodeInterruptCount field of the Error Node header.
     82  *
     83  * AEST - ARM Error Source table. Conforms to:
     84  * ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document Sep 2020
     85  *
     86  *****************************************************************************/
     87 
     88 ACPI_STATUS
     89 DtCompileAest (
     90     void                    **List)
     91 {
     92     ACPI_AEST_HEADER        *ErrorNodeHeader;
     93     ACPI_AEST_PROCESSOR     *AestProcessor;
     94     DT_SUBTABLE             *Subtable;
     95     DT_SUBTABLE             *ParentTable;
     96     ACPI_DMTABLE_INFO       *InfoTable;
     97     ACPI_STATUS             Status;
     98     UINT32                  i;
     99     UINT32                  Offset;
    100     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    101 
    102 
    103     while (*PFieldList)
    104     {
    105         /* Compile the common error node header */
    106 
    107         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestHdr,
    108             &Subtable);
    109         if (ACPI_FAILURE (Status))
    110         {
    111             return (Status);
    112         }
    113 
    114         ParentTable = DtPeekSubtable ();
    115         DtInsertSubtable (ParentTable, Subtable);
    116 
    117         /* Everything past the error node header will be a subtable */
    118 
    119         DtPushSubtable (Subtable);
    120 
    121         /*
    122          * Compile the node-specific structure (Based on the error
    123          * node header Type field)
    124          */
    125         ErrorNodeHeader = ACPI_CAST_PTR (ACPI_AEST_HEADER, Subtable->Buffer);
    126 
    127         /* Point past the common error node header */
    128 
    129         Offset = sizeof (ACPI_AEST_HEADER);
    130         ErrorNodeHeader->NodeSpecificOffset = Offset;
    131 
    132         /* Decode the error node type */
    133 
    134         switch (ErrorNodeHeader->Type)
    135         {
    136         case ACPI_AEST_PROCESSOR_ERROR_NODE:
    137 
    138             InfoTable = AcpiDmTableInfoAestProcError;
    139             break;
    140 
    141         case ACPI_AEST_MEMORY_ERROR_NODE:
    142 
    143             InfoTable = AcpiDmTableInfoAestMemError;
    144             break;
    145 
    146         case ACPI_AEST_SMMU_ERROR_NODE:
    147 
    148             InfoTable = AcpiDmTableInfoAestSmmuError;
    149             break;
    150 
    151         case ACPI_AEST_VENDOR_ERROR_NODE:
    152 
    153             InfoTable = AcpiDmTableInfoAestVendorError;
    154             break;
    155 
    156         case ACPI_AEST_GIC_ERROR_NODE:
    157 
    158             InfoTable = AcpiDmTableInfoAestGicError;
    159             break;
    160 
    161         /* Error case below */
    162         default:
    163             AcpiOsPrintf ("Unknown AEST Subtable Type: %X\n",
    164                 ErrorNodeHeader->Type);
    165             return (AE_ERROR);
    166         }
    167 
    168         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    169         if (ACPI_FAILURE (Status))
    170         {
    171             return (Status);
    172         }
    173 
    174         /* Point past the node-specific structure */
    175 
    176         Offset += Subtable->Length;
    177         ErrorNodeHeader->NodeInterfaceOffset = Offset;
    178 
    179         ParentTable = DtPeekSubtable ();
    180         DtInsertSubtable (ParentTable, Subtable);
    181 
    182         /* Compile any additional node-specific substructures */
    183 
    184         if (ErrorNodeHeader->Type == ACPI_AEST_PROCESSOR_ERROR_NODE)
    185         {
    186             /*
    187              * Special handling for PROCESSOR_ERROR_NODE subtables
    188              * (to handle the Resource Substructure via the ResourceType
    189              * field).
    190              */
    191             AestProcessor = ACPI_CAST_PTR (ACPI_AEST_PROCESSOR,
    192                 Subtable->Buffer);
    193 
    194             switch (AestProcessor->ResourceType)
    195             {
    196             case ACPI_AEST_CACHE_RESOURCE:
    197 
    198                 InfoTable = AcpiDmTableInfoAestCacheRsrc;
    199                 break;
    200 
    201             case ACPI_AEST_TLB_RESOURCE:
    202 
    203                 InfoTable = AcpiDmTableInfoAestTlbRsrc;
    204                 break;
    205 
    206             case ACPI_AEST_GENERIC_RESOURCE:
    207 
    208                 InfoTable = AcpiDmTableInfoAestGenRsrc;
    209                 AcpiOsPrintf ("Generic Resource Type (%X) is not supported at this time\n",
    210                     AestProcessor->ResourceType);
    211                 return (AE_ERROR);
    212 
    213             /* Error case below */
    214             default:
    215                 AcpiOsPrintf ("Unknown AEST Processor Resource Type: %X\n",
    216                     AestProcessor->ResourceType);
    217                 return (AE_ERROR);
    218             }
    219 
    220             Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    221             if (ACPI_FAILURE (Status))
    222             {
    223                 return (Status);
    224             }
    225 
    226             /* Point past the resource substructure subtable */
    227 
    228             Offset += Subtable->Length;
    229             ErrorNodeHeader->NodeInterfaceOffset = Offset;
    230 
    231             ParentTable = DtPeekSubtable ();
    232             DtInsertSubtable (ParentTable, Subtable);
    233         }
    234 
    235         /* Compile the (required) node interface structure */
    236 
    237         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXface,
    238             &Subtable);
    239         if (ACPI_FAILURE (Status))
    240         {
    241             return (Status);
    242         }
    243 
    244         ErrorNodeHeader->NodeInterruptOffset = 0;
    245         ParentTable = DtPeekSubtable ();
    246         DtInsertSubtable (ParentTable, Subtable);
    247 
    248         /* Compile each of the node interrupt structures */
    249 
    250         if (ErrorNodeHeader->NodeInterruptCount)
    251         {
    252             /* Point to the first interrupt structure */
    253 
    254             Offset += Subtable->Length;
    255             ErrorNodeHeader->NodeInterruptOffset = Offset;
    256         }
    257 
    258         /* Compile each of the interrupt structures */
    259 
    260         for (i = 0; i < ErrorNodeHeader->NodeInterruptCount; i++)
    261         {
    262             Status = DtCompileTable (PFieldList, AcpiDmTableInfoAestXrupt,
    263                 &Subtable);
    264             if (ACPI_FAILURE (Status))
    265             {
    266                 return (Status);
    267             }
    268 
    269             ParentTable = DtPeekSubtable ();
    270             DtInsertSubtable (ParentTable, Subtable);
    271         }
    272 
    273         /* Prepare for the next AEST Error node */
    274 
    275         DtPopSubtable ();
    276     }
    277 
    278     return (AE_OK);
    279 }
    280 
    281 
    282 /******************************************************************************
    283  *
    284  * FUNCTION:    DtCompileApmt
    285  *
    286  * PARAMETERS:  List                - Current field list pointer
    287  *
    288  * RETURN:      Status
    289  *
    290  * DESCRIPTION: Compile APMT.
    291  *
    292  *****************************************************************************/
    293 
    294 ACPI_STATUS
    295 DtCompileApmt (
    296     void                    **List)
    297 {
    298     ACPI_STATUS             Status;
    299     ACPI_TABLE_HEADER       *Header;
    300     ACPI_APMT_NODE          *ApmtNode;
    301     ACPI_APMT_NODE          *PeerApmtNode;
    302     DT_SUBTABLE             *Subtable;
    303     DT_SUBTABLE             *PeerSubtable;
    304     DT_SUBTABLE             *ParentTable;
    305     DT_FIELD                **PFieldList = (DT_FIELD**)List;
    306     DT_FIELD                *SubtableStart;
    307     UINT32                  CurLength;
    308     char                    MsgBuffer[64] = "";
    309 
    310     ParentTable = DtPeekSubtable();
    311 
    312     Header = ACPI_CAST_PTR(ACPI_TABLE_HEADER, ParentTable->Buffer);
    313 
    314     CurLength = sizeof(ACPI_TABLE_HEADER);
    315 
    316     /* Walk the parse tree */
    317 
    318     while (*PFieldList)
    319     {
    320         /* APMT Node Subtable */
    321 
    322         SubtableStart = *PFieldList;
    323 
    324         Status = DtCompileTable(PFieldList, AcpiDmTableInfoApmtNode, &Subtable);
    325 
    326         if (ACPI_FAILURE(Status))
    327         {
    328             return (Status);
    329         }
    330 
    331         ApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, Subtable->Buffer);
    332 
    333         if (ApmtNode->Length != sizeof(ACPI_APMT_NODE))
    334         {
    335             DtFatal(ASL_MSG_INVALID_LENGTH, SubtableStart, "APMT");
    336             return (AE_ERROR);
    337         }
    338 
    339         if (ApmtNode->Type >= ACPI_APMT_NODE_TYPE_COUNT)
    340         {
    341             snprintf(MsgBuffer, 64, "Node Type : 0x%X", ApmtNode->Type);
    342             DtFatal(ASL_MSG_INVALID_TYPE, SubtableStart, MsgBuffer);
    343             return (AE_ERROR);
    344         }
    345 
    346         PeerSubtable = DtGetNextSubtable(ParentTable, NULL);
    347 
    348         /* Validate the node id needs to be unique. */
    349         while(PeerSubtable)
    350         {
    351             PeerApmtNode = ACPI_CAST_PTR(ACPI_APMT_NODE, PeerSubtable->Buffer);
    352             if (PeerApmtNode->Id == ApmtNode->Id)
    353             {
    354                 snprintf(MsgBuffer, 64, "Node Id : 0x%X existed", ApmtNode->Id);
    355                 DtFatal(ASL_MSG_DUPLICATE_ITEM, SubtableStart, MsgBuffer);
    356                 return (AE_ERROR);
    357             }
    358 
    359             PeerSubtable = DtGetNextSubtable(ParentTable, PeerSubtable);
    360         }
    361 
    362         CurLength += ApmtNode->Length;
    363 
    364         DtInsertSubtable(ParentTable, Subtable);
    365     }
    366 
    367     if (Header->Length != CurLength)
    368     {
    369         snprintf(MsgBuffer, 64, " - APMT Length : %u (expected: %u)",
    370             Header->Length, CurLength);
    371         DtFatal(ASL_MSG_INVALID_LENGTH, NULL, MsgBuffer);
    372         return (AE_ERROR);
    373     }
    374 
    375     return (AE_OK);
    376 }
    377 
    378 /******************************************************************************
    379  *
    380  * FUNCTION:    DtCompileAsf
    381  *
    382  * PARAMETERS:  List                - Current field list pointer
    383  *
    384  * RETURN:      Status
    385  *
    386  * DESCRIPTION: Compile ASF!.
    387  *
    388  *****************************************************************************/
    389 
    390 ACPI_STATUS
    391 DtCompileAsf (
    392     void                    **List)
    393 {
    394     ACPI_ASF_INFO           *AsfTable;
    395     DT_SUBTABLE             *Subtable;
    396     DT_SUBTABLE             *ParentTable;
    397     ACPI_DMTABLE_INFO       *InfoTable;
    398     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
    399     UINT32                  DataCount = 0;
    400     ACPI_STATUS             Status;
    401     UINT32                  i;
    402     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    403     DT_FIELD                *SubtableStart;
    404 
    405 
    406     while (*PFieldList)
    407     {
    408         SubtableStart = *PFieldList;
    409         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
    410             &Subtable);
    411         if (ACPI_FAILURE (Status))
    412         {
    413             return (Status);
    414         }
    415 
    416         ParentTable = DtPeekSubtable ();
    417         DtInsertSubtable (ParentTable, Subtable);
    418         DtPushSubtable (Subtable);
    419 
    420         AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
    421 
    422         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
    423         {
    424         case ACPI_ASF_TYPE_INFO:
    425 
    426             InfoTable = AcpiDmTableInfoAsf0;
    427             break;
    428 
    429         case ACPI_ASF_TYPE_ALERT:
    430 
    431             InfoTable = AcpiDmTableInfoAsf1;
    432             break;
    433 
    434         case ACPI_ASF_TYPE_CONTROL:
    435 
    436             InfoTable = AcpiDmTableInfoAsf2;
    437             break;
    438 
    439         case ACPI_ASF_TYPE_BOOT:
    440 
    441             InfoTable = AcpiDmTableInfoAsf3;
    442             break;
    443 
    444         case ACPI_ASF_TYPE_ADDRESS:
    445 
    446             InfoTable = AcpiDmTableInfoAsf4;
    447             break;
    448 
    449         default:
    450 
    451             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
    452             return (AE_ERROR);
    453         }
    454 
    455         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    456         if (ACPI_FAILURE (Status))
    457         {
    458             return (Status);
    459         }
    460 
    461         ParentTable = DtPeekSubtable ();
    462         DtInsertSubtable (ParentTable, Subtable);
    463 
    464         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
    465         {
    466         case ACPI_ASF_TYPE_INFO:
    467 
    468             DataInfoTable = NULL;
    469             break;
    470 
    471         case ACPI_ASF_TYPE_ALERT:
    472 
    473             DataInfoTable = AcpiDmTableInfoAsf1a;
    474             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
    475                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
    476                     sizeof (ACPI_ASF_HEADER)))->Alerts;
    477             break;
    478 
    479         case ACPI_ASF_TYPE_CONTROL:
    480 
    481             DataInfoTable = AcpiDmTableInfoAsf2a;
    482             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
    483                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
    484                     sizeof (ACPI_ASF_HEADER)))->Controls;
    485             break;
    486 
    487         case ACPI_ASF_TYPE_BOOT:
    488 
    489             DataInfoTable = NULL;
    490             break;
    491 
    492         case ACPI_ASF_TYPE_ADDRESS:
    493 
    494             DataInfoTable = TableInfoAsfAddress;
    495             DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
    496                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
    497                     sizeof (ACPI_ASF_HEADER)))->Devices;
    498             break;
    499 
    500         default:
    501 
    502             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
    503             return (AE_ERROR);
    504         }
    505 
    506         if (DataInfoTable)
    507         {
    508             switch (AsfTable->Header.Type & 0x7F)
    509             {
    510             case ACPI_ASF_TYPE_ADDRESS:
    511 
    512                 while (DataCount > 0)
    513                 {
    514                     Status = DtCompileTable (PFieldList, DataInfoTable,
    515                         &Subtable);
    516                     if (ACPI_FAILURE (Status))
    517                     {
    518                         return (Status);
    519                     }
    520 
    521                     DtInsertSubtable (ParentTable, Subtable);
    522                     DataCount = DataCount - Subtable->Length;
    523                 }
    524                 break;
    525 
    526             default:
    527 
    528                 for (i = 0; i < DataCount; i++)
    529                 {
    530                     Status = DtCompileTable (PFieldList, DataInfoTable,
    531                         &Subtable);
    532                     if (ACPI_FAILURE (Status))
    533                     {
    534                         return (Status);
    535                     }
    536 
    537                     DtInsertSubtable (ParentTable, Subtable);
    538                 }
    539                 break;
    540             }
    541         }
    542 
    543         DtPopSubtable ();
    544     }
    545 
    546     return (AE_OK);
    547 }
    548 
    549 
    550 /******************************************************************************
    551  *
    552  * FUNCTION:    DtCompileCdat
    553  *
    554  * PARAMETERS:  List                - Current field list pointer
    555  *
    556  * RETURN:      Status
    557  *
    558  * DESCRIPTION: Compile CDAT.
    559  *
    560  *****************************************************************************/
    561 
    562 ACPI_STATUS
    563 DtCompileCdat (
    564     void                    **List)
    565 {
    566     ACPI_STATUS             Status = AE_OK;
    567     DT_SUBTABLE             *Subtable;
    568     DT_SUBTABLE             *ParentTable;
    569     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    570     ACPI_CDAT_HEADER        *CdatHeader;
    571     ACPI_DMTABLE_INFO       *InfoTable = NULL;
    572     DT_FIELD                *SubtableStart;
    573 
    574 
    575     /* Walk the parse tree.
    576      *
    577      * Note: Main table consists of only the CDAT table header
    578      * (This is not the standard ACPI table header, however)--
    579      * Followed by some number of subtables.
    580      */
    581     while (*PFieldList)
    582     {
    583         SubtableStart = *PFieldList;
    584 
    585         /* Compile the expected CDAT Subtable header */
    586 
    587         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatHeader,
    588             &Subtable);
    589         if (ACPI_FAILURE (Status))
    590         {
    591             return (Status);
    592         }
    593 
    594         ParentTable = DtPeekSubtable ();
    595         DtInsertSubtable (ParentTable, Subtable);
    596         DtPushSubtable (Subtable);
    597 
    598         CdatHeader = ACPI_CAST_PTR (ACPI_CDAT_HEADER, Subtable->Buffer);
    599 
    600         /* Decode the subtable by type */
    601 
    602         switch (CdatHeader->Type)
    603         {
    604         case ACPI_CDAT_TYPE_DSMAS:
    605             InfoTable = AcpiDmTableInfoCdat0;
    606             break;
    607 
    608         case ACPI_CDAT_TYPE_DSLBIS:
    609             InfoTable = AcpiDmTableInfoCdat1;
    610             break;
    611 
    612         case ACPI_CDAT_TYPE_DSMSCIS:
    613             InfoTable = AcpiDmTableInfoCdat2;
    614             break;
    615 
    616         case ACPI_CDAT_TYPE_DSIS:
    617             InfoTable = AcpiDmTableInfoCdat3;
    618             break;
    619 
    620         case ACPI_CDAT_TYPE_DSEMTS:
    621             InfoTable = AcpiDmTableInfoCdat4;
    622             break;
    623 
    624         case ACPI_CDAT_TYPE_SSLBIS:
    625             InfoTable = AcpiDmTableInfoCdat5;
    626             break;
    627 
    628         default:
    629             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CDAT");
    630         }
    631 
    632         /* Compile the CDAT subtable */
    633 
    634         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    635         if (ACPI_FAILURE (Status))
    636         {
    637             return (Status);
    638         }
    639 
    640         ParentTable = DtPeekSubtable ();
    641         DtInsertSubtable (ParentTable, Subtable);
    642 
    643         switch (CdatHeader->Type)
    644         {
    645         /* Multiple entries supported for this type */
    646 
    647         case ACPI_CDAT_TYPE_SSLBIS:
    648 
    649             /*
    650              * Check for multiple SSLBEs
    651              */
    652             while (*PFieldList && !AcpiUtStricmp ((*PFieldList)->Name, "Port X ID"))
    653             {
    654                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatEntries, &Subtable);
    655                 if (ACPI_FAILURE (Status))
    656                 {
    657                     return (Status);
    658                 }
    659                 ParentTable = DtPeekSubtable ();
    660                 DtInsertSubtable (ParentTable, Subtable);
    661             }
    662             break;
    663 
    664         default:
    665              break;
    666         }
    667 
    668         /* Pop off the CDAT Subtable header subtree */
    669 
    670         DtPopSubtable ();
    671     }
    672 
    673     return (AE_OK);
    674 }
    675 
    676 
    677 /******************************************************************************
    678  *
    679  * FUNCTION:    DtCompileCedt
    680  *
    681  * PARAMETERS:  List                - Current field list pointer
    682  *
    683  * RETURN:      Status
    684  *
    685  * DESCRIPTION: Compile CEDT.
    686  *
    687  *****************************************************************************/
    688 
    689 ACPI_STATUS
    690 DtCompileCedt (
    691     void                    **List)
    692 {
    693     ACPI_STATUS             Status;
    694     DT_SUBTABLE             *Subtable;
    695     DT_SUBTABLE             *ParentTable;
    696     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    697     ACPI_CEDT_HEADER        *CedtHeader;
    698     DT_FIELD                *SubtableStart;
    699 
    700 
    701     /* Walk the parse tree */
    702 
    703     while (*PFieldList)
    704     {
    705         /* if CFMWS and has more than one target, then set to zero later */
    706 
    707         int InsertFlag = 1;
    708         SubtableStart = *PFieldList;
    709 
    710         /* CEDT Header */
    711 
    712         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr,
    713             &Subtable);
    714         if (ACPI_FAILURE (Status))
    715         {
    716             return (Status);
    717         }
    718 
    719         ParentTable = DtPeekSubtable ();
    720         DtInsertSubtable (ParentTable, Subtable);
    721         DtPushSubtable (Subtable);
    722 
    723         CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer);
    724 
    725         switch (CedtHeader->Type)
    726         {
    727         case ACPI_CEDT_TYPE_CHBS:
    728             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable);
    729             if (ACPI_FAILURE (Status))
    730             {
    731                 return (Status);
    732             }
    733             break;
    734         case ACPI_CEDT_TYPE_CFMWS: {
    735             unsigned char *dump;
    736             unsigned int idx, offset, max = 0;
    737 
    738             /* Compile table with first "Interleave target" */
    739 
    740             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1, &Subtable);
    741             if (ACPI_FAILURE (Status))
    742             {
    743                 return (Status);
    744             }
    745 
    746             /* Look in buffer for the number of targets */
    747             offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CFMWS, InterleaveWays);
    748             dump = (unsigned char *) Subtable->Buffer - 4;     /* place at beginning of cedt1 */
    749             max = 0x01 << dump[offset];     /* 2^max, so 0=1, 1=2, 2=4, 3=8.  8 is MAX */
    750             if (max > 8)    max=1;          /* Error in encoding Interleaving Ways. */
    751             if (max == 1)                   /* if only one target, then break here. */
    752                 break;                      /* break if only one target. */
    753 
    754             /* We need to add more interleave targets, so write the current Subtable. */
    755 
    756             ParentTable = DtPeekSubtable ();
    757             DtInsertSubtable (ParentTable, Subtable);   /* Insert AcpiDmTableInfoCedt1 table so we can put in */
    758             DtPushSubtable (Subtable);                  /* the targets > the first. */
    759 
    760             /* Now, find out all interleave targets beyond the first. */
    761 
    762             for (idx = 1; idx < max; idx++) {
    763                 ParentTable = DtPeekSubtable ();
    764 
    765                 if (*PFieldList)
    766                 {
    767                     Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1_te, &Subtable);
    768                     if (ACPI_FAILURE (Status))
    769                     {
    770                         return (Status);
    771                     }
    772                     if (Subtable)
    773                     {
    774                         DtInsertSubtable (ParentTable, Subtable);       /* got a target, so insert table. */
    775                         InsertFlag = 0;
    776                     }
    777                 }
    778             }
    779 
    780             DtPopSubtable ();
    781             ParentTable = DtPeekSubtable ();
    782             break;
    783         }
    784 
    785         default:
    786             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT");
    787             return (AE_ERROR);
    788         }
    789 
    790         ParentTable = DtPeekSubtable ();
    791         if (InsertFlag == 1) {
    792                 DtInsertSubtable (ParentTable, Subtable);
    793         }
    794         DtPopSubtable ();
    795     }
    796 
    797     return (AE_OK);
    798 }
    799 
    800 
    801 /******************************************************************************
    802  *
    803  * FUNCTION:    DtCompileCpep
    804  *
    805  * PARAMETERS:  List                - Current field list pointer
    806  *
    807  * RETURN:      Status
    808  *
    809  * DESCRIPTION: Compile CPEP.
    810  *
    811  *****************************************************************************/
    812 
    813 ACPI_STATUS
    814 DtCompileCpep (
    815     void                    **List)
    816 {
    817     ACPI_STATUS             Status;
    818 
    819 
    820     Status = DtCompileTwoSubtables (List,
    821         AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
    822     return (Status);
    823 }
    824 
    825 
    826 /******************************************************************************
    827  *
    828  * FUNCTION:    DtCompileCsrt
    829  *
    830  * PARAMETERS:  List                - Current field list pointer
    831  *
    832  * RETURN:      Status
    833  *
    834  * DESCRIPTION: Compile CSRT.
    835  *
    836  *****************************************************************************/
    837 
    838 ACPI_STATUS
    839 DtCompileCsrt (
    840     void                    **List)
    841 {
    842     ACPI_STATUS             Status = AE_OK;
    843     DT_SUBTABLE             *Subtable;
    844     DT_SUBTABLE             *ParentTable;
    845     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    846     UINT32                  DescriptorCount;
    847     UINT32                  GroupLength;
    848 
    849 
    850     /* Subtables (Resource Groups) */
    851 
    852     ParentTable = DtPeekSubtable ();
    853     while (*PFieldList)
    854     {
    855         /* Resource group subtable */
    856 
    857         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
    858             &Subtable);
    859         if (ACPI_FAILURE (Status))
    860         {
    861             return (Status);
    862         }
    863 
    864         /* Compute the number of resource descriptors */
    865 
    866         GroupLength =
    867             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
    868                 Subtable->Buffer))->Length -
    869             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
    870                 Subtable->Buffer))->SharedInfoLength -
    871             sizeof (ACPI_CSRT_GROUP);
    872 
    873         DescriptorCount = (GroupLength  /
    874             sizeof (ACPI_CSRT_DESCRIPTOR));
    875 
    876         DtInsertSubtable (ParentTable, Subtable);
    877         DtPushSubtable (Subtable);
    878         ParentTable = DtPeekSubtable ();
    879 
    880         /* Shared info subtable (One per resource group) */
    881 
    882         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
    883             &Subtable);
    884         if (ACPI_FAILURE (Status))
    885         {
    886             return (Status);
    887         }
    888 
    889         DtInsertSubtable (ParentTable, Subtable);
    890 
    891         /* Sub-Subtables (Resource Descriptors) */
    892 
    893         while (*PFieldList && DescriptorCount)
    894         {
    895 
    896             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
    897                 &Subtable);
    898             if (ACPI_FAILURE (Status))
    899             {
    900                 return (Status);
    901             }
    902 
    903             DtInsertSubtable (ParentTable, Subtable);
    904 
    905             DtPushSubtable (Subtable);
    906             ParentTable = DtPeekSubtable ();
    907             if (*PFieldList)
    908             {
    909                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
    910                     &Subtable);
    911                 if (ACPI_FAILURE (Status))
    912                 {
    913                     return (Status);
    914                 }
    915                 if (Subtable)
    916                 {
    917                     DtInsertSubtable (ParentTable, Subtable);
    918                 }
    919             }
    920 
    921             DtPopSubtable ();
    922             ParentTable = DtPeekSubtable ();
    923             DescriptorCount--;
    924         }
    925 
    926         DtPopSubtable ();
    927         ParentTable = DtPeekSubtable ();
    928     }
    929 
    930     return (Status);
    931 }
    932 
    933 
    934 /******************************************************************************
    935  *
    936  * FUNCTION:    DtCompileDbg2
    937  *
    938  * PARAMETERS:  List                - Current field list pointer
    939  *
    940  * RETURN:      Status
    941  *
    942  * DESCRIPTION: Compile DBG2.
    943  *
    944  *****************************************************************************/
    945 
    946 ACPI_STATUS
    947 DtCompileDbg2 (
    948     void                    **List)
    949 {
    950     ACPI_STATUS             Status;
    951     DT_SUBTABLE             *Subtable;
    952     DT_SUBTABLE             *ParentTable;
    953     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    954     UINT32                  SubtableCount;
    955     ACPI_DBG2_HEADER        *Dbg2Header;
    956     ACPI_DBG2_DEVICE        *DeviceInfo;
    957     UINT16                  CurrentOffset;
    958     UINT32                  i;
    959 
    960 
    961     /* Main table */
    962 
    963     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable);
    964     if (ACPI_FAILURE (Status))
    965     {
    966         return (Status);
    967     }
    968 
    969     ParentTable = DtPeekSubtable ();
    970     DtInsertSubtable (ParentTable, Subtable);
    971 
    972     /* Main table fields */
    973 
    974     Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
    975     Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
    976         ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
    977 
    978     SubtableCount = Dbg2Header->InfoCount;
    979     DtPushSubtable (Subtable);
    980 
    981     /* Process all Device Information subtables (Count = InfoCount) */
    982 
    983     while (*PFieldList && SubtableCount)
    984     {
    985         /* Subtable: Debug Device Information */
    986 
    987         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
    988             &Subtable);
    989         if (ACPI_FAILURE (Status))
    990         {
    991             return (Status);
    992         }
    993 
    994         DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
    995         CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
    996 
    997         ParentTable = DtPeekSubtable ();
    998         DtInsertSubtable (ParentTable, Subtable);
    999         DtPushSubtable (Subtable);
   1000 
   1001         ParentTable = DtPeekSubtable ();
   1002 
   1003         /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
   1004 
   1005         DeviceInfo->BaseAddressOffset = CurrentOffset;
   1006         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
   1007         {
   1008             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
   1009                 &Subtable);
   1010             if (ACPI_FAILURE (Status))
   1011             {
   1012                 return (Status);
   1013             }
   1014 
   1015             CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
   1016             DtInsertSubtable (ParentTable, Subtable);
   1017         }
   1018 
   1019         /* AddressSize array (Required, size = RegisterCount) */
   1020 
   1021         DeviceInfo->AddressSizeOffset = CurrentOffset;
   1022         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
   1023         {
   1024             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
   1025                 &Subtable);
   1026             if (ACPI_FAILURE (Status))
   1027             {
   1028                 return (Status);
   1029             }
   1030 
   1031             CurrentOffset += (UINT16) sizeof (UINT32);
   1032             DtInsertSubtable (ParentTable, Subtable);
   1033         }
   1034 
   1035         /* NamespaceString device identifier (Required, size = NamePathLength) */
   1036 
   1037         DeviceInfo->NamepathOffset = CurrentOffset;
   1038         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
   1039             &Subtable);
   1040         if (ACPI_FAILURE (Status))
   1041         {
   1042             return (Status);
   1043         }
   1044 
   1045         /* Update the device info header */
   1046 
   1047         DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
   1048         CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
   1049         DtInsertSubtable (ParentTable, Subtable);
   1050 
   1051         /* OemData - Variable-length data (Optional, size = OemDataLength) */
   1052 
   1053         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
   1054             &Subtable);
   1055         if (Status == AE_END_OF_TABLE)
   1056         {
   1057             /* optional field was not found and we're at the end of the file */
   1058 
   1059             goto subtableDone;
   1060         }
   1061         else if (ACPI_FAILURE (Status))
   1062         {
   1063             return (Status);
   1064         }
   1065 
   1066         /* Update the device info header (zeros if no OEM data present) */
   1067 
   1068         DeviceInfo->OemDataOffset = 0;
   1069         DeviceInfo->OemDataLength = 0;
   1070 
   1071         /* Optional subtable (OemData) */
   1072 
   1073         if (Subtable && Subtable->Length)
   1074         {
   1075             DeviceInfo->OemDataOffset = CurrentOffset;
   1076             DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
   1077 
   1078             DtInsertSubtable (ParentTable, Subtable);
   1079         }
   1080 subtableDone:
   1081         SubtableCount--;
   1082         DtPopSubtable (); /* Get next Device Information subtable */
   1083     }
   1084 
   1085     DtPopSubtable ();
   1086     return (AE_OK);
   1087 }
   1088 
   1089 
   1090 /******************************************************************************
   1091  *
   1092  * FUNCTION:    DtCompileDmar
   1093  *
   1094  * PARAMETERS:  List                - Current field list pointer
   1095  *
   1096  * RETURN:      Status
   1097  *
   1098  * DESCRIPTION: Compile DMAR.
   1099  *
   1100  *****************************************************************************/
   1101 
   1102 ACPI_STATUS
   1103 DtCompileDmar (
   1104     void                    **List)
   1105 {
   1106     ACPI_STATUS             Status;
   1107     DT_SUBTABLE             *Subtable;
   1108     DT_SUBTABLE             *ParentTable;
   1109     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1110     DT_FIELD                *SubtableStart;
   1111     ACPI_DMTABLE_INFO       *InfoTable;
   1112     ACPI_DMAR_HEADER        *DmarHeader;
   1113     ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
   1114     UINT32                  DeviceScopeLength;
   1115     UINT32                  PciPathLength;
   1116 
   1117 
   1118     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable);
   1119     if (ACPI_FAILURE (Status))
   1120     {
   1121         return (Status);
   1122     }
   1123 
   1124     ParentTable = DtPeekSubtable ();
   1125     DtInsertSubtable (ParentTable, Subtable);
   1126     DtPushSubtable (Subtable);
   1127 
   1128     while (*PFieldList)
   1129     {
   1130         /* DMAR Header */
   1131 
   1132         SubtableStart = *PFieldList;
   1133         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
   1134             &Subtable);
   1135         if (ACPI_FAILURE (Status))
   1136         {
   1137             return (Status);
   1138         }
   1139 
   1140         ParentTable = DtPeekSubtable ();
   1141         DtInsertSubtable (ParentTable, Subtable);
   1142         DtPushSubtable (Subtable);
   1143 
   1144         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
   1145 
   1146         switch (DmarHeader->Type)
   1147         {
   1148         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
   1149 
   1150             InfoTable = AcpiDmTableInfoDmar0;
   1151             break;
   1152 
   1153         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
   1154 
   1155             InfoTable = AcpiDmTableInfoDmar1;
   1156             break;
   1157 
   1158         case ACPI_DMAR_TYPE_ROOT_ATS:
   1159 
   1160             InfoTable = AcpiDmTableInfoDmar2;
   1161             break;
   1162 
   1163         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
   1164 
   1165             InfoTable = AcpiDmTableInfoDmar3;
   1166             break;
   1167 
   1168         case ACPI_DMAR_TYPE_NAMESPACE:
   1169 
   1170             InfoTable = AcpiDmTableInfoDmar4;
   1171             break;
   1172 
   1173         case ACPI_DMAR_TYPE_SATC:
   1174 
   1175             InfoTable = AcpiDmTableInfoDmar5;
   1176             break;
   1177 
   1178         default:
   1179 
   1180             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
   1181             return (AE_ERROR);
   1182         }
   1183 
   1184         /* DMAR Subtable */
   1185 
   1186         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1187         if (ACPI_FAILURE (Status))
   1188         {
   1189             return (Status);
   1190         }
   1191 
   1192         ParentTable = DtPeekSubtable ();
   1193         DtInsertSubtable (ParentTable, Subtable);
   1194 
   1195         /*
   1196          * Optional Device Scope subtables
   1197          */
   1198         if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
   1199             (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
   1200         {
   1201             /* These types do not support device scopes */
   1202 
   1203             DtPopSubtable ();
   1204             continue;
   1205         }
   1206 
   1207         DtPushSubtable (Subtable);
   1208         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
   1209             ParentTable->Length;
   1210         while (DeviceScopeLength)
   1211         {
   1212             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
   1213                 &Subtable);
   1214             if (Status == AE_NOT_FOUND)
   1215             {
   1216                 break;
   1217             }
   1218 
   1219             ParentTable = DtPeekSubtable ();
   1220             DtInsertSubtable (ParentTable, Subtable);
   1221             DtPushSubtable (Subtable);
   1222 
   1223             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
   1224 
   1225             /* Optional PCI Paths */
   1226 
   1227             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
   1228             while (PciPathLength)
   1229             {
   1230                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
   1231                     &Subtable);
   1232                 if (Status == AE_NOT_FOUND)
   1233                 {
   1234                     DtPopSubtable ();
   1235                     break;
   1236                 }
   1237 
   1238                 ParentTable = DtPeekSubtable ();
   1239                 DtInsertSubtable (ParentTable, Subtable);
   1240                 PciPathLength -= Subtable->Length;
   1241             }
   1242 
   1243             DtPopSubtable ();
   1244             DeviceScopeLength -= DmarDeviceScope->Length;
   1245         }
   1246 
   1247         DtPopSubtable ();
   1248         DtPopSubtable ();
   1249     }
   1250 
   1251     return (AE_OK);
   1252 }
   1253 
   1254 
   1255 /******************************************************************************
   1256  *
   1257  * FUNCTION:    DtCompileDrtm
   1258  *
   1259  * PARAMETERS:  List                - Current field list pointer
   1260  *
   1261  * RETURN:      Status
   1262  *
   1263  * DESCRIPTION: Compile DRTM.
   1264  *
   1265  *****************************************************************************/
   1266 
   1267 ACPI_STATUS
   1268 DtCompileDrtm (
   1269     void                    **List)
   1270 {
   1271     ACPI_STATUS             Status;
   1272     DT_SUBTABLE             *Subtable;
   1273     DT_SUBTABLE             *ParentTable;
   1274     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1275     UINT32                  Count;
   1276     /* ACPI_TABLE_DRTM         *Drtm; */
   1277     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
   1278     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
   1279     /* ACPI_DRTM_DPS_ID        *DrtmDps; */
   1280 
   1281 
   1282     ParentTable = DtPeekSubtable ();
   1283 
   1284     /* Compile DRTM header */
   1285 
   1286     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
   1287         &Subtable);
   1288     if (ACPI_FAILURE (Status))
   1289     {
   1290         return (Status);
   1291     }
   1292     DtInsertSubtable (ParentTable, Subtable);
   1293 
   1294     /*
   1295      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   1296      * should be taken to avoid accessing ACPI_TABLE_HADER fields.
   1297      */
   1298 #if 0
   1299     Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
   1300         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
   1301 #endif
   1302     /* Compile VTL */
   1303 
   1304     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
   1305         &Subtable);
   1306     if (ACPI_FAILURE (Status))
   1307     {
   1308         return (Status);
   1309     }
   1310 
   1311     DtInsertSubtable (ParentTable, Subtable);
   1312     DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
   1313 
   1314     DtPushSubtable (Subtable);
   1315     ParentTable = DtPeekSubtable ();
   1316     Count = 0;
   1317 
   1318     while (*PFieldList)
   1319     {
   1320         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
   1321             &Subtable);
   1322         if (ACPI_FAILURE (Status))
   1323         {
   1324             return (Status);
   1325         }
   1326         if (!Subtable)
   1327         {
   1328             break;
   1329         }
   1330         DtInsertSubtable (ParentTable, Subtable);
   1331         Count++;
   1332     }
   1333 
   1334     DrtmVtl->ValidatedTableCount = Count;
   1335     DtPopSubtable ();
   1336     ParentTable = DtPeekSubtable ();
   1337 
   1338     /* Compile RL */
   1339 
   1340     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
   1341         &Subtable);
   1342     if (ACPI_FAILURE (Status))
   1343     {
   1344         return (Status);
   1345     }
   1346 
   1347     DtInsertSubtable (ParentTable, Subtable);
   1348     DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
   1349 
   1350     DtPushSubtable (Subtable);
   1351     ParentTable = DtPeekSubtable ();
   1352     Count = 0;
   1353 
   1354     while (*PFieldList)
   1355     {
   1356         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
   1357             &Subtable);
   1358         if (ACPI_FAILURE (Status))
   1359         {
   1360             return (Status);
   1361         }
   1362 
   1363         if (!Subtable)
   1364         {
   1365             break;
   1366         }
   1367 
   1368         DtInsertSubtable (ParentTable, Subtable);
   1369         Count++;
   1370     }
   1371 
   1372     DrtmRl->ResourceCount = Count;
   1373     DtPopSubtable ();
   1374     ParentTable = DtPeekSubtable ();
   1375 
   1376     /* Compile DPS */
   1377 
   1378     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
   1379         &Subtable);
   1380     if (ACPI_FAILURE (Status))
   1381     {
   1382         return (Status);
   1383     }
   1384     DtInsertSubtable (ParentTable, Subtable);
   1385     /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
   1386 
   1387 
   1388     return (AE_OK);
   1389 }
   1390 
   1391 
   1392 /******************************************************************************
   1393  *
   1394  * FUNCTION:    DtCompileEinj
   1395  *
   1396  * PARAMETERS:  List                - Current field list pointer
   1397  *
   1398  * RETURN:      Status
   1399  *
   1400  * DESCRIPTION: Compile EINJ.
   1401  *
   1402  *****************************************************************************/
   1403 
   1404 ACPI_STATUS
   1405 DtCompileEinj (
   1406     void                    **List)
   1407 {
   1408     ACPI_STATUS             Status;
   1409 
   1410 
   1411     Status = DtCompileTwoSubtables (List,
   1412         AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
   1413     return (Status);
   1414 }
   1415 
   1416 
   1417 /******************************************************************************
   1418  *
   1419  * FUNCTION:    DtCompileErst
   1420  *
   1421  * PARAMETERS:  List                - Current field list pointer
   1422  *
   1423  * RETURN:      Status
   1424  *
   1425  * DESCRIPTION: Compile ERST.
   1426  *
   1427  *****************************************************************************/
   1428 
   1429 ACPI_STATUS
   1430 DtCompileErst (
   1431     void                    **List)
   1432 {
   1433     ACPI_STATUS             Status;
   1434 
   1435 
   1436     Status = DtCompileTwoSubtables (List,
   1437         AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
   1438     return (Status);
   1439 }
   1440 
   1441 
   1442 /******************************************************************************
   1443  *
   1444  * FUNCTION:    DtCompileGtdt
   1445  *
   1446  * PARAMETERS:  List                - Current field list pointer
   1447  *
   1448  * RETURN:      Status
   1449  *
   1450  * DESCRIPTION: Compile GTDT.
   1451  *
   1452  *****************************************************************************/
   1453 
   1454 ACPI_STATUS
   1455 DtCompileGtdt (
   1456     void                    **List)
   1457 {
   1458     ACPI_STATUS             Status;
   1459     DT_SUBTABLE             *Subtable;
   1460     DT_SUBTABLE             *ParentTable;
   1461     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1462     DT_FIELD                *SubtableStart;
   1463     ACPI_SUBTABLE_HEADER    *GtdtHeader;
   1464     ACPI_DMTABLE_INFO       *InfoTable;
   1465     UINT32                  GtCount;
   1466     ACPI_TABLE_HEADER       *Header;
   1467 
   1468 
   1469     ParentTable = DtPeekSubtable ();
   1470 
   1471     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   1472 
   1473     /* Compile the main table */
   1474 
   1475     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
   1476         &Subtable);
   1477     if (ACPI_FAILURE (Status))
   1478     {
   1479         return (Status);
   1480     }
   1481 
   1482     /* GTDT revision 3 later contains 2 extra fields before subtables */
   1483 
   1484     if (Header->Revision > 2)
   1485     {
   1486         ParentTable = DtPeekSubtable ();
   1487         DtInsertSubtable (ParentTable, Subtable);
   1488 
   1489         Status = DtCompileTable (PFieldList,
   1490             AcpiDmTableInfoGtdtEl2, &Subtable);
   1491         if (ACPI_FAILURE (Status))
   1492         {
   1493             return (Status);
   1494         }
   1495     }
   1496 
   1497     ParentTable = DtPeekSubtable ();
   1498     DtInsertSubtable (ParentTable, Subtable);
   1499 
   1500     while (*PFieldList)
   1501     {
   1502         SubtableStart = *PFieldList;
   1503         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
   1504             &Subtable);
   1505         if (ACPI_FAILURE (Status))
   1506         {
   1507             return (Status);
   1508         }
   1509 
   1510         ParentTable = DtPeekSubtable ();
   1511         DtInsertSubtable (ParentTable, Subtable);
   1512         DtPushSubtable (Subtable);
   1513 
   1514         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
   1515 
   1516         switch (GtdtHeader->Type)
   1517         {
   1518         case ACPI_GTDT_TYPE_TIMER_BLOCK:
   1519 
   1520             InfoTable = AcpiDmTableInfoGtdt0;
   1521             break;
   1522 
   1523         case ACPI_GTDT_TYPE_WATCHDOG:
   1524 
   1525             InfoTable = AcpiDmTableInfoGtdt1;
   1526             break;
   1527 
   1528         default:
   1529 
   1530             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
   1531             return (AE_ERROR);
   1532         }
   1533 
   1534         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1535         if (ACPI_FAILURE (Status))
   1536         {
   1537             return (Status);
   1538         }
   1539 
   1540         ParentTable = DtPeekSubtable ();
   1541         DtInsertSubtable (ParentTable, Subtable);
   1542 
   1543         /*
   1544          * Additional GT block subtable data
   1545          */
   1546 
   1547         switch (GtdtHeader->Type)
   1548         {
   1549         case ACPI_GTDT_TYPE_TIMER_BLOCK:
   1550 
   1551             DtPushSubtable (Subtable);
   1552             ParentTable = DtPeekSubtable ();
   1553 
   1554             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
   1555                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
   1556 
   1557             while (GtCount)
   1558             {
   1559                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
   1560                     &Subtable);
   1561                 if (ACPI_FAILURE (Status))
   1562                 {
   1563                     return (Status);
   1564                 }
   1565 
   1566                 DtInsertSubtable (ParentTable, Subtable);
   1567                 GtCount--;
   1568             }
   1569 
   1570             DtPopSubtable ();
   1571             break;
   1572 
   1573         default:
   1574 
   1575             break;
   1576         }
   1577 
   1578         DtPopSubtable ();
   1579     }
   1580 
   1581     return (AE_OK);
   1582 }
   1583 
   1584 
   1585 /******************************************************************************
   1586  *
   1587  * FUNCTION:    DtCompileFpdt
   1588  *
   1589  * PARAMETERS:  List                - Current field list pointer
   1590  *
   1591  * RETURN:      Status
   1592  *
   1593  * DESCRIPTION: Compile FPDT.
   1594  *
   1595  *****************************************************************************/
   1596 
   1597 ACPI_STATUS
   1598 DtCompileFpdt (
   1599     void                    **List)
   1600 {
   1601     ACPI_STATUS             Status;
   1602     ACPI_FPDT_HEADER        *FpdtHeader;
   1603     DT_SUBTABLE             *Subtable;
   1604     DT_SUBTABLE             *ParentTable;
   1605     ACPI_DMTABLE_INFO       *InfoTable;
   1606     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1607     DT_FIELD                *SubtableStart;
   1608 
   1609 
   1610     while (*PFieldList)
   1611     {
   1612         SubtableStart = *PFieldList;
   1613         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
   1614             &Subtable);
   1615         if (ACPI_FAILURE (Status))
   1616         {
   1617             return (Status);
   1618         }
   1619 
   1620         ParentTable = DtPeekSubtable ();
   1621         DtInsertSubtable (ParentTable, Subtable);
   1622         DtPushSubtable (Subtable);
   1623 
   1624         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
   1625 
   1626         switch (FpdtHeader->Type)
   1627         {
   1628         case ACPI_FPDT_TYPE_BOOT:
   1629 
   1630             InfoTable = AcpiDmTableInfoFpdt0;
   1631             break;
   1632 
   1633         case ACPI_FPDT_TYPE_S3PERF:
   1634 
   1635             InfoTable = AcpiDmTableInfoFpdt1;
   1636             break;
   1637 
   1638         default:
   1639 
   1640             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
   1641             return (AE_ERROR);
   1642             break;
   1643         }
   1644 
   1645         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1646         if (ACPI_FAILURE (Status))
   1647         {
   1648             return (Status);
   1649         }
   1650 
   1651         ParentTable = DtPeekSubtable ();
   1652         DtInsertSubtable (ParentTable, Subtable);
   1653         DtPopSubtable ();
   1654     }
   1655 
   1656     return (AE_OK);
   1657 }
   1658 
   1659 
   1660 /******************************************************************************
   1661  *
   1662  * FUNCTION:    DtCompileHest
   1663  *
   1664  * PARAMETERS:  List                - Current field list pointer
   1665  *
   1666  * RETURN:      Status
   1667  *
   1668  * DESCRIPTION: Compile HEST.
   1669  *
   1670  *****************************************************************************/
   1671 
   1672 ACPI_STATUS
   1673 DtCompileHest (
   1674     void                    **List)
   1675 {
   1676     ACPI_STATUS             Status;
   1677     DT_SUBTABLE             *Subtable;
   1678     DT_SUBTABLE             *ParentTable;
   1679     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1680     DT_FIELD                *SubtableStart;
   1681     ACPI_DMTABLE_INFO       *InfoTable;
   1682     UINT16                  Type;
   1683     UINT32                  BankCount;
   1684 
   1685 
   1686     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
   1687         &Subtable);
   1688     if (ACPI_FAILURE (Status))
   1689     {
   1690         return (Status);
   1691     }
   1692 
   1693     ParentTable = DtPeekSubtable ();
   1694     DtInsertSubtable (ParentTable, Subtable);
   1695 
   1696     while (*PFieldList)
   1697     {
   1698         /* Get subtable type */
   1699 
   1700         SubtableStart = *PFieldList;
   1701         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
   1702 
   1703         switch (Type)
   1704         {
   1705         case ACPI_HEST_TYPE_IA32_CHECK:
   1706 
   1707             InfoTable = AcpiDmTableInfoHest0;
   1708             break;
   1709 
   1710         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   1711 
   1712             InfoTable = AcpiDmTableInfoHest1;
   1713             break;
   1714 
   1715         case ACPI_HEST_TYPE_IA32_NMI:
   1716 
   1717             InfoTable = AcpiDmTableInfoHest2;
   1718             break;
   1719 
   1720         case ACPI_HEST_TYPE_AER_ROOT_PORT:
   1721 
   1722             InfoTable = AcpiDmTableInfoHest6;
   1723             break;
   1724 
   1725         case ACPI_HEST_TYPE_AER_ENDPOINT:
   1726 
   1727             InfoTable = AcpiDmTableInfoHest7;
   1728             break;
   1729 
   1730         case ACPI_HEST_TYPE_AER_BRIDGE:
   1731 
   1732             InfoTable = AcpiDmTableInfoHest8;
   1733             break;
   1734 
   1735         case ACPI_HEST_TYPE_GENERIC_ERROR:
   1736 
   1737             InfoTable = AcpiDmTableInfoHest9;
   1738             break;
   1739 
   1740         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
   1741 
   1742             InfoTable = AcpiDmTableInfoHest10;
   1743             break;
   1744 
   1745         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   1746 
   1747             InfoTable = AcpiDmTableInfoHest11;
   1748             break;
   1749 
   1750         default:
   1751 
   1752             /* Cannot continue on unknown type */
   1753 
   1754             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
   1755             return (AE_ERROR);
   1756         }
   1757 
   1758         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1759         if (ACPI_FAILURE (Status))
   1760         {
   1761             return (Status);
   1762         }
   1763 
   1764         DtInsertSubtable (ParentTable, Subtable);
   1765 
   1766         /*
   1767          * Additional subtable data - IA32 Error Bank(s)
   1768          */
   1769         BankCount = 0;
   1770         switch (Type)
   1771         {
   1772         case ACPI_HEST_TYPE_IA32_CHECK:
   1773 
   1774             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
   1775                 Subtable->Buffer))->NumHardwareBanks;
   1776             break;
   1777 
   1778         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   1779 
   1780             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
   1781                 Subtable->Buffer))->NumHardwareBanks;
   1782             break;
   1783 
   1784         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   1785 
   1786             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
   1787                 Subtable->Buffer))->NumHardwareBanks;
   1788             break;
   1789 
   1790         default:
   1791 
   1792             break;
   1793         }
   1794 
   1795         while (BankCount)
   1796         {
   1797             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
   1798                 &Subtable);
   1799             if (ACPI_FAILURE (Status))
   1800             {
   1801                 return (Status);
   1802             }
   1803 
   1804             DtInsertSubtable (ParentTable, Subtable);
   1805             BankCount--;
   1806         }
   1807     }
   1808 
   1809     return (AE_OK);
   1810 }
   1811 
   1812 
   1813 /******************************************************************************
   1814  *
   1815  * FUNCTION:    DtCompileHmat
   1816  *
   1817  * PARAMETERS:  List                - Current field list pointer
   1818  *
   1819  * RETURN:      Status
   1820  *
   1821  * DESCRIPTION: Compile HMAT.
   1822  *
   1823  *****************************************************************************/
   1824 
   1825 ACPI_STATUS
   1826 DtCompileHmat (
   1827     void                    **List)
   1828 {
   1829     ACPI_STATUS             Status;
   1830     DT_SUBTABLE             *Subtable;
   1831     DT_SUBTABLE             *ParentTable;
   1832     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1833     DT_FIELD                *SubtableStart;
   1834     DT_FIELD                *EntryStart;
   1835     ACPI_HMAT_STRUCTURE     *HmatStruct;
   1836     ACPI_HMAT_LOCALITY      *HmatLocality;
   1837     ACPI_HMAT_CACHE         *HmatCache;
   1838     ACPI_DMTABLE_INFO       *InfoTable;
   1839     UINT32                  IntPDNumber;
   1840     UINT32                  TgtPDNumber;
   1841     UINT64                  EntryNumber;
   1842     UINT16                  SMBIOSHandleNumber;
   1843 
   1844 
   1845     ParentTable = DtPeekSubtable ();
   1846 
   1847     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
   1848         &Subtable);
   1849     if (ACPI_FAILURE (Status))
   1850     {
   1851         return (Status);
   1852     }
   1853     DtInsertSubtable (ParentTable, Subtable);
   1854 
   1855     while (*PFieldList)
   1856     {
   1857         /* Compile HMAT structure header */
   1858 
   1859         SubtableStart = *PFieldList;
   1860         Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
   1861             &Subtable);
   1862         if (ACPI_FAILURE (Status))
   1863         {
   1864             return (Status);
   1865         }
   1866         DtInsertSubtable (ParentTable, Subtable);
   1867 
   1868         HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
   1869         HmatStruct->Length = Subtable->Length;
   1870 
   1871         /* Compile HMAT structure body */
   1872 
   1873         switch (HmatStruct->Type)
   1874         {
   1875         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
   1876 
   1877             InfoTable = AcpiDmTableInfoHmat0;
   1878             break;
   1879 
   1880         case ACPI_HMAT_TYPE_LOCALITY:
   1881 
   1882             InfoTable = AcpiDmTableInfoHmat1;
   1883             break;
   1884 
   1885         case ACPI_HMAT_TYPE_CACHE:
   1886 
   1887             InfoTable = AcpiDmTableInfoHmat2;
   1888             break;
   1889 
   1890         default:
   1891 
   1892             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
   1893             return (AE_ERROR);
   1894         }
   1895 
   1896         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1897         if (ACPI_FAILURE (Status))
   1898         {
   1899             return (Status);
   1900         }
   1901         DtInsertSubtable (ParentTable, Subtable);
   1902         HmatStruct->Length += Subtable->Length;
   1903 
   1904         /* Compile HMAT structure additionals */
   1905 
   1906         switch (HmatStruct->Type)
   1907         {
   1908         case ACPI_HMAT_TYPE_LOCALITY:
   1909 
   1910             HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
   1911                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   1912 
   1913             /* Compile initiator proximity domain list */
   1914 
   1915             IntPDNumber = 0;
   1916             while (*PFieldList)
   1917             {
   1918                 Status = DtCompileTable (PFieldList,
   1919                     AcpiDmTableInfoHmat1a, &Subtable);
   1920                 if (ACPI_FAILURE (Status))
   1921                 {
   1922                     return (Status);
   1923                 }
   1924                 if (!Subtable)
   1925                 {
   1926                     break;
   1927                 }
   1928                 DtInsertSubtable (ParentTable, Subtable);
   1929                 HmatStruct->Length += Subtable->Length;
   1930                 IntPDNumber++;
   1931             }
   1932             HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
   1933 
   1934             /* Compile target proximity domain list */
   1935 
   1936             TgtPDNumber = 0;
   1937             while (*PFieldList)
   1938             {
   1939                 Status = DtCompileTable (PFieldList,
   1940                     AcpiDmTableInfoHmat1b, &Subtable);
   1941                 if (ACPI_FAILURE (Status))
   1942                 {
   1943                     return (Status);
   1944                 }
   1945                 if (!Subtable)
   1946                 {
   1947                     break;
   1948                 }
   1949                 DtInsertSubtable (ParentTable, Subtable);
   1950                 HmatStruct->Length += Subtable->Length;
   1951                 TgtPDNumber++;
   1952             }
   1953             HmatLocality->NumberOfTargetPDs = TgtPDNumber;
   1954 
   1955             /* Save start of the entries for reporting errors */
   1956 
   1957             EntryStart = *PFieldList;
   1958 
   1959             /* Compile latency/bandwidth entries */
   1960 
   1961             EntryNumber = 0;
   1962             while (*PFieldList)
   1963             {
   1964                 Status = DtCompileTable (PFieldList,
   1965                     AcpiDmTableInfoHmat1c, &Subtable);
   1966                 if (ACPI_FAILURE (Status))
   1967                 {
   1968                     return (Status);
   1969                 }
   1970                 if (!Subtable)
   1971                 {
   1972                     break;
   1973                 }
   1974                 DtInsertSubtable (ParentTable, Subtable);
   1975                 HmatStruct->Length += Subtable->Length;
   1976                 EntryNumber++;
   1977             }
   1978 
   1979             /* Validate number of entries */
   1980 
   1981             if (EntryNumber !=
   1982                 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
   1983             {
   1984                 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
   1985                 return (AE_ERROR);
   1986             }
   1987             break;
   1988 
   1989         case ACPI_HMAT_TYPE_CACHE:
   1990 
   1991             /* Compile SMBIOS handles */
   1992 
   1993             HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
   1994                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   1995             SMBIOSHandleNumber = 0;
   1996             while (*PFieldList)
   1997             {
   1998                 Status = DtCompileTable (PFieldList,
   1999                     AcpiDmTableInfoHmat2a, &Subtable);
   2000                 if (ACPI_FAILURE (Status))
   2001                 {
   2002                     return (Status);
   2003                 }
   2004                 if (!Subtable)
   2005                 {
   2006                     break;
   2007                 }
   2008                 DtInsertSubtable (ParentTable, Subtable);
   2009                 HmatStruct->Length += Subtable->Length;
   2010                 SMBIOSHandleNumber++;
   2011             }
   2012             HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
   2013             break;
   2014 
   2015         default:
   2016 
   2017             break;
   2018         }
   2019     }
   2020 
   2021     return (AE_OK);
   2022 }
   2023 
   2024 
   2025 /******************************************************************************
   2026  *
   2027  * FUNCTION:    DtCompileIort
   2028  *
   2029  * PARAMETERS:  List                - Current field list pointer
   2030  *
   2031  * RETURN:      Status
   2032  *
   2033  * DESCRIPTION: Compile IORT.
   2034  *
   2035  *****************************************************************************/
   2036 
   2037 ACPI_STATUS
   2038 DtCompileIort (
   2039     void                    **List)
   2040 {
   2041     ACPI_STATUS             Status;
   2042     DT_SUBTABLE             *Subtable;
   2043     DT_SUBTABLE             *ParentTable;
   2044     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2045     DT_FIELD                *SubtableStart;
   2046     ACPI_TABLE_HEADER       *Table;
   2047     ACPI_TABLE_IORT         *Iort;
   2048     ACPI_IORT_NODE          *IortNode;
   2049     ACPI_IORT_ITS_GROUP     *IortItsGroup;
   2050     ACPI_IORT_SMMU          *IortSmmu;
   2051     ACPI_IORT_RMR           *IortRmr;
   2052     UINT32                  NodeNumber;
   2053     UINT32                  NodeLength;
   2054     UINT32                  IdMappingNumber;
   2055     UINT32                  ItsNumber;
   2056     UINT32                  ContextIrptNumber;
   2057     UINT32                  PmuIrptNumber;
   2058     UINT32                  PaddingLength;
   2059     UINT8                   Revision;
   2060     UINT32                  RmrCount;
   2061 
   2062 
   2063     ParentTable = DtPeekSubtable ();
   2064 
   2065     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
   2066         &Subtable);
   2067     if (ACPI_FAILURE (Status))
   2068     {
   2069         return (Status);
   2070     }
   2071     DtInsertSubtable (ParentTable, Subtable);
   2072 
   2073     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   2074     Revision = Table->Revision;
   2075 
   2076     /* IORT Revisions E, E.a & E.c have known issues and are not supported */
   2077 
   2078     if (Revision == 1 || Revision == 2 || Revision == 4)
   2079     {
   2080         DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision");
   2081         return (AE_ERROR);
   2082     }
   2083 
   2084     /*
   2085      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   2086      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
   2087      */
   2088     Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
   2089         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
   2090 
   2091     /*
   2092      * OptionalPadding - Variable-length data
   2093      * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
   2094      * Optionally allows the generic data types to be used for filling
   2095      * this field.
   2096      */
   2097     Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
   2098     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
   2099         &Subtable);
   2100     if (ACPI_FAILURE (Status))
   2101     {
   2102         return (Status);
   2103     }
   2104     if (Subtable)
   2105     {
   2106         DtInsertSubtable (ParentTable, Subtable);
   2107         Iort->NodeOffset += Subtable->Length;
   2108     }
   2109     else
   2110     {
   2111         Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
   2112             AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
   2113         if (ACPI_FAILURE (Status))
   2114         {
   2115             return (Status);
   2116         }
   2117         Iort->NodeOffset += PaddingLength;
   2118     }
   2119 
   2120     NodeNumber = 0;
   2121     while (*PFieldList)
   2122     {
   2123         SubtableStart = *PFieldList;
   2124         if (Revision == 0)
   2125         {
   2126             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
   2127                 &Subtable);
   2128         }
   2129         else if (Revision >= 3)
   2130         {
   2131             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3,
   2132                 &Subtable);
   2133         }
   2134 
   2135         if (ACPI_FAILURE (Status))
   2136         {
   2137             return (Status);
   2138         }
   2139 
   2140         DtInsertSubtable (ParentTable, Subtable);
   2141         IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
   2142         NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
   2143 
   2144         DtPushSubtable (Subtable);
   2145         ParentTable = DtPeekSubtable ();
   2146 
   2147         switch (IortNode->Type)
   2148         {
   2149         case ACPI_IORT_NODE_ITS_GROUP:
   2150 
   2151             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
   2152                 &Subtable);
   2153             if (ACPI_FAILURE (Status))
   2154             {
   2155                 return (Status);
   2156             }
   2157 
   2158             DtInsertSubtable (ParentTable, Subtable);
   2159             IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
   2160             NodeLength += Subtable->Length;
   2161 
   2162             ItsNumber = 0;
   2163             while (*PFieldList)
   2164             {
   2165                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
   2166                     &Subtable);
   2167                 if (ACPI_FAILURE (Status))
   2168                 {
   2169                     return (Status);
   2170                 }
   2171                 if (!Subtable)
   2172                 {
   2173                     break;
   2174                 }
   2175 
   2176                 DtInsertSubtable (ParentTable, Subtable);
   2177                 NodeLength += Subtable->Length;
   2178                 ItsNumber++;
   2179             }
   2180 
   2181             IortItsGroup->ItsCount = ItsNumber;
   2182             break;
   2183 
   2184         case ACPI_IORT_NODE_NAMED_COMPONENT:
   2185 
   2186             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
   2187                 &Subtable);
   2188             if (ACPI_FAILURE (Status))
   2189             {
   2190                 return (Status);
   2191             }
   2192 
   2193             DtInsertSubtable (ParentTable, Subtable);
   2194             NodeLength += Subtable->Length;
   2195 
   2196             /*
   2197              * Padding - Variable-length data
   2198              * Optionally allows the offset of the ID mappings to be used
   2199              * for filling this field.
   2200              */
   2201             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
   2202                 &Subtable);
   2203             if (ACPI_FAILURE (Status))
   2204             {
   2205                 return (Status);
   2206             }
   2207 
   2208             if (Subtable)
   2209             {
   2210                 DtInsertSubtable (ParentTable, Subtable);
   2211                 NodeLength += Subtable->Length;
   2212             }
   2213             else
   2214             {
   2215                 if (NodeLength > IortNode->MappingOffset)
   2216                 {
   2217                     return (AE_BAD_DATA);
   2218                 }
   2219 
   2220                 if (NodeLength < IortNode->MappingOffset)
   2221                 {
   2222                     Status = DtCompilePadding (
   2223                         IortNode->MappingOffset - NodeLength,
   2224                         &Subtable);
   2225                     if (ACPI_FAILURE (Status))
   2226                     {
   2227                         return (Status);
   2228                     }
   2229 
   2230                     DtInsertSubtable (ParentTable, Subtable);
   2231                     NodeLength = IortNode->MappingOffset;
   2232                 }
   2233             }
   2234             break;
   2235 
   2236         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
   2237 
   2238             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
   2239                 &Subtable);
   2240             if (ACPI_FAILURE (Status))
   2241             {
   2242                 return (Status);
   2243             }
   2244 
   2245             DtInsertSubtable (ParentTable, Subtable);
   2246             NodeLength += Subtable->Length;
   2247             break;
   2248 
   2249         case ACPI_IORT_NODE_SMMU:
   2250 
   2251             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
   2252                 &Subtable);
   2253             if (ACPI_FAILURE (Status))
   2254             {
   2255                 return (Status);
   2256             }
   2257 
   2258             DtInsertSubtable (ParentTable, Subtable);
   2259             IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
   2260             NodeLength += Subtable->Length;
   2261 
   2262             /* Compile global interrupt array */
   2263 
   2264             IortSmmu->GlobalInterruptOffset = NodeLength;
   2265             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
   2266                 &Subtable);
   2267             if (ACPI_FAILURE (Status))
   2268             {
   2269                 return (Status);
   2270             }
   2271 
   2272             DtInsertSubtable (ParentTable, Subtable);
   2273             NodeLength += Subtable->Length;
   2274 
   2275             /* Compile context interrupt array */
   2276 
   2277             ContextIrptNumber = 0;
   2278             IortSmmu->ContextInterruptOffset = NodeLength;
   2279             while (*PFieldList)
   2280             {
   2281                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
   2282                     &Subtable);
   2283                 if (ACPI_FAILURE (Status))
   2284                 {
   2285                     return (Status);
   2286                 }
   2287 
   2288                 if (!Subtable)
   2289                 {
   2290                     break;
   2291                 }
   2292 
   2293                 DtInsertSubtable (ParentTable, Subtable);
   2294                 NodeLength += Subtable->Length;
   2295                 ContextIrptNumber++;
   2296             }
   2297 
   2298             IortSmmu->ContextInterruptCount = ContextIrptNumber;
   2299 
   2300             /* Compile PMU interrupt array */
   2301 
   2302             PmuIrptNumber = 0;
   2303             IortSmmu->PmuInterruptOffset = NodeLength;
   2304             while (*PFieldList)
   2305             {
   2306                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
   2307                     &Subtable);
   2308                 if (ACPI_FAILURE (Status))
   2309                 {
   2310                     return (Status);
   2311                 }
   2312 
   2313                 if (!Subtable)
   2314                 {
   2315                     break;
   2316                 }
   2317 
   2318                 DtInsertSubtable (ParentTable, Subtable);
   2319                 NodeLength += Subtable->Length;
   2320                 PmuIrptNumber++;
   2321             }
   2322 
   2323             IortSmmu->PmuInterruptCount = PmuIrptNumber;
   2324             break;
   2325 
   2326         case ACPI_IORT_NODE_SMMU_V3:
   2327 
   2328             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
   2329                 &Subtable);
   2330             if (ACPI_FAILURE (Status))
   2331             {
   2332                 return (Status);
   2333             }
   2334 
   2335             DtInsertSubtable (ParentTable, Subtable);
   2336             NodeLength += Subtable->Length;
   2337             break;
   2338 
   2339         case ACPI_IORT_NODE_PMCG:
   2340 
   2341             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
   2342                 &Subtable);
   2343             if (ACPI_FAILURE (Status))
   2344             {
   2345                 return (Status);
   2346             }
   2347 
   2348             DtInsertSubtable (ParentTable, Subtable);
   2349             NodeLength += Subtable->Length;
   2350             break;
   2351 
   2352         case ACPI_IORT_NODE_RMR:
   2353 
   2354             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6,
   2355                 &Subtable);
   2356             if (ACPI_FAILURE (Status))
   2357             {
   2358                 return (Status);
   2359             }
   2360 
   2361             DtInsertSubtable (ParentTable, Subtable);
   2362             IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer);
   2363             NodeLength += Subtable->Length;
   2364 
   2365             /* Compile RMR Descriptors */
   2366 
   2367             RmrCount = 0;
   2368             IortRmr->RmrOffset = NodeLength;
   2369             while (*PFieldList)
   2370             {
   2371                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a,
   2372                     &Subtable);
   2373                 if (ACPI_FAILURE (Status))
   2374                 {
   2375                     return (Status);
   2376                 }
   2377 
   2378                 if (!Subtable)
   2379                 {
   2380                     break;
   2381                 }
   2382 
   2383                 DtInsertSubtable (ParentTable, Subtable);
   2384                 NodeLength += sizeof (ACPI_IORT_RMR_DESC);
   2385                 RmrCount++;
   2386             }
   2387 
   2388             IortRmr->RmrCount = RmrCount;
   2389             break;
   2390 
   2391         default:
   2392 
   2393             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
   2394             return (AE_ERROR);
   2395         }
   2396 
   2397         /* Compile Array of ID mappings */
   2398 
   2399         IortNode->MappingOffset = NodeLength;
   2400         IdMappingNumber = 0;
   2401         while (*PFieldList)
   2402         {
   2403             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
   2404                 &Subtable);
   2405             if (ACPI_FAILURE (Status))
   2406             {
   2407                 return (Status);
   2408             }
   2409 
   2410             if (!Subtable)
   2411             {
   2412                 break;
   2413             }
   2414 
   2415             DtInsertSubtable (ParentTable, Subtable);
   2416             NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
   2417             IdMappingNumber++;
   2418         }
   2419 
   2420         IortNode->MappingCount = IdMappingNumber;
   2421         if (!IdMappingNumber)
   2422         {
   2423             IortNode->MappingOffset = 0;
   2424         }
   2425 
   2426         /*
   2427          * Node length can be determined by DT_LENGTH option
   2428          * IortNode->Length = NodeLength;
   2429          */
   2430         DtPopSubtable ();
   2431         ParentTable = DtPeekSubtable ();
   2432         NodeNumber++;
   2433     }
   2434 
   2435     Iort->NodeCount = NodeNumber;
   2436     return (AE_OK);
   2437 }
   2438 
   2439 
   2440 /******************************************************************************
   2441  *
   2442  * FUNCTION:    DtCompileIvrs
   2443  *
   2444  * PARAMETERS:  List                - Current field list pointer
   2445  *
   2446  * RETURN:      Status
   2447  *
   2448  * DESCRIPTION: Compile IVRS. Notes:
   2449  *              The IVRS is essentially a flat table, with the following
   2450  *              structure:
   2451  *              <Main ACPI Table Header>
   2452  *              <Main subtable - virtualization info>
   2453  *              <IVHD>
   2454  *                  <Device Entries>
   2455  *              ...
   2456  *              <IVHD>
   2457  *                  <Device Entries>
   2458  *              <IVMD>
   2459  *              ...
   2460  *
   2461  *****************************************************************************/
   2462 
   2463 ACPI_STATUS
   2464 DtCompileIvrs (
   2465     void                    **List)
   2466 {
   2467     ACPI_STATUS             Status;
   2468     DT_SUBTABLE             *Subtable;
   2469     DT_SUBTABLE             *ParentTable;
   2470     DT_SUBTABLE             *MainSubtable;
   2471     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2472     DT_FIELD                *SubtableStart;
   2473     ACPI_DMTABLE_INFO       *InfoTable = NULL;
   2474     UINT8                   SubtableType;
   2475     UINT8                   Temp64[16];
   2476     UINT8                   Temp8;
   2477 
   2478 
   2479     /* Main table */
   2480 
   2481     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
   2482         &Subtable);
   2483     if (ACPI_FAILURE (Status))
   2484     {
   2485         return (Status);
   2486     }
   2487 
   2488     ParentTable = DtPeekSubtable ();
   2489     DtInsertSubtable (ParentTable, Subtable);
   2490     DtPushSubtable (Subtable);
   2491 
   2492     /* Save a pointer to the main subtable */
   2493 
   2494     MainSubtable = Subtable;
   2495 
   2496     while (*PFieldList)
   2497     {
   2498         SubtableStart = *PFieldList;
   2499 
   2500         /* Compile the SubtableType integer */
   2501 
   2502         DtCompileInteger (&SubtableType, *PFieldList, 1, 0);
   2503 
   2504         switch (SubtableType)
   2505         {
   2506 
   2507         /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */
   2508 
   2509         case ACPI_IVRS_TYPE_HARDWARE1:
   2510 
   2511             InfoTable = AcpiDmTableInfoIvrsHware1;
   2512             break;
   2513 
   2514         /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */
   2515 
   2516         case ACPI_IVRS_TYPE_HARDWARE2:
   2517         case ACPI_IVRS_TYPE_HARDWARE3:
   2518 
   2519             InfoTable = AcpiDmTableInfoIvrsHware23;
   2520             break;
   2521 
   2522         /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */
   2523 
   2524         case ACPI_IVRS_TYPE_MEMORY1:
   2525         case ACPI_IVRS_TYPE_MEMORY2:
   2526         case ACPI_IVRS_TYPE_MEMORY3:
   2527 
   2528             InfoTable = AcpiDmTableInfoIvrsMemory;
   2529             break;
   2530 
   2531         /* 4-byte device entries */
   2532 
   2533         case ACPI_IVRS_TYPE_PAD4:
   2534         case ACPI_IVRS_TYPE_ALL:
   2535         case ACPI_IVRS_TYPE_SELECT:
   2536         case ACPI_IVRS_TYPE_START:
   2537         case ACPI_IVRS_TYPE_END:
   2538 
   2539             InfoTable = AcpiDmTableInfoIvrs4;
   2540             break;
   2541 
   2542         /* 8-byte device entries, type A */
   2543 
   2544         case ACPI_IVRS_TYPE_ALIAS_SELECT:
   2545         case ACPI_IVRS_TYPE_ALIAS_START:
   2546 
   2547             InfoTable = AcpiDmTableInfoIvrs8a;
   2548             break;
   2549 
   2550         /* 8-byte device entries, type B */
   2551 
   2552         case ACPI_IVRS_TYPE_EXT_SELECT:
   2553         case ACPI_IVRS_TYPE_EXT_START:
   2554 
   2555             InfoTable = AcpiDmTableInfoIvrs8b;
   2556             break;
   2557 
   2558         /* 8-byte device entries, type C */
   2559 
   2560         case ACPI_IVRS_TYPE_SPECIAL:
   2561 
   2562             InfoTable = AcpiDmTableInfoIvrs8c;
   2563             break;
   2564 
   2565         /* Variable device entries, type F0h */
   2566 
   2567         case ACPI_IVRS_TYPE_HID:
   2568 
   2569             InfoTable = AcpiDmTableInfoIvrsHid;
   2570             break;
   2571 
   2572         default:
   2573 
   2574             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
   2575                 "IVRS Device Entry");
   2576             return (AE_ERROR);
   2577         }
   2578 
   2579         /* Compile the InfoTable from above */
   2580 
   2581         Status = DtCompileTable (PFieldList, InfoTable,
   2582             &Subtable);
   2583         if (ACPI_FAILURE (Status))
   2584         {
   2585             return (Status);
   2586         }
   2587 
   2588         ParentTable = DtPeekSubtable ();
   2589         if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 &&
   2590             SubtableType != ACPI_IVRS_TYPE_HARDWARE2 &&
   2591             SubtableType != ACPI_IVRS_TYPE_HARDWARE3 &&
   2592             SubtableType != ACPI_IVRS_TYPE_HID &&
   2593             SubtableType != ACPI_IVRS_TYPE_MEMORY1 &&
   2594             SubtableType != ACPI_IVRS_TYPE_MEMORY2 &&
   2595             SubtableType != ACPI_IVRS_TYPE_MEMORY3)
   2596         {
   2597             if (ParentTable)
   2598                 DtInsertSubtable (ParentTable, Subtable);
   2599         }
   2600 
   2601         switch (SubtableType)
   2602         {
   2603         case ACPI_IVRS_TYPE_HARDWARE1:
   2604         case ACPI_IVRS_TYPE_HARDWARE2:
   2605         case ACPI_IVRS_TYPE_HARDWARE3:
   2606         case ACPI_IVRS_TYPE_MEMORY1:
   2607         case ACPI_IVRS_TYPE_MEMORY2:
   2608         case ACPI_IVRS_TYPE_MEMORY3:
   2609 
   2610             /* Insert these IVHDs/IVMDs at the root subtable */
   2611 
   2612             DtInsertSubtable (MainSubtable, Subtable);
   2613             DtPushSubtable (Subtable);
   2614             break;
   2615 
   2616         case ACPI_IVRS_TYPE_HID:
   2617 
   2618             /* Special handling for the HID named device entry (0xF0) */
   2619 
   2620             if (ParentTable)
   2621             {
   2622                 DtInsertSubtable (ParentTable, Subtable);
   2623             }
   2624 
   2625             /*
   2626              * Process the HID value. First, get the HID value as a string.
   2627              */
   2628             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
   2629 
   2630                /*
   2631                 * Determine if the HID is an integer or a string.
   2632                 * An integer is defined to be 32 bits, with the upper 32 bits
   2633                 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit
   2634                 * integer or a character string. If an integer, the lower
   2635                 * 4 bytes of the field contain the integer and the upper
   2636                 * 4 bytes are padded with 0".
   2637                 */
   2638             if (UtIsIdInteger ((UINT8 *) &Temp64))
   2639             {
   2640                 /* Compile the HID value as an integer */
   2641 
   2642                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
   2643 
   2644                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger,
   2645                     &Subtable);
   2646                 if (ACPI_FAILURE (Status))
   2647                 {
   2648                     return (Status);
   2649                 }
   2650             }
   2651             else
   2652             {
   2653                 /* Compile the HID value as a string */
   2654 
   2655                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString,
   2656                     &Subtable);
   2657                 if (ACPI_FAILURE (Status))
   2658                 {
   2659                     return (Status);
   2660                 }
   2661             }
   2662 
   2663             DtInsertSubtable (ParentTable, Subtable);
   2664 
   2665             /*
   2666              * Process the CID value. First, get the CID value as a string.
   2667              */
   2668             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
   2669 
   2670             if (UtIsIdInteger ((UINT8 *) &Temp64))
   2671             {
   2672                 /* Compile the CID value as an integer */
   2673 
   2674                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
   2675 
   2676                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger,
   2677                     &Subtable);
   2678                 if (ACPI_FAILURE (Status))
   2679                 {
   2680                     return (Status);
   2681                 }
   2682             }
   2683             else
   2684             {
   2685                 /* Compile the CID value as a string */
   2686 
   2687                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString,
   2688                     &Subtable);
   2689                 if (ACPI_FAILURE (Status))
   2690                 {
   2691                     return (Status);
   2692                 }
   2693             }
   2694 
   2695             DtInsertSubtable (ParentTable, Subtable);
   2696 
   2697             /*
   2698              * Process the UID value. First, get and decode the "UID Format" field (Integer).
   2699              */
   2700             if (!*PFieldList)
   2701             {
   2702                 return (AE_OK);
   2703             }
   2704 
   2705             DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0);
   2706 
   2707             switch (Temp8)
   2708             {
   2709             case ACPI_IVRS_UID_NOT_PRESENT:
   2710                 break;
   2711 
   2712             case ACPI_IVRS_UID_IS_INTEGER:
   2713 
   2714                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger,
   2715                     &Subtable);
   2716                 if (ACPI_FAILURE (Status))
   2717                 {
   2718                     return (Status);
   2719                 }
   2720                 DtInsertSubtable (ParentTable, Subtable);
   2721                 break;
   2722 
   2723             case ACPI_IVRS_UID_IS_STRING:
   2724 
   2725                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString,
   2726                     &Subtable);
   2727                 if (ACPI_FAILURE (Status))
   2728                 {
   2729                     return (Status);
   2730                 }
   2731                 DtInsertSubtable (ParentTable, Subtable);
   2732                 break;
   2733 
   2734             default:
   2735 
   2736                 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart,
   2737                     "IVRS Device Entry");
   2738                 return (AE_ERROR);
   2739             }
   2740 
   2741         default:
   2742 
   2743             /* All other subtable types come through here */
   2744             break;
   2745         }
   2746     }
   2747 
   2748     return (AE_OK);
   2749 }
   2750