Home | History | Annotate | Line # | Download | only in compiler
dttable1.c revision 1.1.1.16
      1 /******************************************************************************
      2  *
      3  * Module Name: dttable1.c - handling for specific ACPI tables
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2023, 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  * FUNCTION:    DtCompileAspt
    552  *
    553  * PARAMETERS:  List                - Current field list pointer
    554  *
    555  * RETURN:      Status
    556  *
    557  * DESCRIPTION: Compile ASPT.
    558  *
    559  *****************************************************************************/
    560 
    561 ACPI_STATUS
    562 DtCompileAspt (
    563     void                    **List)
    564 {
    565     ACPI_ASPT_HEADER        *AsptTable;
    566     DT_SUBTABLE             *Subtable;
    567     DT_SUBTABLE             *ParentTable;
    568     ACPI_DMTABLE_INFO       *InfoTable;
    569     ACPI_STATUS             Status;
    570     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    571     DT_FIELD                *SubtableStart;
    572 
    573     Status = DtCompileTable (PFieldList, AcpiDmTableInfoAspt, &Subtable);
    574     if (ACPI_FAILURE (Status))
    575     {
    576         return (Status);
    577     }
    578 
    579     ParentTable = DtPeekSubtable ();
    580     DtInsertSubtable (ParentTable, Subtable);
    581 
    582     while (*PFieldList)
    583     {
    584         SubtableStart = *PFieldList;
    585         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsptHdr,
    586             &Subtable);
    587         if (ACPI_FAILURE (Status))
    588         {
    589             return (Status);
    590         }
    591 
    592         ParentTable = DtPeekSubtable ();
    593         DtInsertSubtable (ParentTable, Subtable);
    594         DtPushSubtable (Subtable);
    595 
    596         AsptTable = ACPI_CAST_PTR (ACPI_ASPT_HEADER, Subtable->Buffer);
    597 
    598         switch (AsptTable->Type) /* Mask off top bit */
    599         {
    600         case ACPI_ASPT_TYPE_GLOBAL_REGS:
    601 
    602             InfoTable = AcpiDmTableInfoAspt0;
    603             break;
    604 
    605         case ACPI_ASPT_TYPE_SEV_MBOX_REGS:
    606 
    607             InfoTable = AcpiDmTableInfoAspt1;
    608             break;
    609 
    610         case ACPI_ASPT_TYPE_ACPI_MBOX_REGS:
    611 
    612             InfoTable = AcpiDmTableInfoAspt2;
    613             break;
    614 
    615         default:
    616 
    617             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASPT");
    618             return (AE_ERROR);
    619         }
    620 
    621         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    622         if (ACPI_FAILURE (Status))
    623         {
    624             return (Status);
    625         }
    626         ParentTable = DtPeekSubtable ();
    627         DtInsertSubtable (ParentTable, Subtable);
    628         DtPopSubtable ();
    629     }
    630 
    631     return (AE_OK);
    632 }
    633 
    634 
    635 /******************************************************************************
    636  *
    637  * FUNCTION:    DtCompileCdat
    638  *
    639  * PARAMETERS:  List                - Current field list pointer
    640  *
    641  * RETURN:      Status
    642  *
    643  * DESCRIPTION: Compile CDAT.
    644  *
    645  *****************************************************************************/
    646 
    647 ACPI_STATUS
    648 DtCompileCdat (
    649     void                    **List)
    650 {
    651     ACPI_STATUS             Status = AE_OK;
    652     DT_SUBTABLE             *Subtable;
    653     DT_SUBTABLE             *ParentTable;
    654     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    655     ACPI_CDAT_HEADER        *CdatHeader;
    656     ACPI_DMTABLE_INFO       *InfoTable = NULL;
    657     DT_FIELD                *SubtableStart;
    658 
    659 
    660     /* Walk the parse tree.
    661      *
    662      * Note: Main table consists of only the CDAT table header
    663      * (This is not the standard ACPI table header, however)--
    664      * Followed by some number of subtables.
    665      */
    666     while (*PFieldList)
    667     {
    668         SubtableStart = *PFieldList;
    669 
    670         /* Compile the expected CDAT Subtable header */
    671 
    672         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatHeader,
    673             &Subtable);
    674         if (ACPI_FAILURE (Status))
    675         {
    676             return (Status);
    677         }
    678 
    679         ParentTable = DtPeekSubtable ();
    680         DtInsertSubtable (ParentTable, Subtable);
    681         DtPushSubtable (Subtable);
    682 
    683         CdatHeader = ACPI_CAST_PTR (ACPI_CDAT_HEADER, Subtable->Buffer);
    684 
    685         /* Decode the subtable by type */
    686 
    687         switch (CdatHeader->Type)
    688         {
    689         case ACPI_CDAT_TYPE_DSMAS:
    690             InfoTable = AcpiDmTableInfoCdat0;
    691             break;
    692 
    693         case ACPI_CDAT_TYPE_DSLBIS:
    694             InfoTable = AcpiDmTableInfoCdat1;
    695             break;
    696 
    697         case ACPI_CDAT_TYPE_DSMSCIS:
    698             InfoTable = AcpiDmTableInfoCdat2;
    699             break;
    700 
    701         case ACPI_CDAT_TYPE_DSIS:
    702             InfoTable = AcpiDmTableInfoCdat3;
    703             break;
    704 
    705         case ACPI_CDAT_TYPE_DSEMTS:
    706             InfoTable = AcpiDmTableInfoCdat4;
    707             break;
    708 
    709         case ACPI_CDAT_TYPE_SSLBIS:
    710             InfoTable = AcpiDmTableInfoCdat5;
    711             break;
    712 
    713         default:
    714             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CDAT");
    715         }
    716 
    717         /* Compile the CDAT subtable */
    718 
    719         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    720         if (ACPI_FAILURE (Status))
    721         {
    722             return (Status);
    723         }
    724 
    725         ParentTable = DtPeekSubtable ();
    726         DtInsertSubtable (ParentTable, Subtable);
    727 
    728         switch (CdatHeader->Type)
    729         {
    730         /* Multiple entries supported for this type */
    731 
    732         case ACPI_CDAT_TYPE_SSLBIS:
    733 
    734             /*
    735              * Check for multiple SSLBEs
    736              */
    737             while (*PFieldList && !AcpiUtStricmp ((*PFieldList)->Name, "Port X ID"))
    738             {
    739                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCdatEntries, &Subtable);
    740                 if (ACPI_FAILURE (Status))
    741                 {
    742                     return (Status);
    743                 }
    744                 ParentTable = DtPeekSubtable ();
    745                 DtInsertSubtable (ParentTable, Subtable);
    746             }
    747             break;
    748 
    749         default:
    750              break;
    751         }
    752 
    753         /* Pop off the CDAT Subtable header subtree */
    754 
    755         DtPopSubtable ();
    756     }
    757 
    758     return (AE_OK);
    759 }
    760 
    761 
    762 /******************************************************************************
    763  *
    764  * FUNCTION:    DtCompileCedt
    765  *
    766  * PARAMETERS:  List                - Current field list pointer
    767  *
    768  * RETURN:      Status
    769  *
    770  * DESCRIPTION: Compile CEDT.
    771  *
    772  *****************************************************************************/
    773 
    774 ACPI_STATUS
    775 DtCompileCedt (
    776     void                    **List)
    777 {
    778     ACPI_STATUS             Status;
    779     DT_SUBTABLE             *Subtable;
    780     DT_SUBTABLE             *ParentTable;
    781     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    782     ACPI_CEDT_HEADER        *CedtHeader;
    783     DT_FIELD                *SubtableStart;
    784 
    785 
    786     /* Walk the parse tree */
    787 
    788     while (*PFieldList)
    789     {
    790         /* if CFMWS and has more than one target, then set to zero later */
    791 
    792         int InsertFlag = 1;
    793         SubtableStart = *PFieldList;
    794 
    795         /* CEDT Header */
    796 
    797         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr,
    798             &Subtable);
    799         if (ACPI_FAILURE (Status))
    800         {
    801             return (Status);
    802         }
    803 
    804         ParentTable = DtPeekSubtable ();
    805         DtInsertSubtable (ParentTable, Subtable);
    806         DtPushSubtable (Subtable);
    807 
    808         CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer);
    809 
    810         switch (CedtHeader->Type)
    811         {
    812         case ACPI_CEDT_TYPE_CHBS:
    813             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable);
    814             if (ACPI_FAILURE (Status))
    815             {
    816                 return (Status);
    817             }
    818             break;
    819         case ACPI_CEDT_TYPE_CFMWS: {
    820             unsigned char *dump;
    821             unsigned int idx, offset, max = 0;
    822 
    823             /* Compile table with first "Interleave target" */
    824 
    825             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1, &Subtable);
    826             if (ACPI_FAILURE (Status))
    827             {
    828                 return (Status);
    829             }
    830 
    831             /* Look in buffer for the number of targets */
    832             offset = (unsigned int) ACPI_OFFSET (ACPI_CEDT_CFMWS, InterleaveWays);
    833             dump = (unsigned char *) Subtable->Buffer - 4;     /* place at beginning of cedt1 */
    834             max = 0x01 << dump[offset];     /* 2^max, so 0=1, 1=2, 2=4, 3=8. 8 is MAX */
    835             if (max > 8)    max=1;          /* Error in encoding Interleaving Ways. */
    836             if (max == 1)                   /* if only one target, then break here. */
    837                 break;                      /* break if only one target. */
    838 
    839             /* We need to add more interleave targets, so write the current Subtable. */
    840 
    841             ParentTable = DtPeekSubtable ();
    842             DtInsertSubtable (ParentTable, Subtable);   /* Insert AcpiDmTableInfoCedt1 table so we can put in */
    843             DtPushSubtable (Subtable);                  /* the targets > the first. */
    844 
    845             /* Now, find out all interleave targets beyond the first. */
    846 
    847             for (idx = 1; idx < max; idx++) {
    848                 ParentTable = DtPeekSubtable ();
    849 
    850                 if (*PFieldList)
    851                 {
    852                     Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt1_te, &Subtable);
    853                     if (ACPI_FAILURE (Status))
    854                     {
    855                         return (Status);
    856                     }
    857                     if (Subtable)
    858                     {
    859                         DtInsertSubtable (ParentTable, Subtable);       /* got a target, so insert table. */
    860                         InsertFlag = 0;
    861                     }
    862                 }
    863             }
    864 
    865             DtPopSubtable ();
    866             ParentTable = DtPeekSubtable ();
    867             break;
    868         }
    869 
    870         default:
    871             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT");
    872             return (AE_ERROR);
    873         }
    874 
    875         ParentTable = DtPeekSubtable ();
    876         if (InsertFlag == 1) {
    877                 DtInsertSubtable (ParentTable, Subtable);
    878         }
    879         DtPopSubtable ();
    880     }
    881 
    882     return (AE_OK);
    883 }
    884 
    885 
    886 /******************************************************************************
    887  *
    888  * FUNCTION:    DtCompileCpep
    889  *
    890  * PARAMETERS:  List                - Current field list pointer
    891  *
    892  * RETURN:      Status
    893  *
    894  * DESCRIPTION: Compile CPEP.
    895  *
    896  *****************************************************************************/
    897 
    898 ACPI_STATUS
    899 DtCompileCpep (
    900     void                    **List)
    901 {
    902     ACPI_STATUS             Status;
    903 
    904 
    905     Status = DtCompileTwoSubtables (List,
    906         AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
    907     return (Status);
    908 }
    909 
    910 
    911 /******************************************************************************
    912  *
    913  * FUNCTION:    DtCompileCsrt
    914  *
    915  * PARAMETERS:  List                - Current field list pointer
    916  *
    917  * RETURN:      Status
    918  *
    919  * DESCRIPTION: Compile CSRT.
    920  *
    921  *****************************************************************************/
    922 
    923 ACPI_STATUS
    924 DtCompileCsrt (
    925     void                    **List)
    926 {
    927     ACPI_STATUS             Status = AE_OK;
    928     DT_SUBTABLE             *Subtable;
    929     DT_SUBTABLE             *ParentTable;
    930     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    931     UINT32                  DescriptorCount;
    932     UINT32                  GroupLength;
    933 
    934 
    935     /* Subtables (Resource Groups) */
    936 
    937     ParentTable = DtPeekSubtable ();
    938     while (*PFieldList)
    939     {
    940         /* Resource group subtable */
    941 
    942         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
    943             &Subtable);
    944         if (ACPI_FAILURE (Status))
    945         {
    946             return (Status);
    947         }
    948 
    949         /* Compute the number of resource descriptors */
    950 
    951         GroupLength =
    952             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
    953                 Subtable->Buffer))->Length -
    954             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
    955                 Subtable->Buffer))->SharedInfoLength -
    956             sizeof (ACPI_CSRT_GROUP);
    957 
    958         DescriptorCount = (GroupLength  /
    959             sizeof (ACPI_CSRT_DESCRIPTOR));
    960 
    961         DtInsertSubtable (ParentTable, Subtable);
    962         DtPushSubtable (Subtable);
    963         ParentTable = DtPeekSubtable ();
    964 
    965         /* Shared info subtable (One per resource group) */
    966 
    967         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
    968             &Subtable);
    969         if (ACPI_FAILURE (Status))
    970         {
    971             return (Status);
    972         }
    973 
    974         DtInsertSubtable (ParentTable, Subtable);
    975 
    976         /* Sub-Subtables (Resource Descriptors) */
    977 
    978         while (*PFieldList && DescriptorCount)
    979         {
    980 
    981             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
    982                 &Subtable);
    983             if (ACPI_FAILURE (Status))
    984             {
    985                 return (Status);
    986             }
    987 
    988             DtInsertSubtable (ParentTable, Subtable);
    989 
    990             DtPushSubtable (Subtable);
    991             ParentTable = DtPeekSubtable ();
    992             if (*PFieldList)
    993             {
    994                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
    995                     &Subtable);
    996                 if (ACPI_FAILURE (Status))
    997                 {
    998                     return (Status);
    999                 }
   1000                 if (Subtable)
   1001                 {
   1002                     DtInsertSubtable (ParentTable, Subtable);
   1003                 }
   1004             }
   1005 
   1006             DtPopSubtable ();
   1007             ParentTable = DtPeekSubtable ();
   1008             DescriptorCount--;
   1009         }
   1010 
   1011         DtPopSubtable ();
   1012         ParentTable = DtPeekSubtable ();
   1013     }
   1014 
   1015     return (Status);
   1016 }
   1017 
   1018 
   1019 /******************************************************************************
   1020  *
   1021  * FUNCTION:    DtCompileDbg2
   1022  *
   1023  * PARAMETERS:  List                - Current field list pointer
   1024  *
   1025  * RETURN:      Status
   1026  *
   1027  * DESCRIPTION: Compile DBG2.
   1028  *
   1029  *****************************************************************************/
   1030 
   1031 ACPI_STATUS
   1032 DtCompileDbg2 (
   1033     void                    **List)
   1034 {
   1035     ACPI_STATUS             Status;
   1036     DT_SUBTABLE             *Subtable;
   1037     DT_SUBTABLE             *ParentTable;
   1038     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1039     UINT32                  SubtableCount;
   1040     ACPI_DBG2_HEADER        *Dbg2Header;
   1041     ACPI_DBG2_DEVICE        *DeviceInfo;
   1042     UINT16                  CurrentOffset;
   1043     UINT32                  i;
   1044 
   1045 
   1046     /* Main table */
   1047 
   1048     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable);
   1049     if (ACPI_FAILURE (Status))
   1050     {
   1051         return (Status);
   1052     }
   1053 
   1054     ParentTable = DtPeekSubtable ();
   1055     DtInsertSubtable (ParentTable, Subtable);
   1056 
   1057     /* Main table fields */
   1058 
   1059     Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
   1060     Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
   1061         ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
   1062 
   1063     SubtableCount = Dbg2Header->InfoCount;
   1064     DtPushSubtable (Subtable);
   1065 
   1066     /* Process all Device Information subtables (Count = InfoCount) */
   1067 
   1068     while (*PFieldList && SubtableCount)
   1069     {
   1070         /* Subtable: Debug Device Information */
   1071 
   1072         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
   1073             &Subtable);
   1074         if (ACPI_FAILURE (Status))
   1075         {
   1076             return (Status);
   1077         }
   1078 
   1079         DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
   1080         CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
   1081 
   1082         ParentTable = DtPeekSubtable ();
   1083         DtInsertSubtable (ParentTable, Subtable);
   1084         DtPushSubtable (Subtable);
   1085 
   1086         ParentTable = DtPeekSubtable ();
   1087 
   1088         /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
   1089 
   1090         DeviceInfo->BaseAddressOffset = CurrentOffset;
   1091         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
   1092         {
   1093             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
   1094                 &Subtable);
   1095             if (ACPI_FAILURE (Status))
   1096             {
   1097                 return (Status);
   1098             }
   1099 
   1100             CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
   1101             DtInsertSubtable (ParentTable, Subtable);
   1102         }
   1103 
   1104         /* AddressSize array (Required, size = RegisterCount) */
   1105 
   1106         DeviceInfo->AddressSizeOffset = CurrentOffset;
   1107         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
   1108         {
   1109             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
   1110                 &Subtable);
   1111             if (ACPI_FAILURE (Status))
   1112             {
   1113                 return (Status);
   1114             }
   1115 
   1116             CurrentOffset += (UINT16) sizeof (UINT32);
   1117             DtInsertSubtable (ParentTable, Subtable);
   1118         }
   1119 
   1120         /* NamespaceString device identifier (Required, size = NamePathLength) */
   1121 
   1122         DeviceInfo->NamepathOffset = CurrentOffset;
   1123         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
   1124             &Subtable);
   1125         if (ACPI_FAILURE (Status))
   1126         {
   1127             return (Status);
   1128         }
   1129 
   1130         /* Update the device info header */
   1131 
   1132         DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
   1133         CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
   1134         DtInsertSubtable (ParentTable, Subtable);
   1135 
   1136         /* OemData - Variable-length data (Optional, size = OemDataLength) */
   1137 
   1138         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
   1139             &Subtable);
   1140         if (Status == AE_END_OF_TABLE)
   1141         {
   1142             /* optional field was not found and we're at the end of the file */
   1143 
   1144             goto subtableDone;
   1145         }
   1146         else if (ACPI_FAILURE (Status))
   1147         {
   1148             return (Status);
   1149         }
   1150 
   1151         /* Update the device info header (zeros if no OEM data present) */
   1152 
   1153         DeviceInfo->OemDataOffset = 0;
   1154         DeviceInfo->OemDataLength = 0;
   1155 
   1156         /* Optional subtable (OemData) */
   1157 
   1158         if (Subtable && Subtable->Length)
   1159         {
   1160             DeviceInfo->OemDataOffset = CurrentOffset;
   1161             DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
   1162 
   1163             DtInsertSubtable (ParentTable, Subtable);
   1164         }
   1165 subtableDone:
   1166         SubtableCount--;
   1167         DtPopSubtable (); /* Get next Device Information subtable */
   1168     }
   1169 
   1170     DtPopSubtable ();
   1171     return (AE_OK);
   1172 }
   1173 
   1174 
   1175 /******************************************************************************
   1176  *
   1177  * FUNCTION:    DtCompileDmar
   1178  *
   1179  * PARAMETERS:  List                - Current field list pointer
   1180  *
   1181  * RETURN:      Status
   1182  *
   1183  * DESCRIPTION: Compile DMAR.
   1184  *
   1185  *****************************************************************************/
   1186 
   1187 ACPI_STATUS
   1188 DtCompileDmar (
   1189     void                    **List)
   1190 {
   1191     ACPI_STATUS             Status;
   1192     DT_SUBTABLE             *Subtable;
   1193     DT_SUBTABLE             *ParentTable;
   1194     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1195     DT_FIELD                *SubtableStart;
   1196     ACPI_DMTABLE_INFO       *InfoTable;
   1197     ACPI_DMAR_HEADER        *DmarHeader;
   1198     ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
   1199     UINT32                  DeviceScopeLength;
   1200     UINT32                  PciPathLength;
   1201 
   1202 
   1203     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable);
   1204     if (ACPI_FAILURE (Status))
   1205     {
   1206         return (Status);
   1207     }
   1208 
   1209     ParentTable = DtPeekSubtable ();
   1210     DtInsertSubtable (ParentTable, Subtable);
   1211     DtPushSubtable (Subtable);
   1212 
   1213     while (*PFieldList)
   1214     {
   1215         /* DMAR Header */
   1216 
   1217         SubtableStart = *PFieldList;
   1218         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
   1219             &Subtable);
   1220         if (ACPI_FAILURE (Status))
   1221         {
   1222             return (Status);
   1223         }
   1224 
   1225         ParentTable = DtPeekSubtable ();
   1226         DtInsertSubtable (ParentTable, Subtable);
   1227         DtPushSubtable (Subtable);
   1228 
   1229         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
   1230 
   1231         switch (DmarHeader->Type)
   1232         {
   1233         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
   1234 
   1235             InfoTable = AcpiDmTableInfoDmar0;
   1236             break;
   1237 
   1238         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
   1239 
   1240             InfoTable = AcpiDmTableInfoDmar1;
   1241             break;
   1242 
   1243         case ACPI_DMAR_TYPE_ROOT_ATS:
   1244 
   1245             InfoTable = AcpiDmTableInfoDmar2;
   1246             break;
   1247 
   1248         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
   1249 
   1250             InfoTable = AcpiDmTableInfoDmar3;
   1251             break;
   1252 
   1253         case ACPI_DMAR_TYPE_NAMESPACE:
   1254 
   1255             InfoTable = AcpiDmTableInfoDmar4;
   1256             break;
   1257 
   1258         case ACPI_DMAR_TYPE_SATC:
   1259 
   1260             InfoTable = AcpiDmTableInfoDmar5;
   1261             break;
   1262 
   1263         default:
   1264 
   1265             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
   1266             return (AE_ERROR);
   1267         }
   1268 
   1269         /* DMAR Subtable */
   1270 
   1271         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1272         if (ACPI_FAILURE (Status))
   1273         {
   1274             return (Status);
   1275         }
   1276 
   1277         ParentTable = DtPeekSubtable ();
   1278         DtInsertSubtable (ParentTable, Subtable);
   1279 
   1280         /*
   1281          * Optional Device Scope subtables
   1282          */
   1283         if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
   1284             (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
   1285         {
   1286             /* These types do not support device scopes */
   1287 
   1288             DtPopSubtable ();
   1289             continue;
   1290         }
   1291 
   1292         DtPushSubtable (Subtable);
   1293         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
   1294             ParentTable->Length;
   1295         while (DeviceScopeLength)
   1296         {
   1297             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
   1298                 &Subtable);
   1299             if (Status == AE_NOT_FOUND)
   1300             {
   1301                 break;
   1302             }
   1303 
   1304             ParentTable = DtPeekSubtable ();
   1305             DtInsertSubtable (ParentTable, Subtable);
   1306             DtPushSubtable (Subtable);
   1307 
   1308             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
   1309 
   1310             /* Optional PCI Paths */
   1311 
   1312             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
   1313             while (PciPathLength)
   1314             {
   1315                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
   1316                     &Subtable);
   1317                 if (Status == AE_NOT_FOUND)
   1318                 {
   1319                     DtPopSubtable ();
   1320                     break;
   1321                 }
   1322 
   1323                 ParentTable = DtPeekSubtable ();
   1324                 DtInsertSubtable (ParentTable, Subtable);
   1325                 PciPathLength -= Subtable->Length;
   1326             }
   1327 
   1328             DtPopSubtable ();
   1329             DeviceScopeLength -= DmarDeviceScope->Length;
   1330         }
   1331 
   1332         DtPopSubtable ();
   1333         DtPopSubtable ();
   1334     }
   1335 
   1336     return (AE_OK);
   1337 }
   1338 
   1339 
   1340 /******************************************************************************
   1341  *
   1342  * FUNCTION:    DtCompileDrtm
   1343  *
   1344  * PARAMETERS:  List                - Current field list pointer
   1345  *
   1346  * RETURN:      Status
   1347  *
   1348  * DESCRIPTION: Compile DRTM.
   1349  *
   1350  *****************************************************************************/
   1351 
   1352 ACPI_STATUS
   1353 DtCompileDrtm (
   1354     void                    **List)
   1355 {
   1356     ACPI_STATUS             Status;
   1357     DT_SUBTABLE             *Subtable;
   1358     DT_SUBTABLE             *ParentTable;
   1359     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1360     UINT32                  Count;
   1361     /* ACPI_TABLE_DRTM         *Drtm; */
   1362     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
   1363     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
   1364     /* ACPI_DRTM_DPS_ID        *DrtmDps; */
   1365 
   1366 
   1367     ParentTable = DtPeekSubtable ();
   1368 
   1369     /* Compile DRTM header */
   1370 
   1371     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
   1372         &Subtable);
   1373     if (ACPI_FAILURE (Status))
   1374     {
   1375         return (Status);
   1376     }
   1377     DtInsertSubtable (ParentTable, Subtable);
   1378 
   1379     /*
   1380      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   1381      * should be taken to avoid accessing ACPI_TABLE_HADER fields.
   1382      */
   1383 #if 0
   1384     Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
   1385         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
   1386 #endif
   1387     /* Compile VTL */
   1388 
   1389     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
   1390         &Subtable);
   1391     if (ACPI_FAILURE (Status))
   1392     {
   1393         return (Status);
   1394     }
   1395 
   1396     DtInsertSubtable (ParentTable, Subtable);
   1397     DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
   1398 
   1399     DtPushSubtable (Subtable);
   1400     ParentTable = DtPeekSubtable ();
   1401     Count = 0;
   1402 
   1403     while (*PFieldList)
   1404     {
   1405         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
   1406             &Subtable);
   1407         if (ACPI_FAILURE (Status))
   1408         {
   1409             return (Status);
   1410         }
   1411         if (!Subtable)
   1412         {
   1413             break;
   1414         }
   1415         DtInsertSubtable (ParentTable, Subtable);
   1416         Count++;
   1417     }
   1418 
   1419     DrtmVtl->ValidatedTableCount = Count;
   1420     DtPopSubtable ();
   1421     ParentTable = DtPeekSubtable ();
   1422 
   1423     /* Compile RL */
   1424 
   1425     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
   1426         &Subtable);
   1427     if (ACPI_FAILURE (Status))
   1428     {
   1429         return (Status);
   1430     }
   1431 
   1432     DtInsertSubtable (ParentTable, Subtable);
   1433     DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
   1434 
   1435     DtPushSubtable (Subtable);
   1436     ParentTable = DtPeekSubtable ();
   1437     Count = 0;
   1438 
   1439     while (*PFieldList)
   1440     {
   1441         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
   1442             &Subtable);
   1443         if (ACPI_FAILURE (Status))
   1444         {
   1445             return (Status);
   1446         }
   1447 
   1448         if (!Subtable)
   1449         {
   1450             break;
   1451         }
   1452 
   1453         DtInsertSubtable (ParentTable, Subtable);
   1454         Count++;
   1455     }
   1456 
   1457     DrtmRl->ResourceCount = Count;
   1458     DtPopSubtable ();
   1459     ParentTable = DtPeekSubtable ();
   1460 
   1461     /* Compile DPS */
   1462 
   1463     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
   1464         &Subtable);
   1465     if (ACPI_FAILURE (Status))
   1466     {
   1467         return (Status);
   1468     }
   1469     DtInsertSubtable (ParentTable, Subtable);
   1470     /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
   1471 
   1472 
   1473     return (AE_OK);
   1474 }
   1475 
   1476 
   1477 /******************************************************************************
   1478  *
   1479  * FUNCTION:    DtCompileEinj
   1480  *
   1481  * PARAMETERS:  List                - Current field list pointer
   1482  *
   1483  * RETURN:      Status
   1484  *
   1485  * DESCRIPTION: Compile EINJ.
   1486  *
   1487  *****************************************************************************/
   1488 
   1489 ACPI_STATUS
   1490 DtCompileEinj (
   1491     void                    **List)
   1492 {
   1493     ACPI_STATUS             Status;
   1494 
   1495 
   1496     Status = DtCompileTwoSubtables (List,
   1497         AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
   1498     return (Status);
   1499 }
   1500 
   1501 
   1502 /******************************************************************************
   1503  *
   1504  * FUNCTION:    DtCompileErst
   1505  *
   1506  * PARAMETERS:  List                - Current field list pointer
   1507  *
   1508  * RETURN:      Status
   1509  *
   1510  * DESCRIPTION: Compile ERST.
   1511  *
   1512  *****************************************************************************/
   1513 
   1514 ACPI_STATUS
   1515 DtCompileErst (
   1516     void                    **List)
   1517 {
   1518     ACPI_STATUS             Status;
   1519 
   1520 
   1521     Status = DtCompileTwoSubtables (List,
   1522         AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
   1523     return (Status);
   1524 }
   1525 
   1526 
   1527 /******************************************************************************
   1528  *
   1529  * FUNCTION:    DtCompileGtdt
   1530  *
   1531  * PARAMETERS:  List                - Current field list pointer
   1532  *
   1533  * RETURN:      Status
   1534  *
   1535  * DESCRIPTION: Compile GTDT.
   1536  *
   1537  *****************************************************************************/
   1538 
   1539 ACPI_STATUS
   1540 DtCompileGtdt (
   1541     void                    **List)
   1542 {
   1543     ACPI_STATUS             Status;
   1544     DT_SUBTABLE             *Subtable;
   1545     DT_SUBTABLE             *ParentTable;
   1546     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1547     DT_FIELD                *SubtableStart;
   1548     ACPI_SUBTABLE_HEADER    *GtdtHeader;
   1549     ACPI_DMTABLE_INFO       *InfoTable;
   1550     UINT32                  GtCount;
   1551     ACPI_TABLE_HEADER       *Header;
   1552 
   1553 
   1554     ParentTable = DtPeekSubtable ();
   1555 
   1556     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   1557 
   1558     /* Compile the main table */
   1559 
   1560     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
   1561         &Subtable);
   1562     if (ACPI_FAILURE (Status))
   1563     {
   1564         return (Status);
   1565     }
   1566 
   1567     /* GTDT revision 3 later contains 2 extra fields before subtables */
   1568 
   1569     if (Header->Revision > 2)
   1570     {
   1571         ParentTable = DtPeekSubtable ();
   1572         DtInsertSubtable (ParentTable, Subtable);
   1573 
   1574         Status = DtCompileTable (PFieldList,
   1575             AcpiDmTableInfoGtdtEl2, &Subtable);
   1576         if (ACPI_FAILURE (Status))
   1577         {
   1578             return (Status);
   1579         }
   1580     }
   1581 
   1582     ParentTable = DtPeekSubtable ();
   1583     DtInsertSubtable (ParentTable, Subtable);
   1584 
   1585     while (*PFieldList)
   1586     {
   1587         SubtableStart = *PFieldList;
   1588         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
   1589             &Subtable);
   1590         if (ACPI_FAILURE (Status))
   1591         {
   1592             return (Status);
   1593         }
   1594 
   1595         ParentTable = DtPeekSubtable ();
   1596         DtInsertSubtable (ParentTable, Subtable);
   1597         DtPushSubtable (Subtable);
   1598 
   1599         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
   1600 
   1601         switch (GtdtHeader->Type)
   1602         {
   1603         case ACPI_GTDT_TYPE_TIMER_BLOCK:
   1604 
   1605             InfoTable = AcpiDmTableInfoGtdt0;
   1606             break;
   1607 
   1608         case ACPI_GTDT_TYPE_WATCHDOG:
   1609 
   1610             InfoTable = AcpiDmTableInfoGtdt1;
   1611             break;
   1612 
   1613         default:
   1614 
   1615             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
   1616             return (AE_ERROR);
   1617         }
   1618 
   1619         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1620         if (ACPI_FAILURE (Status))
   1621         {
   1622             return (Status);
   1623         }
   1624 
   1625         ParentTable = DtPeekSubtable ();
   1626         DtInsertSubtable (ParentTable, Subtable);
   1627 
   1628         /*
   1629          * Additional GT block subtable data
   1630          */
   1631 
   1632         switch (GtdtHeader->Type)
   1633         {
   1634         case ACPI_GTDT_TYPE_TIMER_BLOCK:
   1635 
   1636             DtPushSubtable (Subtable);
   1637             ParentTable = DtPeekSubtable ();
   1638 
   1639             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
   1640                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
   1641 
   1642             while (GtCount)
   1643             {
   1644                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
   1645                     &Subtable);
   1646                 if (ACPI_FAILURE (Status))
   1647                 {
   1648                     return (Status);
   1649                 }
   1650 
   1651                 DtInsertSubtable (ParentTable, Subtable);
   1652                 GtCount--;
   1653             }
   1654 
   1655             DtPopSubtable ();
   1656             break;
   1657 
   1658         default:
   1659 
   1660             break;
   1661         }
   1662 
   1663         DtPopSubtable ();
   1664     }
   1665 
   1666     return (AE_OK);
   1667 }
   1668 
   1669 
   1670 /******************************************************************************
   1671  *
   1672  * FUNCTION:    DtCompileFpdt
   1673  *
   1674  * PARAMETERS:  List                - Current field list pointer
   1675  *
   1676  * RETURN:      Status
   1677  *
   1678  * DESCRIPTION: Compile FPDT.
   1679  *
   1680  *****************************************************************************/
   1681 
   1682 ACPI_STATUS
   1683 DtCompileFpdt (
   1684     void                    **List)
   1685 {
   1686     ACPI_STATUS             Status;
   1687     ACPI_FPDT_HEADER        *FpdtHeader;
   1688     DT_SUBTABLE             *Subtable;
   1689     DT_SUBTABLE             *ParentTable;
   1690     ACPI_DMTABLE_INFO       *InfoTable;
   1691     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1692     DT_FIELD                *SubtableStart;
   1693 
   1694 
   1695     while (*PFieldList)
   1696     {
   1697         SubtableStart = *PFieldList;
   1698         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
   1699             &Subtable);
   1700         if (ACPI_FAILURE (Status))
   1701         {
   1702             return (Status);
   1703         }
   1704 
   1705         ParentTable = DtPeekSubtable ();
   1706         DtInsertSubtable (ParentTable, Subtable);
   1707         DtPushSubtable (Subtable);
   1708 
   1709         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
   1710 
   1711         switch (FpdtHeader->Type)
   1712         {
   1713         case ACPI_FPDT_TYPE_BOOT:
   1714 
   1715             InfoTable = AcpiDmTableInfoFpdt0;
   1716             break;
   1717 
   1718         case ACPI_FPDT_TYPE_S3PERF:
   1719 
   1720             InfoTable = AcpiDmTableInfoFpdt1;
   1721             break;
   1722 
   1723         default:
   1724 
   1725             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
   1726             return (AE_ERROR);
   1727             break;
   1728         }
   1729 
   1730         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1731         if (ACPI_FAILURE (Status))
   1732         {
   1733             return (Status);
   1734         }
   1735 
   1736         ParentTable = DtPeekSubtable ();
   1737         DtInsertSubtable (ParentTable, Subtable);
   1738         DtPopSubtable ();
   1739     }
   1740 
   1741     return (AE_OK);
   1742 }
   1743 
   1744 
   1745 /******************************************************************************
   1746  *
   1747  * FUNCTION:    DtCompileHest
   1748  *
   1749  * PARAMETERS:  List                - Current field list pointer
   1750  *
   1751  * RETURN:      Status
   1752  *
   1753  * DESCRIPTION: Compile HEST.
   1754  *
   1755  *****************************************************************************/
   1756 
   1757 ACPI_STATUS
   1758 DtCompileHest (
   1759     void                    **List)
   1760 {
   1761     ACPI_STATUS             Status;
   1762     DT_SUBTABLE             *Subtable;
   1763     DT_SUBTABLE             *ParentTable;
   1764     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1765     DT_FIELD                *SubtableStart;
   1766     ACPI_DMTABLE_INFO       *InfoTable;
   1767     UINT16                  Type;
   1768     UINT32                  BankCount;
   1769 
   1770 
   1771     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
   1772         &Subtable);
   1773     if (ACPI_FAILURE (Status))
   1774     {
   1775         return (Status);
   1776     }
   1777 
   1778     ParentTable = DtPeekSubtable ();
   1779     DtInsertSubtable (ParentTable, Subtable);
   1780 
   1781     while (*PFieldList)
   1782     {
   1783         /* Get subtable type */
   1784 
   1785         SubtableStart = *PFieldList;
   1786         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
   1787 
   1788         switch (Type)
   1789         {
   1790         case ACPI_HEST_TYPE_IA32_CHECK:
   1791 
   1792             InfoTable = AcpiDmTableInfoHest0;
   1793             break;
   1794 
   1795         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   1796 
   1797             InfoTable = AcpiDmTableInfoHest1;
   1798             break;
   1799 
   1800         case ACPI_HEST_TYPE_IA32_NMI:
   1801 
   1802             InfoTable = AcpiDmTableInfoHest2;
   1803             break;
   1804 
   1805         case ACPI_HEST_TYPE_AER_ROOT_PORT:
   1806 
   1807             InfoTable = AcpiDmTableInfoHest6;
   1808             break;
   1809 
   1810         case ACPI_HEST_TYPE_AER_ENDPOINT:
   1811 
   1812             InfoTable = AcpiDmTableInfoHest7;
   1813             break;
   1814 
   1815         case ACPI_HEST_TYPE_AER_BRIDGE:
   1816 
   1817             InfoTable = AcpiDmTableInfoHest8;
   1818             break;
   1819 
   1820         case ACPI_HEST_TYPE_GENERIC_ERROR:
   1821 
   1822             InfoTable = AcpiDmTableInfoHest9;
   1823             break;
   1824 
   1825         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
   1826 
   1827             InfoTable = AcpiDmTableInfoHest10;
   1828             break;
   1829 
   1830         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   1831 
   1832             InfoTable = AcpiDmTableInfoHest11;
   1833             break;
   1834 
   1835         default:
   1836 
   1837             /* Cannot continue on unknown type */
   1838 
   1839             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
   1840             return (AE_ERROR);
   1841         }
   1842 
   1843         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1844         if (ACPI_FAILURE (Status))
   1845         {
   1846             return (Status);
   1847         }
   1848 
   1849         DtInsertSubtable (ParentTable, Subtable);
   1850 
   1851         /*
   1852          * Additional subtable data - IA32 Error Bank(s)
   1853          */
   1854         BankCount = 0;
   1855         switch (Type)
   1856         {
   1857         case ACPI_HEST_TYPE_IA32_CHECK:
   1858 
   1859             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
   1860                 Subtable->Buffer))->NumHardwareBanks;
   1861             break;
   1862 
   1863         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   1864 
   1865             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
   1866                 Subtable->Buffer))->NumHardwareBanks;
   1867             break;
   1868 
   1869         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   1870 
   1871             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
   1872                 Subtable->Buffer))->NumHardwareBanks;
   1873             break;
   1874 
   1875         default:
   1876 
   1877             break;
   1878         }
   1879 
   1880         while (BankCount)
   1881         {
   1882             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
   1883                 &Subtable);
   1884             if (ACPI_FAILURE (Status))
   1885             {
   1886                 return (Status);
   1887             }
   1888 
   1889             DtInsertSubtable (ParentTable, Subtable);
   1890             BankCount--;
   1891         }
   1892     }
   1893 
   1894     return (AE_OK);
   1895 }
   1896 
   1897 
   1898 /******************************************************************************
   1899  *
   1900  * FUNCTION:    DtCompileHmat
   1901  *
   1902  * PARAMETERS:  List                - Current field list pointer
   1903  *
   1904  * RETURN:      Status
   1905  *
   1906  * DESCRIPTION: Compile HMAT.
   1907  *
   1908  *****************************************************************************/
   1909 
   1910 ACPI_STATUS
   1911 DtCompileHmat (
   1912     void                    **List)
   1913 {
   1914     ACPI_STATUS             Status;
   1915     DT_SUBTABLE             *Subtable;
   1916     DT_SUBTABLE             *ParentTable;
   1917     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1918     DT_FIELD                *SubtableStart;
   1919     DT_FIELD                *EntryStart;
   1920     ACPI_HMAT_STRUCTURE     *HmatStruct;
   1921     ACPI_HMAT_LOCALITY      *HmatLocality;
   1922     ACPI_HMAT_CACHE         *HmatCache;
   1923     ACPI_DMTABLE_INFO       *InfoTable;
   1924     UINT32                  IntPDNumber;
   1925     UINT32                  TgtPDNumber;
   1926     UINT64                  EntryNumber;
   1927     UINT16                  SMBIOSHandleNumber;
   1928 
   1929 
   1930     ParentTable = DtPeekSubtable ();
   1931 
   1932     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
   1933         &Subtable);
   1934     if (ACPI_FAILURE (Status))
   1935     {
   1936         return (Status);
   1937     }
   1938     DtInsertSubtable (ParentTable, Subtable);
   1939 
   1940     while (*PFieldList)
   1941     {
   1942         /* Compile HMAT structure header */
   1943 
   1944         SubtableStart = *PFieldList;
   1945         Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
   1946             &Subtable);
   1947         if (ACPI_FAILURE (Status))
   1948         {
   1949             return (Status);
   1950         }
   1951         DtInsertSubtable (ParentTable, Subtable);
   1952 
   1953         HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
   1954         HmatStruct->Length = Subtable->Length;
   1955 
   1956         /* Compile HMAT structure body */
   1957 
   1958         switch (HmatStruct->Type)
   1959         {
   1960         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
   1961 
   1962             InfoTable = AcpiDmTableInfoHmat0;
   1963             break;
   1964 
   1965         case ACPI_HMAT_TYPE_LOCALITY:
   1966 
   1967             InfoTable = AcpiDmTableInfoHmat1;
   1968             break;
   1969 
   1970         case ACPI_HMAT_TYPE_CACHE:
   1971 
   1972             InfoTable = AcpiDmTableInfoHmat2;
   1973             break;
   1974 
   1975         default:
   1976 
   1977             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
   1978             return (AE_ERROR);
   1979         }
   1980 
   1981         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1982         if (ACPI_FAILURE (Status))
   1983         {
   1984             return (Status);
   1985         }
   1986         DtInsertSubtable (ParentTable, Subtable);
   1987         HmatStruct->Length += Subtable->Length;
   1988 
   1989         /* Compile HMAT structure additional */
   1990 
   1991         switch (HmatStruct->Type)
   1992         {
   1993         case ACPI_HMAT_TYPE_LOCALITY:
   1994 
   1995             HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
   1996                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   1997 
   1998             /* Compile initiator proximity domain list */
   1999 
   2000             IntPDNumber = 0;
   2001             while (*PFieldList)
   2002             {
   2003                 Status = DtCompileTable (PFieldList,
   2004                     AcpiDmTableInfoHmat1a, &Subtable);
   2005                 if (ACPI_FAILURE (Status))
   2006                 {
   2007                     return (Status);
   2008                 }
   2009                 if (!Subtable)
   2010                 {
   2011                     break;
   2012                 }
   2013                 DtInsertSubtable (ParentTable, Subtable);
   2014                 HmatStruct->Length += Subtable->Length;
   2015                 IntPDNumber++;
   2016             }
   2017             HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
   2018 
   2019             /* Compile target proximity domain list */
   2020 
   2021             TgtPDNumber = 0;
   2022             while (*PFieldList)
   2023             {
   2024                 Status = DtCompileTable (PFieldList,
   2025                     AcpiDmTableInfoHmat1b, &Subtable);
   2026                 if (ACPI_FAILURE (Status))
   2027                 {
   2028                     return (Status);
   2029                 }
   2030                 if (!Subtable)
   2031                 {
   2032                     break;
   2033                 }
   2034                 DtInsertSubtable (ParentTable, Subtable);
   2035                 HmatStruct->Length += Subtable->Length;
   2036                 TgtPDNumber++;
   2037             }
   2038             HmatLocality->NumberOfTargetPDs = TgtPDNumber;
   2039 
   2040             /* Save start of the entries for reporting errors */
   2041 
   2042             EntryStart = *PFieldList;
   2043 
   2044             /* Compile latency/bandwidth entries */
   2045 
   2046             EntryNumber = 0;
   2047             while (*PFieldList)
   2048             {
   2049                 Status = DtCompileTable (PFieldList,
   2050                     AcpiDmTableInfoHmat1c, &Subtable);
   2051                 if (ACPI_FAILURE (Status))
   2052                 {
   2053                     return (Status);
   2054                 }
   2055                 if (!Subtable)
   2056                 {
   2057                     break;
   2058                 }
   2059                 DtInsertSubtable (ParentTable, Subtable);
   2060                 HmatStruct->Length += Subtable->Length;
   2061                 EntryNumber++;
   2062             }
   2063 
   2064             /* Validate number of entries */
   2065 
   2066             if (EntryNumber !=
   2067                 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
   2068             {
   2069                 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
   2070                 return (AE_ERROR);
   2071             }
   2072             break;
   2073 
   2074         case ACPI_HMAT_TYPE_CACHE:
   2075 
   2076             /* Compile SMBIOS handles */
   2077 
   2078             HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
   2079                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   2080             SMBIOSHandleNumber = 0;
   2081             while (*PFieldList)
   2082             {
   2083                 Status = DtCompileTable (PFieldList,
   2084                     AcpiDmTableInfoHmat2a, &Subtable);
   2085                 if (ACPI_FAILURE (Status))
   2086                 {
   2087                     return (Status);
   2088                 }
   2089                 if (!Subtable)
   2090                 {
   2091                     break;
   2092                 }
   2093                 DtInsertSubtable (ParentTable, Subtable);
   2094                 HmatStruct->Length += Subtable->Length;
   2095                 SMBIOSHandleNumber++;
   2096             }
   2097             HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
   2098             break;
   2099 
   2100         default:
   2101 
   2102             break;
   2103         }
   2104     }
   2105 
   2106     return (AE_OK);
   2107 }
   2108 
   2109 
   2110 /******************************************************************************
   2111  *
   2112  * FUNCTION:    DtCompileIort
   2113  *
   2114  * PARAMETERS:  List                - Current field list pointer
   2115  *
   2116  * RETURN:      Status
   2117  *
   2118  * DESCRIPTION: Compile IORT.
   2119  *
   2120  *****************************************************************************/
   2121 
   2122 ACPI_STATUS
   2123 DtCompileIort (
   2124     void                    **List)
   2125 {
   2126     ACPI_STATUS             Status;
   2127     DT_SUBTABLE             *Subtable;
   2128     DT_SUBTABLE             *ParentTable;
   2129     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2130     DT_FIELD                *SubtableStart;
   2131     ACPI_TABLE_HEADER       *Table;
   2132     ACPI_TABLE_IORT         *Iort;
   2133     ACPI_IORT_NODE          *IortNode;
   2134     ACPI_IORT_ITS_GROUP     *IortItsGroup;
   2135     ACPI_IORT_SMMU          *IortSmmu;
   2136     ACPI_IORT_RMR           *IortRmr;
   2137     UINT32                  NodeNumber;
   2138     UINT32                  NodeLength;
   2139     UINT32                  IdMappingNumber;
   2140     UINT32                  ItsNumber;
   2141     UINT32                  ContextIrptNumber;
   2142     UINT32                  PmuIrptNumber;
   2143     UINT32                  PaddingLength;
   2144     UINT8                   Revision;
   2145     UINT32                  RmrCount;
   2146 
   2147 
   2148     ParentTable = DtPeekSubtable ();
   2149 
   2150     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
   2151         &Subtable);
   2152     if (ACPI_FAILURE (Status))
   2153     {
   2154         return (Status);
   2155     }
   2156     DtInsertSubtable (ParentTable, Subtable);
   2157 
   2158     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   2159     Revision = Table->Revision;
   2160 
   2161     /* IORT Revisions E, E.a & E.c have known issues and are not supported */
   2162 
   2163     if (Revision == 1 || Revision == 2 || Revision == 4)
   2164     {
   2165         DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision");
   2166         return (AE_ERROR);
   2167     }
   2168 
   2169     /*
   2170      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   2171      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
   2172      */
   2173     Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
   2174         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
   2175 
   2176     /*
   2177      * OptionalPadding - Variable-length data
   2178      * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
   2179      * Optionally allows the generic data types to be used for filling
   2180      * this field.
   2181      */
   2182     Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
   2183     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
   2184         &Subtable);
   2185     if (ACPI_FAILURE (Status))
   2186     {
   2187         return (Status);
   2188     }
   2189     if (Subtable)
   2190     {
   2191         DtInsertSubtable (ParentTable, Subtable);
   2192         Iort->NodeOffset += Subtable->Length;
   2193     }
   2194     else
   2195     {
   2196         Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
   2197             AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
   2198         if (ACPI_FAILURE (Status))
   2199         {
   2200             return (Status);
   2201         }
   2202         Iort->NodeOffset += PaddingLength;
   2203     }
   2204 
   2205     NodeNumber = 0;
   2206     while (*PFieldList)
   2207     {
   2208         SubtableStart = *PFieldList;
   2209         if (Revision == 0)
   2210         {
   2211             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
   2212                 &Subtable);
   2213         }
   2214         else if (Revision >= 3)
   2215         {
   2216             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3,
   2217                 &Subtable);
   2218         }
   2219 
   2220         if (ACPI_FAILURE (Status))
   2221         {
   2222             return (Status);
   2223         }
   2224 
   2225         DtInsertSubtable (ParentTable, Subtable);
   2226         IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
   2227         NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
   2228 
   2229         DtPushSubtable (Subtable);
   2230         ParentTable = DtPeekSubtable ();
   2231 
   2232         switch (IortNode->Type)
   2233         {
   2234         case ACPI_IORT_NODE_ITS_GROUP:
   2235 
   2236             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
   2237                 &Subtable);
   2238             if (ACPI_FAILURE (Status))
   2239             {
   2240                 return (Status);
   2241             }
   2242 
   2243             DtInsertSubtable (ParentTable, Subtable);
   2244             IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
   2245             NodeLength += Subtable->Length;
   2246 
   2247             ItsNumber = 0;
   2248             while (*PFieldList)
   2249             {
   2250                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
   2251                     &Subtable);
   2252                 if (ACPI_FAILURE (Status))
   2253                 {
   2254                     return (Status);
   2255                 }
   2256                 if (!Subtable)
   2257                 {
   2258                     break;
   2259                 }
   2260 
   2261                 DtInsertSubtable (ParentTable, Subtable);
   2262                 NodeLength += Subtable->Length;
   2263                 ItsNumber++;
   2264             }
   2265 
   2266             IortItsGroup->ItsCount = ItsNumber;
   2267             break;
   2268 
   2269         case ACPI_IORT_NODE_NAMED_COMPONENT:
   2270 
   2271             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
   2272                 &Subtable);
   2273             if (ACPI_FAILURE (Status))
   2274             {
   2275                 return (Status);
   2276             }
   2277 
   2278             DtInsertSubtable (ParentTable, Subtable);
   2279             NodeLength += Subtable->Length;
   2280 
   2281             /*
   2282              * Padding - Variable-length data
   2283              * Optionally allows the offset of the ID mappings to be used
   2284              * for filling this field.
   2285              */
   2286             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
   2287                 &Subtable);
   2288             if (ACPI_FAILURE (Status))
   2289             {
   2290                 return (Status);
   2291             }
   2292 
   2293             if (Subtable)
   2294             {
   2295                 DtInsertSubtable (ParentTable, Subtable);
   2296                 NodeLength += Subtable->Length;
   2297             }
   2298             else
   2299             {
   2300                 if (NodeLength > IortNode->MappingOffset)
   2301                 {
   2302                     return (AE_BAD_DATA);
   2303                 }
   2304 
   2305                 if (NodeLength < IortNode->MappingOffset)
   2306                 {
   2307                     Status = DtCompilePadding (
   2308                         IortNode->MappingOffset - NodeLength,
   2309                         &Subtable);
   2310                     if (ACPI_FAILURE (Status))
   2311                     {
   2312                         return (Status);
   2313                     }
   2314 
   2315                     DtInsertSubtable (ParentTable, Subtable);
   2316                     NodeLength = IortNode->MappingOffset;
   2317                 }
   2318             }
   2319             break;
   2320 
   2321         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
   2322 
   2323             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
   2324                 &Subtable);
   2325             if (ACPI_FAILURE (Status))
   2326             {
   2327                 return (Status);
   2328             }
   2329 
   2330             DtInsertSubtable (ParentTable, Subtable);
   2331             NodeLength += Subtable->Length;
   2332             break;
   2333 
   2334         case ACPI_IORT_NODE_SMMU:
   2335 
   2336             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
   2337                 &Subtable);
   2338             if (ACPI_FAILURE (Status))
   2339             {
   2340                 return (Status);
   2341             }
   2342 
   2343             DtInsertSubtable (ParentTable, Subtable);
   2344             IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
   2345             NodeLength += Subtable->Length;
   2346 
   2347             /* Compile global interrupt array */
   2348 
   2349             IortSmmu->GlobalInterruptOffset = NodeLength;
   2350             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
   2351                 &Subtable);
   2352             if (ACPI_FAILURE (Status))
   2353             {
   2354                 return (Status);
   2355             }
   2356 
   2357             DtInsertSubtable (ParentTable, Subtable);
   2358             NodeLength += Subtable->Length;
   2359 
   2360             /* Compile context interrupt array */
   2361 
   2362             ContextIrptNumber = 0;
   2363             IortSmmu->ContextInterruptOffset = NodeLength;
   2364             while (*PFieldList)
   2365             {
   2366                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
   2367                     &Subtable);
   2368                 if (ACPI_FAILURE (Status))
   2369                 {
   2370                     return (Status);
   2371                 }
   2372 
   2373                 if (!Subtable)
   2374                 {
   2375                     break;
   2376                 }
   2377 
   2378                 DtInsertSubtable (ParentTable, Subtable);
   2379                 NodeLength += Subtable->Length;
   2380                 ContextIrptNumber++;
   2381             }
   2382 
   2383             IortSmmu->ContextInterruptCount = ContextIrptNumber;
   2384 
   2385             /* Compile PMU interrupt array */
   2386 
   2387             PmuIrptNumber = 0;
   2388             IortSmmu->PmuInterruptOffset = NodeLength;
   2389             while (*PFieldList)
   2390             {
   2391                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
   2392                     &Subtable);
   2393                 if (ACPI_FAILURE (Status))
   2394                 {
   2395                     return (Status);
   2396                 }
   2397 
   2398                 if (!Subtable)
   2399                 {
   2400                     break;
   2401                 }
   2402 
   2403                 DtInsertSubtable (ParentTable, Subtable);
   2404                 NodeLength += Subtable->Length;
   2405                 PmuIrptNumber++;
   2406             }
   2407 
   2408             IortSmmu->PmuInterruptCount = PmuIrptNumber;
   2409             break;
   2410 
   2411         case ACPI_IORT_NODE_SMMU_V3:
   2412 
   2413             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
   2414                 &Subtable);
   2415             if (ACPI_FAILURE (Status))
   2416             {
   2417                 return (Status);
   2418             }
   2419 
   2420             DtInsertSubtable (ParentTable, Subtable);
   2421             NodeLength += Subtable->Length;
   2422             break;
   2423 
   2424         case ACPI_IORT_NODE_PMCG:
   2425 
   2426             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
   2427                 &Subtable);
   2428             if (ACPI_FAILURE (Status))
   2429             {
   2430                 return (Status);
   2431             }
   2432 
   2433             DtInsertSubtable (ParentTable, Subtable);
   2434             NodeLength += Subtable->Length;
   2435             break;
   2436 
   2437         case ACPI_IORT_NODE_RMR:
   2438 
   2439             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6,
   2440                 &Subtable);
   2441             if (ACPI_FAILURE (Status))
   2442             {
   2443                 return (Status);
   2444             }
   2445 
   2446             DtInsertSubtable (ParentTable, Subtable);
   2447             IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer);
   2448             NodeLength += Subtable->Length;
   2449 
   2450             /* Compile RMR Descriptors */
   2451 
   2452             RmrCount = 0;
   2453             IortRmr->RmrOffset = NodeLength;
   2454             while (*PFieldList)
   2455             {
   2456                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a,
   2457                     &Subtable);
   2458                 if (ACPI_FAILURE (Status))
   2459                 {
   2460                     return (Status);
   2461                 }
   2462 
   2463                 if (!Subtable)
   2464                 {
   2465                     break;
   2466                 }
   2467 
   2468                 DtInsertSubtable (ParentTable, Subtable);
   2469                 NodeLength += sizeof (ACPI_IORT_RMR_DESC);
   2470                 RmrCount++;
   2471             }
   2472 
   2473             IortRmr->RmrCount = RmrCount;
   2474             break;
   2475 
   2476         default:
   2477 
   2478             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
   2479             return (AE_ERROR);
   2480         }
   2481 
   2482         /* Compile Array of ID mappings */
   2483 
   2484         IortNode->MappingOffset = NodeLength;
   2485         IdMappingNumber = 0;
   2486         while (*PFieldList)
   2487         {
   2488             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
   2489                 &Subtable);
   2490             if (ACPI_FAILURE (Status))
   2491             {
   2492                 return (Status);
   2493             }
   2494 
   2495             if (!Subtable)
   2496             {
   2497                 break;
   2498             }
   2499 
   2500             DtInsertSubtable (ParentTable, Subtable);
   2501             NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
   2502             IdMappingNumber++;
   2503         }
   2504 
   2505         IortNode->MappingCount = IdMappingNumber;
   2506         if (!IdMappingNumber)
   2507         {
   2508             IortNode->MappingOffset = 0;
   2509         }
   2510 
   2511         /*
   2512          * Node length can be determined by DT_LENGTH option
   2513          * IortNode->Length = NodeLength;
   2514          */
   2515         DtPopSubtable ();
   2516         ParentTable = DtPeekSubtable ();
   2517         NodeNumber++;
   2518     }
   2519 
   2520     Iort->NodeCount = NodeNumber;
   2521     return (AE_OK);
   2522 }
   2523 
   2524 
   2525 /******************************************************************************
   2526  *
   2527  * FUNCTION:    DtCompileIvrs
   2528  *
   2529  * PARAMETERS:  List                - Current field list pointer
   2530  *
   2531  * RETURN:      Status
   2532  *
   2533  * DESCRIPTION: Compile IVRS. Notes:
   2534  *              The IVRS is essentially a flat table, with the following
   2535  *              structure:
   2536  *              <Main ACPI Table Header>
   2537  *              <Main subtable - virtualization info>
   2538  *              <IVHD>
   2539  *                  <Device Entries>
   2540  *              ...
   2541  *              <IVHD>
   2542  *                  <Device Entries>
   2543  *              <IVMD>
   2544  *              ...
   2545  *
   2546  *****************************************************************************/
   2547 
   2548 ACPI_STATUS
   2549 DtCompileIvrs (
   2550     void                    **List)
   2551 {
   2552     ACPI_STATUS             Status;
   2553     DT_SUBTABLE             *Subtable;
   2554     DT_SUBTABLE             *ParentTable;
   2555     DT_SUBTABLE             *MainSubtable;
   2556     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2557     DT_FIELD                *SubtableStart;
   2558     ACPI_DMTABLE_INFO       *InfoTable = NULL;
   2559     UINT8                   SubtableType;
   2560     UINT8                   Temp64[16];
   2561     UINT8                   Temp8;
   2562 
   2563 
   2564     /* Main table */
   2565 
   2566     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
   2567         &Subtable);
   2568     if (ACPI_FAILURE (Status))
   2569     {
   2570         return (Status);
   2571     }
   2572 
   2573     ParentTable = DtPeekSubtable ();
   2574     DtInsertSubtable (ParentTable, Subtable);
   2575     DtPushSubtable (Subtable);
   2576 
   2577     /* Save a pointer to the main subtable */
   2578 
   2579     MainSubtable = Subtable;
   2580 
   2581     while (*PFieldList)
   2582     {
   2583         SubtableStart = *PFieldList;
   2584 
   2585         /* Compile the SubtableType integer */
   2586 
   2587         DtCompileInteger (&SubtableType, *PFieldList, 1, 0);
   2588 
   2589         switch (SubtableType)
   2590         {
   2591 
   2592         /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */
   2593 
   2594         case ACPI_IVRS_TYPE_HARDWARE1:
   2595 
   2596             InfoTable = AcpiDmTableInfoIvrsHware1;
   2597             break;
   2598 
   2599         /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */
   2600 
   2601         case ACPI_IVRS_TYPE_HARDWARE2:
   2602         case ACPI_IVRS_TYPE_HARDWARE3:
   2603 
   2604             InfoTable = AcpiDmTableInfoIvrsHware23;
   2605             break;
   2606 
   2607         /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */
   2608 
   2609         case ACPI_IVRS_TYPE_MEMORY1:
   2610         case ACPI_IVRS_TYPE_MEMORY2:
   2611         case ACPI_IVRS_TYPE_MEMORY3:
   2612 
   2613             InfoTable = AcpiDmTableInfoIvrsMemory;
   2614             break;
   2615 
   2616         /* 4-byte device entries */
   2617 
   2618         case ACPI_IVRS_TYPE_PAD4:
   2619         case ACPI_IVRS_TYPE_ALL:
   2620         case ACPI_IVRS_TYPE_SELECT:
   2621         case ACPI_IVRS_TYPE_START:
   2622         case ACPI_IVRS_TYPE_END:
   2623 
   2624             InfoTable = AcpiDmTableInfoIvrs4;
   2625             break;
   2626 
   2627         /* 8-byte device entries, type A */
   2628 
   2629         case ACPI_IVRS_TYPE_ALIAS_SELECT:
   2630         case ACPI_IVRS_TYPE_ALIAS_START:
   2631 
   2632             InfoTable = AcpiDmTableInfoIvrs8a;
   2633             break;
   2634 
   2635         /* 8-byte device entries, type B */
   2636 
   2637         case ACPI_IVRS_TYPE_EXT_SELECT:
   2638         case ACPI_IVRS_TYPE_EXT_START:
   2639 
   2640             InfoTable = AcpiDmTableInfoIvrs8b;
   2641             break;
   2642 
   2643         /* 8-byte device entries, type C */
   2644 
   2645         case ACPI_IVRS_TYPE_SPECIAL:
   2646 
   2647             InfoTable = AcpiDmTableInfoIvrs8c;
   2648             break;
   2649 
   2650         /* Variable device entries, type F0h */
   2651 
   2652         case ACPI_IVRS_TYPE_HID:
   2653 
   2654             InfoTable = AcpiDmTableInfoIvrsHid;
   2655             break;
   2656 
   2657         default:
   2658 
   2659             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
   2660                 "IVRS Device Entry");
   2661             return (AE_ERROR);
   2662         }
   2663 
   2664         /* Compile the InfoTable from above */
   2665 
   2666         Status = DtCompileTable (PFieldList, InfoTable,
   2667             &Subtable);
   2668         if (ACPI_FAILURE (Status))
   2669         {
   2670             return (Status);
   2671         }
   2672 
   2673         ParentTable = DtPeekSubtable ();
   2674         if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 &&
   2675             SubtableType != ACPI_IVRS_TYPE_HARDWARE2 &&
   2676             SubtableType != ACPI_IVRS_TYPE_HARDWARE3 &&
   2677             SubtableType != ACPI_IVRS_TYPE_HID &&
   2678             SubtableType != ACPI_IVRS_TYPE_MEMORY1 &&
   2679             SubtableType != ACPI_IVRS_TYPE_MEMORY2 &&
   2680             SubtableType != ACPI_IVRS_TYPE_MEMORY3)
   2681         {
   2682             if (ParentTable)
   2683                 DtInsertSubtable (ParentTable, Subtable);
   2684         }
   2685 
   2686         switch (SubtableType)
   2687         {
   2688         case ACPI_IVRS_TYPE_HARDWARE1:
   2689         case ACPI_IVRS_TYPE_HARDWARE2:
   2690         case ACPI_IVRS_TYPE_HARDWARE3:
   2691         case ACPI_IVRS_TYPE_MEMORY1:
   2692         case ACPI_IVRS_TYPE_MEMORY2:
   2693         case ACPI_IVRS_TYPE_MEMORY3:
   2694 
   2695             /* Insert these IVHDs/IVMDs at the root subtable */
   2696 
   2697             DtInsertSubtable (MainSubtable, Subtable);
   2698             DtPushSubtable (Subtable);
   2699             break;
   2700 
   2701         case ACPI_IVRS_TYPE_HID:
   2702 
   2703             /* Special handling for the HID named device entry (0xF0) */
   2704 
   2705             if (ParentTable)
   2706             {
   2707                 DtInsertSubtable (ParentTable, Subtable);
   2708             }
   2709 
   2710             /*
   2711              * Process the HID value. First, get the HID value as a string.
   2712              */
   2713             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
   2714 
   2715                /*
   2716                 * Determine if the HID is an integer or a string.
   2717                 * An integer is defined to be 32 bits, with the upper 32 bits
   2718                 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit
   2719                 * integer or a character string. If an integer, the lower
   2720                 * 4 bytes of the field contain the integer and the upper
   2721                 * 4 bytes are padded with 0".
   2722                 */
   2723             if (UtIsIdInteger ((UINT8 *) &Temp64))
   2724             {
   2725                 /* Compile the HID value as an integer */
   2726 
   2727                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
   2728 
   2729                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger,
   2730                     &Subtable);
   2731                 if (ACPI_FAILURE (Status))
   2732                 {
   2733                     return (Status);
   2734                 }
   2735             }
   2736             else
   2737             {
   2738                 /* Compile the HID value as a string */
   2739 
   2740                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString,
   2741                     &Subtable);
   2742                 if (ACPI_FAILURE (Status))
   2743                 {
   2744                     return (Status);
   2745                 }
   2746             }
   2747 
   2748             DtInsertSubtable (ParentTable, Subtable);
   2749 
   2750             /*
   2751              * Process the CID value. First, get the CID value as a string.
   2752              */
   2753             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
   2754 
   2755             if (UtIsIdInteger ((UINT8 *) &Temp64))
   2756             {
   2757                 /* Compile the CID value as an integer */
   2758 
   2759                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
   2760 
   2761                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger,
   2762                     &Subtable);
   2763                 if (ACPI_FAILURE (Status))
   2764                 {
   2765                     return (Status);
   2766                 }
   2767             }
   2768             else
   2769             {
   2770                 /* Compile the CID value as a string */
   2771 
   2772                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString,
   2773                     &Subtable);
   2774                 if (ACPI_FAILURE (Status))
   2775                 {
   2776                     return (Status);
   2777                 }
   2778             }
   2779 
   2780             DtInsertSubtable (ParentTable, Subtable);
   2781 
   2782             /*
   2783              * Process the UID value. First, get and decode the "UID Format" field (Integer).
   2784              */
   2785             if (!*PFieldList)
   2786             {
   2787                 return (AE_OK);
   2788             }
   2789 
   2790             DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0);
   2791 
   2792             switch (Temp8)
   2793             {
   2794             case ACPI_IVRS_UID_NOT_PRESENT:
   2795                 break;
   2796 
   2797             case ACPI_IVRS_UID_IS_INTEGER:
   2798 
   2799                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger,
   2800                     &Subtable);
   2801                 if (ACPI_FAILURE (Status))
   2802                 {
   2803                     return (Status);
   2804                 }
   2805                 DtInsertSubtable (ParentTable, Subtable);
   2806                 break;
   2807 
   2808             case ACPI_IVRS_UID_IS_STRING:
   2809 
   2810                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString,
   2811                     &Subtable);
   2812                 if (ACPI_FAILURE (Status))
   2813                 {
   2814                     return (Status);
   2815                 }
   2816                 DtInsertSubtable (ParentTable, Subtable);
   2817                 break;
   2818 
   2819             default:
   2820 
   2821                 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart,
   2822                     "IVRS Device Entry");
   2823                 return (AE_ERROR);
   2824             }
   2825 
   2826         default:
   2827 
   2828             /* All other subtable types come through here */
   2829             break;
   2830         }
   2831     }
   2832 
   2833     return (AE_OK);
   2834 }
   2835