Home | History | Annotate | Line # | Download | only in compiler
dttable1.c revision 1.1.1.13
      1 /******************************************************************************
      2  *
      3  * Module Name: dttable1.c - handling for specific ACPI tables
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2021, 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:    DtCompileAsf
    285  *
    286  * PARAMETERS:  List                - Current field list pointer
    287  *
    288  * RETURN:      Status
    289  *
    290  * DESCRIPTION: Compile ASF!.
    291  *
    292  *****************************************************************************/
    293 
    294 ACPI_STATUS
    295 DtCompileAsf (
    296     void                    **List)
    297 {
    298     ACPI_ASF_INFO           *AsfTable;
    299     DT_SUBTABLE             *Subtable;
    300     DT_SUBTABLE             *ParentTable;
    301     ACPI_DMTABLE_INFO       *InfoTable;
    302     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
    303     UINT32                  DataCount = 0;
    304     ACPI_STATUS             Status;
    305     UINT32                  i;
    306     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    307     DT_FIELD                *SubtableStart;
    308 
    309 
    310     while (*PFieldList)
    311     {
    312         SubtableStart = *PFieldList;
    313         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
    314             &Subtable);
    315         if (ACPI_FAILURE (Status))
    316         {
    317             return (Status);
    318         }
    319 
    320         ParentTable = DtPeekSubtable ();
    321         DtInsertSubtable (ParentTable, Subtable);
    322         DtPushSubtable (Subtable);
    323 
    324         AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
    325 
    326         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
    327         {
    328         case ACPI_ASF_TYPE_INFO:
    329 
    330             InfoTable = AcpiDmTableInfoAsf0;
    331             break;
    332 
    333         case ACPI_ASF_TYPE_ALERT:
    334 
    335             InfoTable = AcpiDmTableInfoAsf1;
    336             break;
    337 
    338         case ACPI_ASF_TYPE_CONTROL:
    339 
    340             InfoTable = AcpiDmTableInfoAsf2;
    341             break;
    342 
    343         case ACPI_ASF_TYPE_BOOT:
    344 
    345             InfoTable = AcpiDmTableInfoAsf3;
    346             break;
    347 
    348         case ACPI_ASF_TYPE_ADDRESS:
    349 
    350             InfoTable = AcpiDmTableInfoAsf4;
    351             break;
    352 
    353         default:
    354 
    355             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
    356             return (AE_ERROR);
    357         }
    358 
    359         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    360         if (ACPI_FAILURE (Status))
    361         {
    362             return (Status);
    363         }
    364 
    365         ParentTable = DtPeekSubtable ();
    366         DtInsertSubtable (ParentTable, Subtable);
    367 
    368         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
    369         {
    370         case ACPI_ASF_TYPE_INFO:
    371 
    372             DataInfoTable = NULL;
    373             break;
    374 
    375         case ACPI_ASF_TYPE_ALERT:
    376 
    377             DataInfoTable = AcpiDmTableInfoAsf1a;
    378             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
    379                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
    380                     sizeof (ACPI_ASF_HEADER)))->Alerts;
    381             break;
    382 
    383         case ACPI_ASF_TYPE_CONTROL:
    384 
    385             DataInfoTable = AcpiDmTableInfoAsf2a;
    386             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
    387                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
    388                     sizeof (ACPI_ASF_HEADER)))->Controls;
    389             break;
    390 
    391         case ACPI_ASF_TYPE_BOOT:
    392 
    393             DataInfoTable = NULL;
    394             break;
    395 
    396         case ACPI_ASF_TYPE_ADDRESS:
    397 
    398             DataInfoTable = TableInfoAsfAddress;
    399             DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
    400                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
    401                     sizeof (ACPI_ASF_HEADER)))->Devices;
    402             break;
    403 
    404         default:
    405 
    406             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
    407             return (AE_ERROR);
    408         }
    409 
    410         if (DataInfoTable)
    411         {
    412             switch (AsfTable->Header.Type & 0x7F)
    413             {
    414             case ACPI_ASF_TYPE_ADDRESS:
    415 
    416                 while (DataCount > 0)
    417                 {
    418                     Status = DtCompileTable (PFieldList, DataInfoTable,
    419                         &Subtable);
    420                     if (ACPI_FAILURE (Status))
    421                     {
    422                         return (Status);
    423                     }
    424 
    425                     DtInsertSubtable (ParentTable, Subtable);
    426                     DataCount = DataCount - Subtable->Length;
    427                 }
    428                 break;
    429 
    430             default:
    431 
    432                 for (i = 0; i < DataCount; i++)
    433                 {
    434                     Status = DtCompileTable (PFieldList, DataInfoTable,
    435                         &Subtable);
    436                     if (ACPI_FAILURE (Status))
    437                     {
    438                         return (Status);
    439                     }
    440 
    441                     DtInsertSubtable (ParentTable, Subtable);
    442                 }
    443                 break;
    444             }
    445         }
    446 
    447         DtPopSubtable ();
    448     }
    449 
    450     return (AE_OK);
    451 }
    452 
    453 
    454 /******************************************************************************
    455  *
    456  * FUNCTION:    DtCompileCedt
    457  *
    458  * PARAMETERS:  List                - Current field list pointer
    459  *
    460  * RETURN:      Status
    461  *
    462  * DESCRIPTION: Compile CEDT.
    463  *
    464  *****************************************************************************/
    465 
    466 ACPI_STATUS
    467 DtCompileCedt (
    468     void                    **List)
    469 {
    470     ACPI_STATUS             Status;
    471     DT_SUBTABLE             *Subtable;
    472     DT_SUBTABLE             *ParentTable;
    473     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    474     ACPI_CEDT_HEADER        *CedtHeader;
    475     DT_FIELD                *SubtableStart;
    476 
    477 
    478     /* Walk the parse tree */
    479 
    480     while (*PFieldList)
    481     {
    482         SubtableStart = *PFieldList;
    483 
    484         /* CEDT Header */
    485 
    486         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedtHdr,
    487             &Subtable);
    488         if (ACPI_FAILURE (Status))
    489         {
    490             return (Status);
    491         }
    492 
    493         ParentTable = DtPeekSubtable ();
    494         DtInsertSubtable (ParentTable, Subtable);
    495         DtPushSubtable (Subtable);
    496 
    497         CedtHeader = ACPI_CAST_PTR (ACPI_CEDT_HEADER, Subtable->Buffer);
    498 
    499         switch (CedtHeader->Type)
    500         {
    501         case ACPI_CEDT_TYPE_CHBS:
    502 
    503             break;
    504 
    505         default:
    506 
    507             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "CEDT");
    508             return (AE_ERROR);
    509         }
    510 
    511         /* CEDT Subtable */
    512 
    513         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCedt0, &Subtable);
    514         if (ACPI_FAILURE (Status))
    515         {
    516             return (Status);
    517         }
    518 
    519         ParentTable = DtPeekSubtable ();
    520         DtInsertSubtable (ParentTable, Subtable);
    521         DtPopSubtable ();
    522     }
    523 
    524     return (AE_OK);
    525 }
    526 
    527 
    528 /******************************************************************************
    529  *
    530  * FUNCTION:    DtCompileCpep
    531  *
    532  * PARAMETERS:  List                - Current field list pointer
    533  *
    534  * RETURN:      Status
    535  *
    536  * DESCRIPTION: Compile CPEP.
    537  *
    538  *****************************************************************************/
    539 
    540 ACPI_STATUS
    541 DtCompileCpep (
    542     void                    **List)
    543 {
    544     ACPI_STATUS             Status;
    545 
    546 
    547     Status = DtCompileTwoSubtables (List,
    548         AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
    549     return (Status);
    550 }
    551 
    552 
    553 /******************************************************************************
    554  *
    555  * FUNCTION:    DtCompileCsrt
    556  *
    557  * PARAMETERS:  List                - Current field list pointer
    558  *
    559  * RETURN:      Status
    560  *
    561  * DESCRIPTION: Compile CSRT.
    562  *
    563  *****************************************************************************/
    564 
    565 ACPI_STATUS
    566 DtCompileCsrt (
    567     void                    **List)
    568 {
    569     ACPI_STATUS             Status = AE_OK;
    570     DT_SUBTABLE             *Subtable;
    571     DT_SUBTABLE             *ParentTable;
    572     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    573     UINT32                  DescriptorCount;
    574     UINT32                  GroupLength;
    575 
    576 
    577     /* Subtables (Resource Groups) */
    578 
    579     ParentTable = DtPeekSubtable ();
    580     while (*PFieldList)
    581     {
    582         /* Resource group subtable */
    583 
    584         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
    585             &Subtable);
    586         if (ACPI_FAILURE (Status))
    587         {
    588             return (Status);
    589         }
    590 
    591         /* Compute the number of resource descriptors */
    592 
    593         GroupLength =
    594             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
    595                 Subtable->Buffer))->Length -
    596             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
    597                 Subtable->Buffer))->SharedInfoLength -
    598             sizeof (ACPI_CSRT_GROUP);
    599 
    600         DescriptorCount = (GroupLength  /
    601             sizeof (ACPI_CSRT_DESCRIPTOR));
    602 
    603         DtInsertSubtable (ParentTable, Subtable);
    604         DtPushSubtable (Subtable);
    605         ParentTable = DtPeekSubtable ();
    606 
    607         /* Shared info subtable (One per resource group) */
    608 
    609         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
    610             &Subtable);
    611         if (ACPI_FAILURE (Status))
    612         {
    613             return (Status);
    614         }
    615 
    616         DtInsertSubtable (ParentTable, Subtable);
    617 
    618         /* Sub-Subtables (Resource Descriptors) */
    619 
    620         while (*PFieldList && DescriptorCount)
    621         {
    622 
    623             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
    624                 &Subtable);
    625             if (ACPI_FAILURE (Status))
    626             {
    627                 return (Status);
    628             }
    629 
    630             DtInsertSubtable (ParentTable, Subtable);
    631 
    632             DtPushSubtable (Subtable);
    633             ParentTable = DtPeekSubtable ();
    634             if (*PFieldList)
    635             {
    636                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
    637                     &Subtable);
    638                 if (ACPI_FAILURE (Status))
    639                 {
    640                     return (Status);
    641                 }
    642                 if (Subtable)
    643                 {
    644                     DtInsertSubtable (ParentTable, Subtable);
    645                 }
    646             }
    647 
    648             DtPopSubtable ();
    649             ParentTable = DtPeekSubtable ();
    650             DescriptorCount--;
    651         }
    652 
    653         DtPopSubtable ();
    654         ParentTable = DtPeekSubtable ();
    655     }
    656 
    657     return (Status);
    658 }
    659 
    660 
    661 /******************************************************************************
    662  *
    663  * FUNCTION:    DtCompileDbg2
    664  *
    665  * PARAMETERS:  List                - Current field list pointer
    666  *
    667  * RETURN:      Status
    668  *
    669  * DESCRIPTION: Compile DBG2.
    670  *
    671  *****************************************************************************/
    672 
    673 ACPI_STATUS
    674 DtCompileDbg2 (
    675     void                    **List)
    676 {
    677     ACPI_STATUS             Status;
    678     DT_SUBTABLE             *Subtable;
    679     DT_SUBTABLE             *ParentTable;
    680     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    681     UINT32                  SubtableCount;
    682     ACPI_DBG2_HEADER        *Dbg2Header;
    683     ACPI_DBG2_DEVICE        *DeviceInfo;
    684     UINT16                  CurrentOffset;
    685     UINT32                  i;
    686 
    687 
    688     /* Main table */
    689 
    690     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable);
    691     if (ACPI_FAILURE (Status))
    692     {
    693         return (Status);
    694     }
    695 
    696     ParentTable = DtPeekSubtable ();
    697     DtInsertSubtable (ParentTable, Subtable);
    698 
    699     /* Main table fields */
    700 
    701     Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
    702     Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
    703         ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
    704 
    705     SubtableCount = Dbg2Header->InfoCount;
    706     DtPushSubtable (Subtable);
    707 
    708     /* Process all Device Information subtables (Count = InfoCount) */
    709 
    710     while (*PFieldList && SubtableCount)
    711     {
    712         /* Subtable: Debug Device Information */
    713 
    714         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
    715             &Subtable);
    716         if (ACPI_FAILURE (Status))
    717         {
    718             return (Status);
    719         }
    720 
    721         DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
    722         CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
    723 
    724         ParentTable = DtPeekSubtable ();
    725         DtInsertSubtable (ParentTable, Subtable);
    726         DtPushSubtable (Subtable);
    727 
    728         ParentTable = DtPeekSubtable ();
    729 
    730         /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
    731 
    732         DeviceInfo->BaseAddressOffset = CurrentOffset;
    733         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
    734         {
    735             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
    736                 &Subtable);
    737             if (ACPI_FAILURE (Status))
    738             {
    739                 return (Status);
    740             }
    741 
    742             CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
    743             DtInsertSubtable (ParentTable, Subtable);
    744         }
    745 
    746         /* AddressSize array (Required, size = RegisterCount) */
    747 
    748         DeviceInfo->AddressSizeOffset = CurrentOffset;
    749         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
    750         {
    751             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
    752                 &Subtable);
    753             if (ACPI_FAILURE (Status))
    754             {
    755                 return (Status);
    756             }
    757 
    758             CurrentOffset += (UINT16) sizeof (UINT32);
    759             DtInsertSubtable (ParentTable, Subtable);
    760         }
    761 
    762         /* NamespaceString device identifier (Required, size = NamePathLength) */
    763 
    764         DeviceInfo->NamepathOffset = CurrentOffset;
    765         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
    766             &Subtable);
    767         if (ACPI_FAILURE (Status))
    768         {
    769             return (Status);
    770         }
    771 
    772         /* Update the device info header */
    773 
    774         DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
    775         CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
    776         DtInsertSubtable (ParentTable, Subtable);
    777 
    778         /* OemData - Variable-length data (Optional, size = OemDataLength) */
    779 
    780         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
    781             &Subtable);
    782         if (Status == AE_END_OF_TABLE)
    783         {
    784             /* optional field was not found and we're at the end of the file */
    785 
    786             goto subtableDone;
    787         }
    788         else if (ACPI_FAILURE (Status))
    789         {
    790             return (Status);
    791         }
    792 
    793         /* Update the device info header (zeros if no OEM data present) */
    794 
    795         DeviceInfo->OemDataOffset = 0;
    796         DeviceInfo->OemDataLength = 0;
    797 
    798         /* Optional subtable (OemData) */
    799 
    800         if (Subtable && Subtable->Length)
    801         {
    802             DeviceInfo->OemDataOffset = CurrentOffset;
    803             DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
    804 
    805             DtInsertSubtable (ParentTable, Subtable);
    806         }
    807 subtableDone:
    808         SubtableCount--;
    809         DtPopSubtable (); /* Get next Device Information subtable */
    810     }
    811 
    812     DtPopSubtable ();
    813     return (AE_OK);
    814 }
    815 
    816 
    817 /******************************************************************************
    818  *
    819  * FUNCTION:    DtCompileDmar
    820  *
    821  * PARAMETERS:  List                - Current field list pointer
    822  *
    823  * RETURN:      Status
    824  *
    825  * DESCRIPTION: Compile DMAR.
    826  *
    827  *****************************************************************************/
    828 
    829 ACPI_STATUS
    830 DtCompileDmar (
    831     void                    **List)
    832 {
    833     ACPI_STATUS             Status;
    834     DT_SUBTABLE             *Subtable;
    835     DT_SUBTABLE             *ParentTable;
    836     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    837     DT_FIELD                *SubtableStart;
    838     ACPI_DMTABLE_INFO       *InfoTable;
    839     ACPI_DMAR_HEADER        *DmarHeader;
    840     ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
    841     UINT32                  DeviceScopeLength;
    842     UINT32                  PciPathLength;
    843 
    844 
    845     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable);
    846     if (ACPI_FAILURE (Status))
    847     {
    848         return (Status);
    849     }
    850 
    851     ParentTable = DtPeekSubtable ();
    852     DtInsertSubtable (ParentTable, Subtable);
    853     DtPushSubtable (Subtable);
    854 
    855     while (*PFieldList)
    856     {
    857         /* DMAR Header */
    858 
    859         SubtableStart = *PFieldList;
    860         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
    861             &Subtable);
    862         if (ACPI_FAILURE (Status))
    863         {
    864             return (Status);
    865         }
    866 
    867         ParentTable = DtPeekSubtable ();
    868         DtInsertSubtable (ParentTable, Subtable);
    869         DtPushSubtable (Subtable);
    870 
    871         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
    872 
    873         switch (DmarHeader->Type)
    874         {
    875         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
    876 
    877             InfoTable = AcpiDmTableInfoDmar0;
    878             break;
    879 
    880         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
    881 
    882             InfoTable = AcpiDmTableInfoDmar1;
    883             break;
    884 
    885         case ACPI_DMAR_TYPE_ROOT_ATS:
    886 
    887             InfoTable = AcpiDmTableInfoDmar2;
    888             break;
    889 
    890         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
    891 
    892             InfoTable = AcpiDmTableInfoDmar3;
    893             break;
    894 
    895         case ACPI_DMAR_TYPE_NAMESPACE:
    896 
    897             InfoTable = AcpiDmTableInfoDmar4;
    898             break;
    899 
    900         default:
    901 
    902             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
    903             return (AE_ERROR);
    904         }
    905 
    906         /* DMAR Subtable */
    907 
    908         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    909         if (ACPI_FAILURE (Status))
    910         {
    911             return (Status);
    912         }
    913 
    914         ParentTable = DtPeekSubtable ();
    915         DtInsertSubtable (ParentTable, Subtable);
    916 
    917         /*
    918          * Optional Device Scope subtables
    919          */
    920         if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
    921             (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
    922         {
    923             /* These types do not support device scopes */
    924 
    925             DtPopSubtable ();
    926             continue;
    927         }
    928 
    929         DtPushSubtable (Subtable);
    930         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
    931             ParentTable->Length;
    932         while (DeviceScopeLength)
    933         {
    934             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
    935                 &Subtable);
    936             if (Status == AE_NOT_FOUND)
    937             {
    938                 break;
    939             }
    940 
    941             ParentTable = DtPeekSubtable ();
    942             DtInsertSubtable (ParentTable, Subtable);
    943             DtPushSubtable (Subtable);
    944 
    945             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
    946 
    947             /* Optional PCI Paths */
    948 
    949             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
    950             while (PciPathLength)
    951             {
    952                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
    953                     &Subtable);
    954                 if (Status == AE_NOT_FOUND)
    955                 {
    956                     DtPopSubtable ();
    957                     break;
    958                 }
    959 
    960                 ParentTable = DtPeekSubtable ();
    961                 DtInsertSubtable (ParentTable, Subtable);
    962                 PciPathLength -= Subtable->Length;
    963             }
    964 
    965             DtPopSubtable ();
    966             DeviceScopeLength -= DmarDeviceScope->Length;
    967         }
    968 
    969         DtPopSubtable ();
    970         DtPopSubtable ();
    971     }
    972 
    973     return (AE_OK);
    974 }
    975 
    976 
    977 /******************************************************************************
    978  *
    979  * FUNCTION:    DtCompileDrtm
    980  *
    981  * PARAMETERS:  List                - Current field list pointer
    982  *
    983  * RETURN:      Status
    984  *
    985  * DESCRIPTION: Compile DRTM.
    986  *
    987  *****************************************************************************/
    988 
    989 ACPI_STATUS
    990 DtCompileDrtm (
    991     void                    **List)
    992 {
    993     ACPI_STATUS             Status;
    994     DT_SUBTABLE             *Subtable;
    995     DT_SUBTABLE             *ParentTable;
    996     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    997     UINT32                  Count;
    998     /* ACPI_TABLE_DRTM         *Drtm; */
    999     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
   1000     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
   1001     /* ACPI_DRTM_DPS_ID        *DrtmDps; */
   1002 
   1003 
   1004     ParentTable = DtPeekSubtable ();
   1005 
   1006     /* Compile DRTM header */
   1007 
   1008     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
   1009         &Subtable);
   1010     if (ACPI_FAILURE (Status))
   1011     {
   1012         return (Status);
   1013     }
   1014     DtInsertSubtable (ParentTable, Subtable);
   1015 
   1016     /*
   1017      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   1018      * should be taken to avoid accessing ACPI_TABLE_HADER fields.
   1019      */
   1020 #if 0
   1021     Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
   1022         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
   1023 #endif
   1024     /* Compile VTL */
   1025 
   1026     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
   1027         &Subtable);
   1028     if (ACPI_FAILURE (Status))
   1029     {
   1030         return (Status);
   1031     }
   1032 
   1033     DtInsertSubtable (ParentTable, Subtable);
   1034     DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
   1035 
   1036     DtPushSubtable (Subtable);
   1037     ParentTable = DtPeekSubtable ();
   1038     Count = 0;
   1039 
   1040     while (*PFieldList)
   1041     {
   1042         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
   1043             &Subtable);
   1044         if (ACPI_FAILURE (Status))
   1045         {
   1046             return (Status);
   1047         }
   1048         if (!Subtable)
   1049         {
   1050             break;
   1051         }
   1052         DtInsertSubtable (ParentTable, Subtable);
   1053         Count++;
   1054     }
   1055 
   1056     DrtmVtl->ValidatedTableCount = Count;
   1057     DtPopSubtable ();
   1058     ParentTable = DtPeekSubtable ();
   1059 
   1060     /* Compile RL */
   1061 
   1062     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
   1063         &Subtable);
   1064     if (ACPI_FAILURE (Status))
   1065     {
   1066         return (Status);
   1067     }
   1068 
   1069     DtInsertSubtable (ParentTable, Subtable);
   1070     DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
   1071 
   1072     DtPushSubtable (Subtable);
   1073     ParentTable = DtPeekSubtable ();
   1074     Count = 0;
   1075 
   1076     while (*PFieldList)
   1077     {
   1078         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
   1079             &Subtable);
   1080         if (ACPI_FAILURE (Status))
   1081         {
   1082             return (Status);
   1083         }
   1084 
   1085         if (!Subtable)
   1086         {
   1087             break;
   1088         }
   1089 
   1090         DtInsertSubtable (ParentTable, Subtable);
   1091         Count++;
   1092     }
   1093 
   1094     DrtmRl->ResourceCount = Count;
   1095     DtPopSubtable ();
   1096     ParentTable = DtPeekSubtable ();
   1097 
   1098     /* Compile DPS */
   1099 
   1100     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
   1101         &Subtable);
   1102     if (ACPI_FAILURE (Status))
   1103     {
   1104         return (Status);
   1105     }
   1106     DtInsertSubtable (ParentTable, Subtable);
   1107     /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
   1108 
   1109 
   1110     return (AE_OK);
   1111 }
   1112 
   1113 
   1114 /******************************************************************************
   1115  *
   1116  * FUNCTION:    DtCompileEinj
   1117  *
   1118  * PARAMETERS:  List                - Current field list pointer
   1119  *
   1120  * RETURN:      Status
   1121  *
   1122  * DESCRIPTION: Compile EINJ.
   1123  *
   1124  *****************************************************************************/
   1125 
   1126 ACPI_STATUS
   1127 DtCompileEinj (
   1128     void                    **List)
   1129 {
   1130     ACPI_STATUS             Status;
   1131 
   1132 
   1133     Status = DtCompileTwoSubtables (List,
   1134         AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
   1135     return (Status);
   1136 }
   1137 
   1138 
   1139 /******************************************************************************
   1140  *
   1141  * FUNCTION:    DtCompileErst
   1142  *
   1143  * PARAMETERS:  List                - Current field list pointer
   1144  *
   1145  * RETURN:      Status
   1146  *
   1147  * DESCRIPTION: Compile ERST.
   1148  *
   1149  *****************************************************************************/
   1150 
   1151 ACPI_STATUS
   1152 DtCompileErst (
   1153     void                    **List)
   1154 {
   1155     ACPI_STATUS             Status;
   1156 
   1157 
   1158     Status = DtCompileTwoSubtables (List,
   1159         AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
   1160     return (Status);
   1161 }
   1162 
   1163 
   1164 /******************************************************************************
   1165  *
   1166  * FUNCTION:    DtCompileGtdt
   1167  *
   1168  * PARAMETERS:  List                - Current field list pointer
   1169  *
   1170  * RETURN:      Status
   1171  *
   1172  * DESCRIPTION: Compile GTDT.
   1173  *
   1174  *****************************************************************************/
   1175 
   1176 ACPI_STATUS
   1177 DtCompileGtdt (
   1178     void                    **List)
   1179 {
   1180     ACPI_STATUS             Status;
   1181     DT_SUBTABLE             *Subtable;
   1182     DT_SUBTABLE             *ParentTable;
   1183     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1184     DT_FIELD                *SubtableStart;
   1185     ACPI_SUBTABLE_HEADER    *GtdtHeader;
   1186     ACPI_DMTABLE_INFO       *InfoTable;
   1187     UINT32                  GtCount;
   1188     ACPI_TABLE_HEADER       *Header;
   1189 
   1190 
   1191     ParentTable = DtPeekSubtable ();
   1192 
   1193     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   1194 
   1195     /* Compile the main table */
   1196 
   1197     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
   1198         &Subtable);
   1199     if (ACPI_FAILURE (Status))
   1200     {
   1201         return (Status);
   1202     }
   1203 
   1204     /* GTDT revision 3 later contains 2 extra fields before subtables */
   1205 
   1206     if (Header->Revision > 2)
   1207     {
   1208         ParentTable = DtPeekSubtable ();
   1209         DtInsertSubtable (ParentTable, Subtable);
   1210 
   1211         Status = DtCompileTable (PFieldList,
   1212             AcpiDmTableInfoGtdtEl2, &Subtable);
   1213         if (ACPI_FAILURE (Status))
   1214         {
   1215             return (Status);
   1216         }
   1217     }
   1218 
   1219     ParentTable = DtPeekSubtable ();
   1220     DtInsertSubtable (ParentTable, Subtable);
   1221 
   1222     while (*PFieldList)
   1223     {
   1224         SubtableStart = *PFieldList;
   1225         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
   1226             &Subtable);
   1227         if (ACPI_FAILURE (Status))
   1228         {
   1229             return (Status);
   1230         }
   1231 
   1232         ParentTable = DtPeekSubtable ();
   1233         DtInsertSubtable (ParentTable, Subtable);
   1234         DtPushSubtable (Subtable);
   1235 
   1236         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
   1237 
   1238         switch (GtdtHeader->Type)
   1239         {
   1240         case ACPI_GTDT_TYPE_TIMER_BLOCK:
   1241 
   1242             InfoTable = AcpiDmTableInfoGtdt0;
   1243             break;
   1244 
   1245         case ACPI_GTDT_TYPE_WATCHDOG:
   1246 
   1247             InfoTable = AcpiDmTableInfoGtdt1;
   1248             break;
   1249 
   1250         default:
   1251 
   1252             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
   1253             return (AE_ERROR);
   1254         }
   1255 
   1256         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1257         if (ACPI_FAILURE (Status))
   1258         {
   1259             return (Status);
   1260         }
   1261 
   1262         ParentTable = DtPeekSubtable ();
   1263         DtInsertSubtable (ParentTable, Subtable);
   1264 
   1265         /*
   1266          * Additional GT block subtable data
   1267          */
   1268 
   1269         switch (GtdtHeader->Type)
   1270         {
   1271         case ACPI_GTDT_TYPE_TIMER_BLOCK:
   1272 
   1273             DtPushSubtable (Subtable);
   1274             ParentTable = DtPeekSubtable ();
   1275 
   1276             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
   1277                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
   1278 
   1279             while (GtCount)
   1280             {
   1281                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
   1282                     &Subtable);
   1283                 if (ACPI_FAILURE (Status))
   1284                 {
   1285                     return (Status);
   1286                 }
   1287 
   1288                 DtInsertSubtable (ParentTable, Subtable);
   1289                 GtCount--;
   1290             }
   1291 
   1292             DtPopSubtable ();
   1293             break;
   1294 
   1295         default:
   1296 
   1297             break;
   1298         }
   1299 
   1300         DtPopSubtable ();
   1301     }
   1302 
   1303     return (AE_OK);
   1304 }
   1305 
   1306 
   1307 /******************************************************************************
   1308  *
   1309  * FUNCTION:    DtCompileFpdt
   1310  *
   1311  * PARAMETERS:  List                - Current field list pointer
   1312  *
   1313  * RETURN:      Status
   1314  *
   1315  * DESCRIPTION: Compile FPDT.
   1316  *
   1317  *****************************************************************************/
   1318 
   1319 ACPI_STATUS
   1320 DtCompileFpdt (
   1321     void                    **List)
   1322 {
   1323     ACPI_STATUS             Status;
   1324     ACPI_FPDT_HEADER        *FpdtHeader;
   1325     DT_SUBTABLE             *Subtable;
   1326     DT_SUBTABLE             *ParentTable;
   1327     ACPI_DMTABLE_INFO       *InfoTable;
   1328     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1329     DT_FIELD                *SubtableStart;
   1330 
   1331 
   1332     while (*PFieldList)
   1333     {
   1334         SubtableStart = *PFieldList;
   1335         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
   1336             &Subtable);
   1337         if (ACPI_FAILURE (Status))
   1338         {
   1339             return (Status);
   1340         }
   1341 
   1342         ParentTable = DtPeekSubtable ();
   1343         DtInsertSubtable (ParentTable, Subtable);
   1344         DtPushSubtable (Subtable);
   1345 
   1346         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
   1347 
   1348         switch (FpdtHeader->Type)
   1349         {
   1350         case ACPI_FPDT_TYPE_BOOT:
   1351 
   1352             InfoTable = AcpiDmTableInfoFpdt0;
   1353             break;
   1354 
   1355         case ACPI_FPDT_TYPE_S3PERF:
   1356 
   1357             InfoTable = AcpiDmTableInfoFpdt1;
   1358             break;
   1359 
   1360         default:
   1361 
   1362             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
   1363             return (AE_ERROR);
   1364             break;
   1365         }
   1366 
   1367         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1368         if (ACPI_FAILURE (Status))
   1369         {
   1370             return (Status);
   1371         }
   1372 
   1373         ParentTable = DtPeekSubtable ();
   1374         DtInsertSubtable (ParentTable, Subtable);
   1375         DtPopSubtable ();
   1376     }
   1377 
   1378     return (AE_OK);
   1379 }
   1380 
   1381 
   1382 /******************************************************************************
   1383  *
   1384  * FUNCTION:    DtCompileHest
   1385  *
   1386  * PARAMETERS:  List                - Current field list pointer
   1387  *
   1388  * RETURN:      Status
   1389  *
   1390  * DESCRIPTION: Compile HEST.
   1391  *
   1392  *****************************************************************************/
   1393 
   1394 ACPI_STATUS
   1395 DtCompileHest (
   1396     void                    **List)
   1397 {
   1398     ACPI_STATUS             Status;
   1399     DT_SUBTABLE             *Subtable;
   1400     DT_SUBTABLE             *ParentTable;
   1401     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1402     DT_FIELD                *SubtableStart;
   1403     ACPI_DMTABLE_INFO       *InfoTable;
   1404     UINT16                  Type;
   1405     UINT32                  BankCount;
   1406 
   1407 
   1408     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
   1409         &Subtable);
   1410     if (ACPI_FAILURE (Status))
   1411     {
   1412         return (Status);
   1413     }
   1414 
   1415     ParentTable = DtPeekSubtable ();
   1416     DtInsertSubtable (ParentTable, Subtable);
   1417 
   1418     while (*PFieldList)
   1419     {
   1420         /* Get subtable type */
   1421 
   1422         SubtableStart = *PFieldList;
   1423         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
   1424 
   1425         switch (Type)
   1426         {
   1427         case ACPI_HEST_TYPE_IA32_CHECK:
   1428 
   1429             InfoTable = AcpiDmTableInfoHest0;
   1430             break;
   1431 
   1432         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   1433 
   1434             InfoTable = AcpiDmTableInfoHest1;
   1435             break;
   1436 
   1437         case ACPI_HEST_TYPE_IA32_NMI:
   1438 
   1439             InfoTable = AcpiDmTableInfoHest2;
   1440             break;
   1441 
   1442         case ACPI_HEST_TYPE_AER_ROOT_PORT:
   1443 
   1444             InfoTable = AcpiDmTableInfoHest6;
   1445             break;
   1446 
   1447         case ACPI_HEST_TYPE_AER_ENDPOINT:
   1448 
   1449             InfoTable = AcpiDmTableInfoHest7;
   1450             break;
   1451 
   1452         case ACPI_HEST_TYPE_AER_BRIDGE:
   1453 
   1454             InfoTable = AcpiDmTableInfoHest8;
   1455             break;
   1456 
   1457         case ACPI_HEST_TYPE_GENERIC_ERROR:
   1458 
   1459             InfoTable = AcpiDmTableInfoHest9;
   1460             break;
   1461 
   1462         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
   1463 
   1464             InfoTable = AcpiDmTableInfoHest10;
   1465             break;
   1466 
   1467         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   1468 
   1469             InfoTable = AcpiDmTableInfoHest11;
   1470             break;
   1471 
   1472         default:
   1473 
   1474             /* Cannot continue on unknown type */
   1475 
   1476             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
   1477             return (AE_ERROR);
   1478         }
   1479 
   1480         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1481         if (ACPI_FAILURE (Status))
   1482         {
   1483             return (Status);
   1484         }
   1485 
   1486         DtInsertSubtable (ParentTable, Subtable);
   1487 
   1488         /*
   1489          * Additional subtable data - IA32 Error Bank(s)
   1490          */
   1491         BankCount = 0;
   1492         switch (Type)
   1493         {
   1494         case ACPI_HEST_TYPE_IA32_CHECK:
   1495 
   1496             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
   1497                 Subtable->Buffer))->NumHardwareBanks;
   1498             break;
   1499 
   1500         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   1501 
   1502             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
   1503                 Subtable->Buffer))->NumHardwareBanks;
   1504             break;
   1505 
   1506         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   1507 
   1508             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
   1509                 Subtable->Buffer))->NumHardwareBanks;
   1510             break;
   1511 
   1512         default:
   1513 
   1514             break;
   1515         }
   1516 
   1517         while (BankCount)
   1518         {
   1519             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
   1520                 &Subtable);
   1521             if (ACPI_FAILURE (Status))
   1522             {
   1523                 return (Status);
   1524             }
   1525 
   1526             DtInsertSubtable (ParentTable, Subtable);
   1527             BankCount--;
   1528         }
   1529     }
   1530 
   1531     return (AE_OK);
   1532 }
   1533 
   1534 
   1535 /******************************************************************************
   1536  *
   1537  * FUNCTION:    DtCompileHmat
   1538  *
   1539  * PARAMETERS:  List                - Current field list pointer
   1540  *
   1541  * RETURN:      Status
   1542  *
   1543  * DESCRIPTION: Compile HMAT.
   1544  *
   1545  *****************************************************************************/
   1546 
   1547 ACPI_STATUS
   1548 DtCompileHmat (
   1549     void                    **List)
   1550 {
   1551     ACPI_STATUS             Status;
   1552     DT_SUBTABLE             *Subtable;
   1553     DT_SUBTABLE             *ParentTable;
   1554     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1555     DT_FIELD                *SubtableStart;
   1556     DT_FIELD                *EntryStart;
   1557     ACPI_HMAT_STRUCTURE     *HmatStruct;
   1558     ACPI_HMAT_LOCALITY      *HmatLocality;
   1559     ACPI_HMAT_CACHE         *HmatCache;
   1560     ACPI_DMTABLE_INFO       *InfoTable;
   1561     UINT32                  IntPDNumber;
   1562     UINT32                  TgtPDNumber;
   1563     UINT64                  EntryNumber;
   1564     UINT16                  SMBIOSHandleNumber;
   1565 
   1566 
   1567     ParentTable = DtPeekSubtable ();
   1568 
   1569     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
   1570         &Subtable);
   1571     if (ACPI_FAILURE (Status))
   1572     {
   1573         return (Status);
   1574     }
   1575     DtInsertSubtable (ParentTable, Subtable);
   1576 
   1577     while (*PFieldList)
   1578     {
   1579         /* Compile HMAT structure header */
   1580 
   1581         SubtableStart = *PFieldList;
   1582         Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
   1583             &Subtable);
   1584         if (ACPI_FAILURE (Status))
   1585         {
   1586             return (Status);
   1587         }
   1588         DtInsertSubtable (ParentTable, Subtable);
   1589 
   1590         HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
   1591         HmatStruct->Length = Subtable->Length;
   1592 
   1593         /* Compile HMAT structure body */
   1594 
   1595         switch (HmatStruct->Type)
   1596         {
   1597         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
   1598 
   1599             InfoTable = AcpiDmTableInfoHmat0;
   1600             break;
   1601 
   1602         case ACPI_HMAT_TYPE_LOCALITY:
   1603 
   1604             InfoTable = AcpiDmTableInfoHmat1;
   1605             break;
   1606 
   1607         case ACPI_HMAT_TYPE_CACHE:
   1608 
   1609             InfoTable = AcpiDmTableInfoHmat2;
   1610             break;
   1611 
   1612         default:
   1613 
   1614             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
   1615             return (AE_ERROR);
   1616         }
   1617 
   1618         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1619         if (ACPI_FAILURE (Status))
   1620         {
   1621             return (Status);
   1622         }
   1623         DtInsertSubtable (ParentTable, Subtable);
   1624         HmatStruct->Length += Subtable->Length;
   1625 
   1626         /* Compile HMAT structure additionals */
   1627 
   1628         switch (HmatStruct->Type)
   1629         {
   1630         case ACPI_HMAT_TYPE_LOCALITY:
   1631 
   1632             HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
   1633                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   1634 
   1635             /* Compile initiator proximity domain list */
   1636 
   1637             IntPDNumber = 0;
   1638             while (*PFieldList)
   1639             {
   1640                 Status = DtCompileTable (PFieldList,
   1641                     AcpiDmTableInfoHmat1a, &Subtable);
   1642                 if (ACPI_FAILURE (Status))
   1643                 {
   1644                     return (Status);
   1645                 }
   1646                 if (!Subtable)
   1647                 {
   1648                     break;
   1649                 }
   1650                 DtInsertSubtable (ParentTable, Subtable);
   1651                 HmatStruct->Length += Subtable->Length;
   1652                 IntPDNumber++;
   1653             }
   1654             HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
   1655 
   1656             /* Compile target proximity domain list */
   1657 
   1658             TgtPDNumber = 0;
   1659             while (*PFieldList)
   1660             {
   1661                 Status = DtCompileTable (PFieldList,
   1662                     AcpiDmTableInfoHmat1b, &Subtable);
   1663                 if (ACPI_FAILURE (Status))
   1664                 {
   1665                     return (Status);
   1666                 }
   1667                 if (!Subtable)
   1668                 {
   1669                     break;
   1670                 }
   1671                 DtInsertSubtable (ParentTable, Subtable);
   1672                 HmatStruct->Length += Subtable->Length;
   1673                 TgtPDNumber++;
   1674             }
   1675             HmatLocality->NumberOfTargetPDs = TgtPDNumber;
   1676 
   1677             /* Save start of the entries for reporting errors */
   1678 
   1679             EntryStart = *PFieldList;
   1680 
   1681             /* Compile latency/bandwidth entries */
   1682 
   1683             EntryNumber = 0;
   1684             while (*PFieldList)
   1685             {
   1686                 Status = DtCompileTable (PFieldList,
   1687                     AcpiDmTableInfoHmat1c, &Subtable);
   1688                 if (ACPI_FAILURE (Status))
   1689                 {
   1690                     return (Status);
   1691                 }
   1692                 if (!Subtable)
   1693                 {
   1694                     break;
   1695                 }
   1696                 DtInsertSubtable (ParentTable, Subtable);
   1697                 HmatStruct->Length += Subtable->Length;
   1698                 EntryNumber++;
   1699             }
   1700 
   1701             /* Validate number of entries */
   1702 
   1703             if (EntryNumber !=
   1704                 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
   1705             {
   1706                 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
   1707                 return (AE_ERROR);
   1708             }
   1709             break;
   1710 
   1711         case ACPI_HMAT_TYPE_CACHE:
   1712 
   1713             /* Compile SMBIOS handles */
   1714 
   1715             HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
   1716                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   1717             SMBIOSHandleNumber = 0;
   1718             while (*PFieldList)
   1719             {
   1720                 Status = DtCompileTable (PFieldList,
   1721                     AcpiDmTableInfoHmat2a, &Subtable);
   1722                 if (ACPI_FAILURE (Status))
   1723                 {
   1724                     return (Status);
   1725                 }
   1726                 if (!Subtable)
   1727                 {
   1728                     break;
   1729                 }
   1730                 DtInsertSubtable (ParentTable, Subtable);
   1731                 HmatStruct->Length += Subtable->Length;
   1732                 SMBIOSHandleNumber++;
   1733             }
   1734             HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
   1735             break;
   1736 
   1737         default:
   1738 
   1739             break;
   1740         }
   1741     }
   1742 
   1743     return (AE_OK);
   1744 }
   1745 
   1746 
   1747 /******************************************************************************
   1748  *
   1749  * FUNCTION:    DtCompileIort
   1750  *
   1751  * PARAMETERS:  List                - Current field list pointer
   1752  *
   1753  * RETURN:      Status
   1754  *
   1755  * DESCRIPTION: Compile IORT.
   1756  *
   1757  *****************************************************************************/
   1758 
   1759 ACPI_STATUS
   1760 DtCompileIort (
   1761     void                    **List)
   1762 {
   1763     ACPI_STATUS             Status;
   1764     DT_SUBTABLE             *Subtable;
   1765     DT_SUBTABLE             *ParentTable;
   1766     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1767     DT_FIELD                *SubtableStart;
   1768     ACPI_TABLE_HEADER       *Table;
   1769     ACPI_TABLE_IORT         *Iort;
   1770     ACPI_IORT_NODE          *IortNode;
   1771     ACPI_IORT_ITS_GROUP     *IortItsGroup;
   1772     ACPI_IORT_SMMU          *IortSmmu;
   1773     ACPI_IORT_RMR           *IortRmr;
   1774     UINT32                  NodeNumber;
   1775     UINT32                  NodeLength;
   1776     UINT32                  IdMappingNumber;
   1777     UINT32                  ItsNumber;
   1778     UINT32                  ContextIrptNumber;
   1779     UINT32                  PmuIrptNumber;
   1780     UINT32                  PaddingLength;
   1781     UINT8                   Revision;
   1782     UINT32                  RmrCount;
   1783 
   1784 
   1785     ParentTable = DtPeekSubtable ();
   1786 
   1787     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
   1788         &Subtable);
   1789     if (ACPI_FAILURE (Status))
   1790     {
   1791         return (Status);
   1792     }
   1793     DtInsertSubtable (ParentTable, Subtable);
   1794 
   1795     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   1796     Revision = Table->Revision;
   1797 
   1798     /* Both IORT Rev E and E.a have known issues and are not supported */
   1799 
   1800     if (Revision == 1 || Revision == 2)
   1801     {
   1802         DtError (ASL_ERROR, ASL_MSG_UNSUPPORTED, NULL, "IORT table revision");
   1803         return (AE_ERROR);
   1804     }
   1805 
   1806     /*
   1807      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   1808      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
   1809      */
   1810     Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
   1811         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
   1812 
   1813     /*
   1814      * OptionalPadding - Variable-length data
   1815      * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
   1816      * Optionally allows the generic data types to be used for filling
   1817      * this field.
   1818      */
   1819     Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
   1820     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
   1821         &Subtable);
   1822     if (ACPI_FAILURE (Status))
   1823     {
   1824         return (Status);
   1825     }
   1826     if (Subtable)
   1827     {
   1828         DtInsertSubtable (ParentTable, Subtable);
   1829         Iort->NodeOffset += Subtable->Length;
   1830     }
   1831     else
   1832     {
   1833         Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
   1834             AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
   1835         if (ACPI_FAILURE (Status))
   1836         {
   1837             return (Status);
   1838         }
   1839         Iort->NodeOffset += PaddingLength;
   1840     }
   1841 
   1842     NodeNumber = 0;
   1843     while (*PFieldList)
   1844     {
   1845         SubtableStart = *PFieldList;
   1846         if (Revision == 0)
   1847         {
   1848             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
   1849                 &Subtable);
   1850         }
   1851         else if (Revision >= 3)
   1852         {
   1853             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr3,
   1854                 &Subtable);
   1855         }
   1856 
   1857         if (ACPI_FAILURE (Status))
   1858         {
   1859             return (Status);
   1860         }
   1861 
   1862         DtInsertSubtable (ParentTable, Subtable);
   1863         IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
   1864         NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
   1865 
   1866         DtPushSubtable (Subtable);
   1867         ParentTable = DtPeekSubtable ();
   1868 
   1869         switch (IortNode->Type)
   1870         {
   1871         case ACPI_IORT_NODE_ITS_GROUP:
   1872 
   1873             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
   1874                 &Subtable);
   1875             if (ACPI_FAILURE (Status))
   1876             {
   1877                 return (Status);
   1878             }
   1879 
   1880             DtInsertSubtable (ParentTable, Subtable);
   1881             IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
   1882             NodeLength += Subtable->Length;
   1883 
   1884             ItsNumber = 0;
   1885             while (*PFieldList)
   1886             {
   1887                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
   1888                     &Subtable);
   1889                 if (ACPI_FAILURE (Status))
   1890                 {
   1891                     return (Status);
   1892                 }
   1893                 if (!Subtable)
   1894                 {
   1895                     break;
   1896                 }
   1897 
   1898                 DtInsertSubtable (ParentTable, Subtable);
   1899                 NodeLength += Subtable->Length;
   1900                 ItsNumber++;
   1901             }
   1902 
   1903             IortItsGroup->ItsCount = ItsNumber;
   1904             break;
   1905 
   1906         case ACPI_IORT_NODE_NAMED_COMPONENT:
   1907 
   1908             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
   1909                 &Subtable);
   1910             if (ACPI_FAILURE (Status))
   1911             {
   1912                 return (Status);
   1913             }
   1914 
   1915             DtInsertSubtable (ParentTable, Subtable);
   1916             NodeLength += Subtable->Length;
   1917 
   1918             /*
   1919              * Padding - Variable-length data
   1920              * Optionally allows the offset of the ID mappings to be used
   1921              * for filling this field.
   1922              */
   1923             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
   1924                 &Subtable);
   1925             if (ACPI_FAILURE (Status))
   1926             {
   1927                 return (Status);
   1928             }
   1929 
   1930             if (Subtable)
   1931             {
   1932                 DtInsertSubtable (ParentTable, Subtable);
   1933                 NodeLength += Subtable->Length;
   1934             }
   1935             else
   1936             {
   1937                 if (NodeLength > IortNode->MappingOffset)
   1938                 {
   1939                     return (AE_BAD_DATA);
   1940                 }
   1941 
   1942                 if (NodeLength < IortNode->MappingOffset)
   1943                 {
   1944                     Status = DtCompilePadding (
   1945                         IortNode->MappingOffset - NodeLength,
   1946                         &Subtable);
   1947                     if (ACPI_FAILURE (Status))
   1948                     {
   1949                         return (Status);
   1950                     }
   1951 
   1952                     DtInsertSubtable (ParentTable, Subtable);
   1953                     NodeLength = IortNode->MappingOffset;
   1954                 }
   1955             }
   1956             break;
   1957 
   1958         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
   1959 
   1960             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
   1961                 &Subtable);
   1962             if (ACPI_FAILURE (Status))
   1963             {
   1964                 return (Status);
   1965             }
   1966 
   1967             DtInsertSubtable (ParentTable, Subtable);
   1968             NodeLength += Subtable->Length;
   1969             break;
   1970 
   1971         case ACPI_IORT_NODE_SMMU:
   1972 
   1973             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
   1974                 &Subtable);
   1975             if (ACPI_FAILURE (Status))
   1976             {
   1977                 return (Status);
   1978             }
   1979 
   1980             DtInsertSubtable (ParentTable, Subtable);
   1981             IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
   1982             NodeLength += Subtable->Length;
   1983 
   1984             /* Compile global interrupt array */
   1985 
   1986             IortSmmu->GlobalInterruptOffset = NodeLength;
   1987             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
   1988                 &Subtable);
   1989             if (ACPI_FAILURE (Status))
   1990             {
   1991                 return (Status);
   1992             }
   1993 
   1994             DtInsertSubtable (ParentTable, Subtable);
   1995             NodeLength += Subtable->Length;
   1996 
   1997             /* Compile context interrupt array */
   1998 
   1999             ContextIrptNumber = 0;
   2000             IortSmmu->ContextInterruptOffset = NodeLength;
   2001             while (*PFieldList)
   2002             {
   2003                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
   2004                     &Subtable);
   2005                 if (ACPI_FAILURE (Status))
   2006                 {
   2007                     return (Status);
   2008                 }
   2009 
   2010                 if (!Subtable)
   2011                 {
   2012                     break;
   2013                 }
   2014 
   2015                 DtInsertSubtable (ParentTable, Subtable);
   2016                 NodeLength += Subtable->Length;
   2017                 ContextIrptNumber++;
   2018             }
   2019 
   2020             IortSmmu->ContextInterruptCount = ContextIrptNumber;
   2021 
   2022             /* Compile PMU interrupt array */
   2023 
   2024             PmuIrptNumber = 0;
   2025             IortSmmu->PmuInterruptOffset = NodeLength;
   2026             while (*PFieldList)
   2027             {
   2028                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
   2029                     &Subtable);
   2030                 if (ACPI_FAILURE (Status))
   2031                 {
   2032                     return (Status);
   2033                 }
   2034 
   2035                 if (!Subtable)
   2036                 {
   2037                     break;
   2038                 }
   2039 
   2040                 DtInsertSubtable (ParentTable, Subtable);
   2041                 NodeLength += Subtable->Length;
   2042                 PmuIrptNumber++;
   2043             }
   2044 
   2045             IortSmmu->PmuInterruptCount = PmuIrptNumber;
   2046             break;
   2047 
   2048         case ACPI_IORT_NODE_SMMU_V3:
   2049 
   2050             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
   2051                 &Subtable);
   2052             if (ACPI_FAILURE (Status))
   2053             {
   2054                 return (Status);
   2055             }
   2056 
   2057             DtInsertSubtable (ParentTable, Subtable);
   2058             NodeLength += Subtable->Length;
   2059             break;
   2060 
   2061         case ACPI_IORT_NODE_PMCG:
   2062 
   2063             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
   2064                 &Subtable);
   2065             if (ACPI_FAILURE (Status))
   2066             {
   2067                 return (Status);
   2068             }
   2069 
   2070             DtInsertSubtable (ParentTable, Subtable);
   2071             NodeLength += Subtable->Length;
   2072             break;
   2073 
   2074         case ACPI_IORT_NODE_RMR:
   2075 
   2076             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6,
   2077                 &Subtable);
   2078             if (ACPI_FAILURE (Status))
   2079             {
   2080                 return (Status);
   2081             }
   2082 
   2083             DtInsertSubtable (ParentTable, Subtable);
   2084             IortRmr = ACPI_CAST_PTR (ACPI_IORT_RMR, Subtable->Buffer);
   2085             NodeLength += Subtable->Length;
   2086 
   2087             /* Compile RMR Descriptors */
   2088 
   2089             RmrCount = 0;
   2090             IortRmr->RmrOffset = NodeLength;
   2091             while (*PFieldList)
   2092             {
   2093                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort6a,
   2094                     &Subtable);
   2095                 if (ACPI_FAILURE (Status))
   2096                 {
   2097                     return (Status);
   2098                 }
   2099 
   2100                 if (!Subtable)
   2101                 {
   2102                     break;
   2103                 }
   2104 
   2105                 DtInsertSubtable (ParentTable, Subtable);
   2106                 NodeLength += sizeof (ACPI_IORT_RMR_DESC);
   2107                 RmrCount++;
   2108             }
   2109 
   2110             IortRmr->RmrCount = RmrCount;
   2111             break;
   2112 
   2113 	default:
   2114 
   2115             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
   2116             return (AE_ERROR);
   2117         }
   2118 
   2119         /* Compile Array of ID mappings */
   2120 
   2121         IortNode->MappingOffset = NodeLength;
   2122         IdMappingNumber = 0;
   2123         while (*PFieldList)
   2124         {
   2125             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
   2126                 &Subtable);
   2127             if (ACPI_FAILURE (Status))
   2128             {
   2129                 return (Status);
   2130             }
   2131 
   2132             if (!Subtable)
   2133             {
   2134                 break;
   2135             }
   2136 
   2137             DtInsertSubtable (ParentTable, Subtable);
   2138             NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
   2139             IdMappingNumber++;
   2140         }
   2141 
   2142         IortNode->MappingCount = IdMappingNumber;
   2143         if (!IdMappingNumber)
   2144         {
   2145             IortNode->MappingOffset = 0;
   2146         }
   2147 
   2148         /*
   2149          * Node length can be determined by DT_LENGTH option
   2150          * IortNode->Length = NodeLength;
   2151          */
   2152         DtPopSubtable ();
   2153         ParentTable = DtPeekSubtable ();
   2154         NodeNumber++;
   2155     }
   2156 
   2157     Iort->NodeCount = NodeNumber;
   2158     return (AE_OK);
   2159 }
   2160 
   2161 
   2162 /******************************************************************************
   2163  *
   2164  * FUNCTION:    DtCompileIvrs
   2165  *
   2166  * PARAMETERS:  List                - Current field list pointer
   2167  *
   2168  * RETURN:      Status
   2169  *
   2170  * DESCRIPTION: Compile IVRS. Notes:
   2171  *              The IVRS is essentially a flat table, with the following
   2172  *              structure:
   2173  *              <Main ACPI Table Header>
   2174  *              <Main subtable - virtualization info>
   2175  *              <IVHD>
   2176  *                  <Device Entries>
   2177  *              ...
   2178  *              <IVHD>
   2179  *                  <Device Entries>
   2180  *              <IVMD>
   2181  *              ...
   2182  *
   2183  *****************************************************************************/
   2184 
   2185 ACPI_STATUS
   2186 DtCompileIvrs (
   2187     void                    **List)
   2188 {
   2189     ACPI_STATUS             Status;
   2190     DT_SUBTABLE             *Subtable;
   2191     DT_SUBTABLE             *ParentTable;
   2192     DT_SUBTABLE             *MainSubtable;
   2193     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2194     DT_FIELD                *SubtableStart;
   2195     ACPI_DMTABLE_INFO       *InfoTable = NULL;
   2196     UINT8                   SubtableType;
   2197     UINT8                   Temp64[16];
   2198     UINT8                   Temp8;
   2199 
   2200 
   2201     /* Main table */
   2202 
   2203     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
   2204         &Subtable);
   2205     if (ACPI_FAILURE (Status))
   2206     {
   2207         return (Status);
   2208     }
   2209 
   2210     ParentTable = DtPeekSubtable ();
   2211     DtInsertSubtable (ParentTable, Subtable);
   2212     DtPushSubtable (Subtable);
   2213 
   2214     /* Save a pointer to the main subtable */
   2215 
   2216     MainSubtable = Subtable;
   2217 
   2218     while (*PFieldList)
   2219     {
   2220         SubtableStart = *PFieldList;
   2221 
   2222         /* Compile the SubtableType integer */
   2223 
   2224         DtCompileInteger (&SubtableType, *PFieldList, 1, 0);
   2225 
   2226         switch (SubtableType)
   2227         {
   2228 
   2229         /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */
   2230 
   2231         case ACPI_IVRS_TYPE_HARDWARE1:
   2232 
   2233             InfoTable = AcpiDmTableInfoIvrsHware1;
   2234             break;
   2235 
   2236         /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */
   2237 
   2238         case ACPI_IVRS_TYPE_HARDWARE2:
   2239         case ACPI_IVRS_TYPE_HARDWARE3:
   2240 
   2241             InfoTable = AcpiDmTableInfoIvrsHware23;
   2242             break;
   2243 
   2244         /* Types 20h, 21h, 22h, IVMD (I/O Virtualization Memory Definition Block) */
   2245 
   2246         case ACPI_IVRS_TYPE_MEMORY1:
   2247         case ACPI_IVRS_TYPE_MEMORY2:
   2248         case ACPI_IVRS_TYPE_MEMORY3:
   2249 
   2250             InfoTable = AcpiDmTableInfoIvrsMemory;
   2251             break;
   2252 
   2253         /* 4-byte device entries */
   2254 
   2255         case ACPI_IVRS_TYPE_PAD4:
   2256         case ACPI_IVRS_TYPE_ALL:
   2257         case ACPI_IVRS_TYPE_SELECT:
   2258         case ACPI_IVRS_TYPE_START:
   2259         case ACPI_IVRS_TYPE_END:
   2260 
   2261             InfoTable = AcpiDmTableInfoIvrs4;
   2262             break;
   2263 
   2264         /* 8-byte device entries, type A */
   2265 
   2266         case ACPI_IVRS_TYPE_ALIAS_SELECT:
   2267         case ACPI_IVRS_TYPE_ALIAS_START:
   2268 
   2269             InfoTable = AcpiDmTableInfoIvrs8a;
   2270             break;
   2271 
   2272         /* 8-byte device entries, type B */
   2273 
   2274         case ACPI_IVRS_TYPE_EXT_SELECT:
   2275         case ACPI_IVRS_TYPE_EXT_START:
   2276 
   2277             InfoTable = AcpiDmTableInfoIvrs8b;
   2278             break;
   2279 
   2280         /* 8-byte device entries, type C */
   2281 
   2282         case ACPI_IVRS_TYPE_SPECIAL:
   2283 
   2284             InfoTable = AcpiDmTableInfoIvrs8c;
   2285             break;
   2286 
   2287         /* Variable device entries, type F0h */
   2288 
   2289         case ACPI_IVRS_TYPE_HID:
   2290 
   2291             InfoTable = AcpiDmTableInfoIvrsHid;
   2292             break;
   2293 
   2294         default:
   2295 
   2296             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
   2297                 "IVRS Device Entry");
   2298             return (AE_ERROR);
   2299         }
   2300 
   2301         /* Compile the InfoTable from above */
   2302 
   2303         Status = DtCompileTable (PFieldList, InfoTable,
   2304             &Subtable);
   2305         if (ACPI_FAILURE (Status))
   2306         {
   2307             return (Status);
   2308         }
   2309 
   2310         ParentTable = DtPeekSubtable ();
   2311         if (SubtableType != ACPI_IVRS_TYPE_HARDWARE1 &&
   2312             SubtableType != ACPI_IVRS_TYPE_HARDWARE2 &&
   2313             SubtableType != ACPI_IVRS_TYPE_HARDWARE3 &&
   2314             SubtableType != ACPI_IVRS_TYPE_HID &&
   2315             SubtableType != ACPI_IVRS_TYPE_MEMORY1 &&
   2316             SubtableType != ACPI_IVRS_TYPE_MEMORY2 &&
   2317             SubtableType != ACPI_IVRS_TYPE_MEMORY3)
   2318         {
   2319             if (ParentTable)
   2320                 DtInsertSubtable (ParentTable, Subtable);
   2321         }
   2322 
   2323         switch (SubtableType)
   2324         {
   2325         case ACPI_IVRS_TYPE_HARDWARE1:
   2326         case ACPI_IVRS_TYPE_HARDWARE2:
   2327         case ACPI_IVRS_TYPE_HARDWARE3:
   2328         case ACPI_IVRS_TYPE_MEMORY1:
   2329         case ACPI_IVRS_TYPE_MEMORY2:
   2330         case ACPI_IVRS_TYPE_MEMORY3:
   2331 
   2332             /* Insert these IVHDs/IVMDs at the root subtable */
   2333 
   2334             DtInsertSubtable (MainSubtable, Subtable);
   2335             DtPushSubtable (Subtable);
   2336             ParentTable = MainSubtable;
   2337             break;
   2338 
   2339         case ACPI_IVRS_TYPE_HID:
   2340 
   2341             /* Special handling for the HID named device entry (0xF0) */
   2342 
   2343             if (ParentTable)
   2344             {
   2345                 DtInsertSubtable (ParentTable, Subtable);
   2346             }
   2347 
   2348             /*
   2349              * Process the HID value. First, get the HID value as a string.
   2350              */
   2351             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
   2352 
   2353                /*
   2354                 * Determine if the HID is an integer or a string.
   2355                 * An integer is defined to be 32 bits, with the upper 32 bits
   2356                 * set to zero. (from the ACPI Spec): "The HID can be a 32-bit
   2357                 * integer or a character string. If an integer, the lower
   2358                 * 4 bytes of the field contain the integer and the upper
   2359                 * 4 bytes are padded with 0".
   2360                 */
   2361             if (UtIsIdInteger ((UINT8 *) &Temp64))
   2362             {
   2363                 /* Compile the HID value as an integer */
   2364 
   2365                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
   2366 
   2367                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidInteger,
   2368                     &Subtable);
   2369                 if (ACPI_FAILURE (Status))
   2370                 {
   2371                     return (Status);
   2372                 }
   2373             }
   2374             else
   2375             {
   2376                 /* Compile the HID value as a string */
   2377 
   2378                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHidString,
   2379                     &Subtable);
   2380                 if (ACPI_FAILURE (Status))
   2381                 {
   2382                     return (Status);
   2383                 }
   2384             }
   2385 
   2386             DtInsertSubtable (ParentTable, Subtable);
   2387 
   2388             /*
   2389              * Process the CID value. First, get the CID value as a string.
   2390              */
   2391             DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 16, DT_FIELD_TYPE_STRING, 0);
   2392 
   2393             if (UtIsIdInteger ((UINT8 *) &Temp64))
   2394             {
   2395                 /* Compile the CID value as an integer */
   2396 
   2397                 DtCompileOneField ((UINT8 *) &Temp64, *PFieldList, 8, DT_FIELD_TYPE_INTEGER, 0);
   2398 
   2399                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidInteger,
   2400                     &Subtable);
   2401                 if (ACPI_FAILURE (Status))
   2402                 {
   2403                     return (Status);
   2404                 }
   2405             }
   2406             else
   2407             {
   2408                 /* Compile the CID value as a string */
   2409 
   2410                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsCidString,
   2411                     &Subtable);
   2412                 if (ACPI_FAILURE (Status))
   2413                 {
   2414                     return (Status);
   2415                 }
   2416             }
   2417 
   2418             DtInsertSubtable (ParentTable, Subtable);
   2419 
   2420             /*
   2421              * Process the UID value. First, get and decode the "UID Format" field (Integer).
   2422              */
   2423             if (!*PFieldList)
   2424             {
   2425                 return (AE_OK);
   2426             }
   2427 
   2428             DtCompileOneField (&Temp8, *PFieldList, 1, DT_FIELD_TYPE_INTEGER, 0);
   2429 
   2430             switch (Temp8)
   2431             {
   2432             case ACPI_IVRS_UID_NOT_PRESENT:
   2433                 break;
   2434 
   2435             case ACPI_IVRS_UID_IS_INTEGER:
   2436 
   2437                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidInteger,
   2438                     &Subtable);
   2439                 if (ACPI_FAILURE (Status))
   2440                 {
   2441                     return (Status);
   2442                 }
   2443                 DtInsertSubtable (ParentTable, Subtable);
   2444                 break;
   2445 
   2446             case ACPI_IVRS_UID_IS_STRING:
   2447 
   2448                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsUidString,
   2449                     &Subtable);
   2450                 if (ACPI_FAILURE (Status))
   2451                 {
   2452                     return (Status);
   2453                 }
   2454                 DtInsertSubtable (ParentTable, Subtable);
   2455                 break;
   2456 
   2457             default:
   2458 
   2459                 DtFatal (ASL_MSG_UNKNOWN_FORMAT, SubtableStart,
   2460                     "IVRS Device Entry");
   2461                 return (AE_ERROR);
   2462             }
   2463 
   2464         default:
   2465 
   2466             /* All other subtable types come through here */
   2467             break;
   2468         }
   2469     }
   2470 
   2471     return (AE_OK);
   2472 }
   2473