Home | History | Annotate | Line # | Download | only in compiler
dttable1.c revision 1.1.1.7
      1 /******************************************************************************
      2  *
      3  * Module Name: dttable1.c - handling for specific ACPI tables
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2018, 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 MERCHANTIBILITY 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:    DtCompileAsf
     68  *
     69  * PARAMETERS:  List                - Current field list pointer
     70  *
     71  * RETURN:      Status
     72  *
     73  * DESCRIPTION: Compile ASF!.
     74  *
     75  *****************************************************************************/
     76 
     77 ACPI_STATUS
     78 DtCompileAsf (
     79     void                    **List)
     80 {
     81     ACPI_ASF_INFO           *AsfTable;
     82     DT_SUBTABLE             *Subtable;
     83     DT_SUBTABLE             *ParentTable;
     84     ACPI_DMTABLE_INFO       *InfoTable;
     85     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
     86     UINT32                  DataCount = 0;
     87     ACPI_STATUS             Status;
     88     UINT32                  i;
     89     DT_FIELD                **PFieldList = (DT_FIELD **) List;
     90     DT_FIELD                *SubtableStart;
     91 
     92 
     93     while (*PFieldList)
     94     {
     95         SubtableStart = *PFieldList;
     96         Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr,
     97             &Subtable);
     98         if (ACPI_FAILURE (Status))
     99         {
    100             return (Status);
    101         }
    102 
    103         ParentTable = DtPeekSubtable ();
    104         DtInsertSubtable (ParentTable, Subtable);
    105         DtPushSubtable (Subtable);
    106 
    107         AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer);
    108 
    109         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
    110         {
    111         case ACPI_ASF_TYPE_INFO:
    112 
    113             InfoTable = AcpiDmTableInfoAsf0;
    114             break;
    115 
    116         case ACPI_ASF_TYPE_ALERT:
    117 
    118             InfoTable = AcpiDmTableInfoAsf1;
    119             break;
    120 
    121         case ACPI_ASF_TYPE_CONTROL:
    122 
    123             InfoTable = AcpiDmTableInfoAsf2;
    124             break;
    125 
    126         case ACPI_ASF_TYPE_BOOT:
    127 
    128             InfoTable = AcpiDmTableInfoAsf3;
    129             break;
    130 
    131         case ACPI_ASF_TYPE_ADDRESS:
    132 
    133             InfoTable = AcpiDmTableInfoAsf4;
    134             break;
    135 
    136         default:
    137 
    138             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
    139             return (AE_ERROR);
    140         }
    141 
    142         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    143         if (ACPI_FAILURE (Status))
    144         {
    145             return (Status);
    146         }
    147 
    148         ParentTable = DtPeekSubtable ();
    149         DtInsertSubtable (ParentTable, Subtable);
    150 
    151         switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */
    152         {
    153         case ACPI_ASF_TYPE_INFO:
    154 
    155             DataInfoTable = NULL;
    156             break;
    157 
    158         case ACPI_ASF_TYPE_ALERT:
    159 
    160             DataInfoTable = AcpiDmTableInfoAsf1a;
    161             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT,
    162                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
    163                     sizeof (ACPI_ASF_HEADER)))->Alerts;
    164             break;
    165 
    166         case ACPI_ASF_TYPE_CONTROL:
    167 
    168             DataInfoTable = AcpiDmTableInfoAsf2a;
    169             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE,
    170                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
    171                     sizeof (ACPI_ASF_HEADER)))->Controls;
    172             break;
    173 
    174         case ACPI_ASF_TYPE_BOOT:
    175 
    176             DataInfoTable = NULL;
    177             break;
    178 
    179         case ACPI_ASF_TYPE_ADDRESS:
    180 
    181             DataInfoTable = TableInfoAsfAddress;
    182             DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS,
    183                 ACPI_SUB_PTR (UINT8, Subtable->Buffer,
    184                     sizeof (ACPI_ASF_HEADER)))->Devices;
    185             break;
    186 
    187         default:
    188 
    189             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!");
    190             return (AE_ERROR);
    191         }
    192 
    193         if (DataInfoTable)
    194         {
    195             switch (AsfTable->Header.Type & 0x7F)
    196             {
    197             case ACPI_ASF_TYPE_ADDRESS:
    198 
    199                 while (DataCount > 0)
    200                 {
    201                     Status = DtCompileTable (PFieldList, DataInfoTable,
    202                         &Subtable);
    203                     if (ACPI_FAILURE (Status))
    204                     {
    205                         return (Status);
    206                     }
    207 
    208                     DtInsertSubtable (ParentTable, Subtable);
    209                     DataCount = DataCount - Subtable->Length;
    210                 }
    211                 break;
    212 
    213             default:
    214 
    215                 for (i = 0; i < DataCount; i++)
    216                 {
    217                     Status = DtCompileTable (PFieldList, DataInfoTable,
    218                         &Subtable);
    219                     if (ACPI_FAILURE (Status))
    220                     {
    221                         return (Status);
    222                     }
    223 
    224                     DtInsertSubtable (ParentTable, Subtable);
    225                 }
    226                 break;
    227             }
    228         }
    229 
    230         DtPopSubtable ();
    231     }
    232 
    233     return (AE_OK);
    234 }
    235 
    236 
    237 /******************************************************************************
    238  *
    239  * FUNCTION:    DtCompileCpep
    240  *
    241  * PARAMETERS:  List                - Current field list pointer
    242  *
    243  * RETURN:      Status
    244  *
    245  * DESCRIPTION: Compile CPEP.
    246  *
    247  *****************************************************************************/
    248 
    249 ACPI_STATUS
    250 DtCompileCpep (
    251     void                    **List)
    252 {
    253     ACPI_STATUS             Status;
    254 
    255 
    256     Status = DtCompileTwoSubtables (List,
    257         AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
    258     return (Status);
    259 }
    260 
    261 
    262 /******************************************************************************
    263  *
    264  * FUNCTION:    DtCompileCsrt
    265  *
    266  * PARAMETERS:  List                - Current field list pointer
    267  *
    268  * RETURN:      Status
    269  *
    270  * DESCRIPTION: Compile CSRT.
    271  *
    272  *****************************************************************************/
    273 
    274 ACPI_STATUS
    275 DtCompileCsrt (
    276     void                    **List)
    277 {
    278     ACPI_STATUS             Status = AE_OK;
    279     DT_SUBTABLE             *Subtable;
    280     DT_SUBTABLE             *ParentTable;
    281     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    282     UINT32                  DescriptorCount;
    283     UINT32                  GroupLength;
    284 
    285 
    286     /* Subtables (Resource Groups) */
    287 
    288     ParentTable = DtPeekSubtable ();
    289     while (*PFieldList)
    290     {
    291         /* Resource group subtable */
    292 
    293         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
    294             &Subtable);
    295         if (ACPI_FAILURE (Status))
    296         {
    297             return (Status);
    298         }
    299 
    300         /* Compute the number of resource descriptors */
    301 
    302         GroupLength =
    303             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
    304                 Subtable->Buffer))->Length -
    305             (ACPI_CAST_PTR (ACPI_CSRT_GROUP,
    306                 Subtable->Buffer))->SharedInfoLength -
    307             sizeof (ACPI_CSRT_GROUP);
    308 
    309         DescriptorCount = (GroupLength  /
    310             sizeof (ACPI_CSRT_DESCRIPTOR));
    311 
    312         DtInsertSubtable (ParentTable, Subtable);
    313         DtPushSubtable (Subtable);
    314         ParentTable = DtPeekSubtable ();
    315 
    316         /* Shared info subtable (One per resource group) */
    317 
    318         Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
    319             &Subtable);
    320         if (ACPI_FAILURE (Status))
    321         {
    322             return (Status);
    323         }
    324 
    325         DtInsertSubtable (ParentTable, Subtable);
    326 
    327         /* Sub-Subtables (Resource Descriptors) */
    328 
    329         while (*PFieldList && DescriptorCount)
    330         {
    331 
    332             Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
    333                 &Subtable);
    334             if (ACPI_FAILURE (Status))
    335             {
    336                 return (Status);
    337             }
    338 
    339             DtInsertSubtable (ParentTable, Subtable);
    340 
    341             DtPushSubtable (Subtable);
    342             ParentTable = DtPeekSubtable ();
    343             if (*PFieldList)
    344             {
    345                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
    346                     &Subtable);
    347                 if (ACPI_FAILURE (Status))
    348                 {
    349                     return (Status);
    350                 }
    351                 if (Subtable)
    352                 {
    353                     DtInsertSubtable (ParentTable, Subtable);
    354                 }
    355             }
    356 
    357             DtPopSubtable ();
    358             ParentTable = DtPeekSubtable ();
    359             DescriptorCount--;
    360         }
    361 
    362         DtPopSubtable ();
    363         ParentTable = DtPeekSubtable ();
    364     }
    365 
    366     return (Status);
    367 }
    368 
    369 
    370 /******************************************************************************
    371  *
    372  * FUNCTION:    DtCompileDbg2
    373  *
    374  * PARAMETERS:  List                - Current field list pointer
    375  *
    376  * RETURN:      Status
    377  *
    378  * DESCRIPTION: Compile DBG2.
    379  *
    380  *****************************************************************************/
    381 
    382 ACPI_STATUS
    383 DtCompileDbg2 (
    384     void                    **List)
    385 {
    386     ACPI_STATUS             Status;
    387     DT_SUBTABLE             *Subtable;
    388     DT_SUBTABLE             *ParentTable;
    389     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    390     UINT32                  SubtableCount;
    391     ACPI_DBG2_HEADER        *Dbg2Header;
    392     ACPI_DBG2_DEVICE        *DeviceInfo;
    393     UINT16                  CurrentOffset;
    394     UINT32                  i;
    395 
    396 
    397     /* Main table */
    398 
    399     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable);
    400     if (ACPI_FAILURE (Status))
    401     {
    402         return (Status);
    403     }
    404 
    405     ParentTable = DtPeekSubtable ();
    406     DtInsertSubtable (ParentTable, Subtable);
    407 
    408     /* Main table fields */
    409 
    410     Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer);
    411     Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF (
    412         ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header);
    413 
    414     SubtableCount = Dbg2Header->InfoCount;
    415     DtPushSubtable (Subtable);
    416 
    417     /* Process all Device Information subtables (Count = InfoCount) */
    418 
    419     while (*PFieldList && SubtableCount)
    420     {
    421         /* Subtable: Debug Device Information */
    422 
    423         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
    424             &Subtable);
    425         if (ACPI_FAILURE (Status))
    426         {
    427             return (Status);
    428         }
    429 
    430         DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer);
    431         CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE);
    432 
    433         ParentTable = DtPeekSubtable ();
    434         DtInsertSubtable (ParentTable, Subtable);
    435         DtPushSubtable (Subtable);
    436 
    437         ParentTable = DtPeekSubtable ();
    438 
    439         /* BaseAddressRegister GAS array (Required, size is RegisterCount) */
    440 
    441         DeviceInfo->BaseAddressOffset = CurrentOffset;
    442         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
    443         {
    444             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
    445                 &Subtable);
    446             if (ACPI_FAILURE (Status))
    447             {
    448                 return (Status);
    449             }
    450 
    451             CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
    452             DtInsertSubtable (ParentTable, Subtable);
    453         }
    454 
    455         /* AddressSize array (Required, size = RegisterCount) */
    456 
    457         DeviceInfo->AddressSizeOffset = CurrentOffset;
    458         for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
    459         {
    460             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
    461                 &Subtable);
    462             if (ACPI_FAILURE (Status))
    463             {
    464                 return (Status);
    465             }
    466 
    467             CurrentOffset += (UINT16) sizeof (UINT32);
    468             DtInsertSubtable (ParentTable, Subtable);
    469         }
    470 
    471         /* NamespaceString device identifier (Required, size = NamePathLength) */
    472 
    473         DeviceInfo->NamepathOffset = CurrentOffset;
    474         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
    475             &Subtable);
    476         if (ACPI_FAILURE (Status))
    477         {
    478             return (Status);
    479         }
    480 
    481         /* Update the device info header */
    482 
    483         DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
    484         CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
    485         DtInsertSubtable (ParentTable, Subtable);
    486 
    487         /* OemData - Variable-length data (Optional, size = OemDataLength) */
    488 
    489         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
    490             &Subtable);
    491         if (Status == AE_END_OF_TABLE)
    492         {
    493             /* optional field was not found and we're at the end of the file */
    494 
    495             goto subtableDone;
    496         }
    497         else if (ACPI_FAILURE (Status))
    498         {
    499             return (Status);
    500         }
    501 
    502         /* Update the device info header (zeros if no OEM data present) */
    503 
    504         DeviceInfo->OemDataOffset = 0;
    505         DeviceInfo->OemDataLength = 0;
    506 
    507         /* Optional subtable (OemData) */
    508 
    509         if (Subtable && Subtable->Length)
    510         {
    511             DeviceInfo->OemDataOffset = CurrentOffset;
    512             DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
    513 
    514             DtInsertSubtable (ParentTable, Subtable);
    515         }
    516 subtableDone:
    517         SubtableCount--;
    518         DtPopSubtable (); /* Get next Device Information subtable */
    519     }
    520 
    521     DtPopSubtable ();
    522     return (AE_OK);
    523 }
    524 
    525 
    526 /******************************************************************************
    527  *
    528  * FUNCTION:    DtCompileDmar
    529  *
    530  * PARAMETERS:  List                - Current field list pointer
    531  *
    532  * RETURN:      Status
    533  *
    534  * DESCRIPTION: Compile DMAR.
    535  *
    536  *****************************************************************************/
    537 
    538 ACPI_STATUS
    539 DtCompileDmar (
    540     void                    **List)
    541 {
    542     ACPI_STATUS             Status;
    543     DT_SUBTABLE             *Subtable;
    544     DT_SUBTABLE             *ParentTable;
    545     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    546     DT_FIELD                *SubtableStart;
    547     ACPI_DMTABLE_INFO       *InfoTable;
    548     ACPI_DMAR_HEADER        *DmarHeader;
    549     ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
    550     UINT32                  DeviceScopeLength;
    551     UINT32                  PciPathLength;
    552 
    553 
    554     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable);
    555     if (ACPI_FAILURE (Status))
    556     {
    557         return (Status);
    558     }
    559 
    560     ParentTable = DtPeekSubtable ();
    561     DtInsertSubtable (ParentTable, Subtable);
    562     DtPushSubtable (Subtable);
    563 
    564     while (*PFieldList)
    565     {
    566         /* DMAR Header */
    567 
    568         SubtableStart = *PFieldList;
    569         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
    570             &Subtable);
    571         if (ACPI_FAILURE (Status))
    572         {
    573             return (Status);
    574         }
    575 
    576         ParentTable = DtPeekSubtable ();
    577         DtInsertSubtable (ParentTable, Subtable);
    578         DtPushSubtable (Subtable);
    579 
    580         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
    581 
    582         switch (DmarHeader->Type)
    583         {
    584         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
    585 
    586             InfoTable = AcpiDmTableInfoDmar0;
    587             break;
    588 
    589         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
    590 
    591             InfoTable = AcpiDmTableInfoDmar1;
    592             break;
    593 
    594         case ACPI_DMAR_TYPE_ROOT_ATS:
    595 
    596             InfoTable = AcpiDmTableInfoDmar2;
    597             break;
    598 
    599         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
    600 
    601             InfoTable = AcpiDmTableInfoDmar3;
    602             break;
    603 
    604         case ACPI_DMAR_TYPE_NAMESPACE:
    605 
    606             InfoTable = AcpiDmTableInfoDmar4;
    607             break;
    608 
    609         default:
    610 
    611             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
    612             return (AE_ERROR);
    613         }
    614 
    615         /* DMAR Subtable */
    616 
    617         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    618         if (ACPI_FAILURE (Status))
    619         {
    620             return (Status);
    621         }
    622 
    623         ParentTable = DtPeekSubtable ();
    624         DtInsertSubtable (ParentTable, Subtable);
    625 
    626         /*
    627          * Optional Device Scope subtables
    628          */
    629         if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
    630             (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
    631         {
    632             /* These types do not support device scopes */
    633 
    634             DtPopSubtable ();
    635             continue;
    636         }
    637 
    638         DtPushSubtable (Subtable);
    639         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
    640             ParentTable->Length;
    641         while (DeviceScopeLength)
    642         {
    643             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
    644                 &Subtable);
    645             if (Status == AE_NOT_FOUND)
    646             {
    647                 break;
    648             }
    649 
    650             ParentTable = DtPeekSubtable ();
    651             DtInsertSubtable (ParentTable, Subtable);
    652             DtPushSubtable (Subtable);
    653 
    654             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
    655 
    656             /* Optional PCI Paths */
    657 
    658             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
    659             while (PciPathLength)
    660             {
    661                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
    662                     &Subtable);
    663                 if (Status == AE_NOT_FOUND)
    664                 {
    665                     DtPopSubtable ();
    666                     break;
    667                 }
    668 
    669                 ParentTable = DtPeekSubtable ();
    670                 DtInsertSubtable (ParentTable, Subtable);
    671                 PciPathLength -= Subtable->Length;
    672             }
    673 
    674             DtPopSubtable ();
    675             DeviceScopeLength -= DmarDeviceScope->Length;
    676         }
    677 
    678         DtPopSubtable ();
    679         DtPopSubtable ();
    680     }
    681 
    682     return (AE_OK);
    683 }
    684 
    685 
    686 /******************************************************************************
    687  *
    688  * FUNCTION:    DtCompileDrtm
    689  *
    690  * PARAMETERS:  List                - Current field list pointer
    691  *
    692  * RETURN:      Status
    693  *
    694  * DESCRIPTION: Compile DRTM.
    695  *
    696  *****************************************************************************/
    697 
    698 ACPI_STATUS
    699 DtCompileDrtm (
    700     void                    **List)
    701 {
    702     ACPI_STATUS             Status;
    703     DT_SUBTABLE             *Subtable;
    704     DT_SUBTABLE             *ParentTable;
    705     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    706     UINT32                  Count;
    707     /* ACPI_TABLE_DRTM         *Drtm; */
    708     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
    709     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
    710     /* ACPI_DRTM_DPS_ID        *DrtmDps; */
    711 
    712 
    713     ParentTable = DtPeekSubtable ();
    714 
    715     /* Compile DRTM header */
    716 
    717     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
    718         &Subtable);
    719     if (ACPI_FAILURE (Status))
    720     {
    721         return (Status);
    722     }
    723     DtInsertSubtable (ParentTable, Subtable);
    724 
    725     /*
    726      * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
    727      * should be taken to avoid accessing ACPI_TABLE_HADER fields.
    728      */
    729 #if 0
    730     Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
    731         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
    732 #endif
    733     /* Compile VTL */
    734 
    735     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
    736         &Subtable);
    737     if (ACPI_FAILURE (Status))
    738     {
    739         return (Status);
    740     }
    741 
    742     DtInsertSubtable (ParentTable, Subtable);
    743     DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
    744 
    745     DtPushSubtable (Subtable);
    746     ParentTable = DtPeekSubtable ();
    747     Count = 0;
    748 
    749     while (*PFieldList)
    750     {
    751         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
    752             &Subtable);
    753         if (ACPI_FAILURE (Status))
    754         {
    755             return (Status);
    756         }
    757         if (!Subtable)
    758         {
    759             break;
    760         }
    761         DtInsertSubtable (ParentTable, Subtable);
    762         Count++;
    763     }
    764 
    765     DrtmVtl->ValidatedTableCount = Count;
    766     DtPopSubtable ();
    767     ParentTable = DtPeekSubtable ();
    768 
    769     /* Compile RL */
    770 
    771     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
    772         &Subtable);
    773     if (ACPI_FAILURE (Status))
    774     {
    775         return (Status);
    776     }
    777 
    778     DtInsertSubtable (ParentTable, Subtable);
    779     DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
    780 
    781     DtPushSubtable (Subtable);
    782     ParentTable = DtPeekSubtable ();
    783     Count = 0;
    784 
    785     while (*PFieldList)
    786     {
    787         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
    788             &Subtable);
    789         if (ACPI_FAILURE (Status))
    790         {
    791             return (Status);
    792         }
    793 
    794         if (!Subtable)
    795         {
    796             break;
    797         }
    798 
    799         DtInsertSubtable (ParentTable, Subtable);
    800         Count++;
    801     }
    802 
    803     DrtmRl->ResourceCount = Count;
    804     DtPopSubtable ();
    805     ParentTable = DtPeekSubtable ();
    806 
    807     /* Compile DPS */
    808 
    809     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
    810         &Subtable);
    811     if (ACPI_FAILURE (Status))
    812     {
    813         return (Status);
    814     }
    815     DtInsertSubtable (ParentTable, Subtable);
    816     /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
    817 
    818 
    819     return (AE_OK);
    820 }
    821 
    822 
    823 /******************************************************************************
    824  *
    825  * FUNCTION:    DtCompileEinj
    826  *
    827  * PARAMETERS:  List                - Current field list pointer
    828  *
    829  * RETURN:      Status
    830  *
    831  * DESCRIPTION: Compile EINJ.
    832  *
    833  *****************************************************************************/
    834 
    835 ACPI_STATUS
    836 DtCompileEinj (
    837     void                    **List)
    838 {
    839     ACPI_STATUS             Status;
    840 
    841 
    842     Status = DtCompileTwoSubtables (List,
    843         AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
    844     return (Status);
    845 }
    846 
    847 
    848 /******************************************************************************
    849  *
    850  * FUNCTION:    DtCompileErst
    851  *
    852  * PARAMETERS:  List                - Current field list pointer
    853  *
    854  * RETURN:      Status
    855  *
    856  * DESCRIPTION: Compile ERST.
    857  *
    858  *****************************************************************************/
    859 
    860 ACPI_STATUS
    861 DtCompileErst (
    862     void                    **List)
    863 {
    864     ACPI_STATUS             Status;
    865 
    866 
    867     Status = DtCompileTwoSubtables (List,
    868         AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
    869     return (Status);
    870 }
    871 
    872 
    873 /******************************************************************************
    874  *
    875  * FUNCTION:    DtCompileGtdt
    876  *
    877  * PARAMETERS:  List                - Current field list pointer
    878  *
    879  * RETURN:      Status
    880  *
    881  * DESCRIPTION: Compile GTDT.
    882  *
    883  *****************************************************************************/
    884 
    885 ACPI_STATUS
    886 DtCompileGtdt (
    887     void                    **List)
    888 {
    889     ACPI_STATUS             Status;
    890     DT_SUBTABLE             *Subtable;
    891     DT_SUBTABLE             *ParentTable;
    892     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    893     DT_FIELD                *SubtableStart;
    894     ACPI_SUBTABLE_HEADER    *GtdtHeader;
    895     ACPI_DMTABLE_INFO       *InfoTable;
    896     UINT32                  GtCount;
    897 
    898 
    899     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
    900         &Subtable);
    901     if (ACPI_FAILURE (Status))
    902     {
    903         return (Status);
    904     }
    905 
    906     ParentTable = DtPeekSubtable ();
    907     DtInsertSubtable (ParentTable, Subtable);
    908 
    909     while (*PFieldList)
    910     {
    911         SubtableStart = *PFieldList;
    912         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
    913             &Subtable);
    914         if (ACPI_FAILURE (Status))
    915         {
    916             return (Status);
    917         }
    918 
    919         ParentTable = DtPeekSubtable ();
    920         DtInsertSubtable (ParentTable, Subtable);
    921         DtPushSubtable (Subtable);
    922 
    923         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
    924 
    925         switch (GtdtHeader->Type)
    926         {
    927         case ACPI_GTDT_TYPE_TIMER_BLOCK:
    928 
    929             InfoTable = AcpiDmTableInfoGtdt0;
    930             break;
    931 
    932         case ACPI_GTDT_TYPE_WATCHDOG:
    933 
    934             InfoTable = AcpiDmTableInfoGtdt1;
    935             break;
    936 
    937         default:
    938 
    939             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
    940             return (AE_ERROR);
    941         }
    942 
    943         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    944         if (ACPI_FAILURE (Status))
    945         {
    946             return (Status);
    947         }
    948 
    949         ParentTable = DtPeekSubtable ();
    950         DtInsertSubtable (ParentTable, Subtable);
    951 
    952         /*
    953          * Additional GT block subtable data
    954          */
    955 
    956         switch (GtdtHeader->Type)
    957         {
    958         case ACPI_GTDT_TYPE_TIMER_BLOCK:
    959 
    960             DtPushSubtable (Subtable);
    961             ParentTable = DtPeekSubtable ();
    962 
    963             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
    964                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
    965 
    966             while (GtCount)
    967             {
    968                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
    969                     &Subtable);
    970                 if (ACPI_FAILURE (Status))
    971                 {
    972                     return (Status);
    973                 }
    974 
    975                 DtInsertSubtable (ParentTable, Subtable);
    976                 GtCount--;
    977             }
    978 
    979             DtPopSubtable ();
    980             break;
    981 
    982         default:
    983 
    984             break;
    985         }
    986 
    987         DtPopSubtable ();
    988     }
    989 
    990     return (AE_OK);
    991 }
    992 
    993 
    994 /******************************************************************************
    995  *
    996  * FUNCTION:    DtCompileFpdt
    997  *
    998  * PARAMETERS:  List                - Current field list pointer
    999  *
   1000  * RETURN:      Status
   1001  *
   1002  * DESCRIPTION: Compile FPDT.
   1003  *
   1004  *****************************************************************************/
   1005 
   1006 ACPI_STATUS
   1007 DtCompileFpdt (
   1008     void                    **List)
   1009 {
   1010     ACPI_STATUS             Status;
   1011     ACPI_FPDT_HEADER        *FpdtHeader;
   1012     DT_SUBTABLE             *Subtable;
   1013     DT_SUBTABLE             *ParentTable;
   1014     ACPI_DMTABLE_INFO       *InfoTable;
   1015     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1016     DT_FIELD                *SubtableStart;
   1017 
   1018 
   1019     while (*PFieldList)
   1020     {
   1021         SubtableStart = *PFieldList;
   1022         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
   1023             &Subtable);
   1024         if (ACPI_FAILURE (Status))
   1025         {
   1026             return (Status);
   1027         }
   1028 
   1029         ParentTable = DtPeekSubtable ();
   1030         DtInsertSubtable (ParentTable, Subtable);
   1031         DtPushSubtable (Subtable);
   1032 
   1033         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
   1034 
   1035         switch (FpdtHeader->Type)
   1036         {
   1037         case ACPI_FPDT_TYPE_BOOT:
   1038 
   1039             InfoTable = AcpiDmTableInfoFpdt0;
   1040             break;
   1041 
   1042         case ACPI_FPDT_TYPE_S3PERF:
   1043 
   1044             InfoTable = AcpiDmTableInfoFpdt1;
   1045             break;
   1046 
   1047         default:
   1048 
   1049             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
   1050             return (AE_ERROR);
   1051             break;
   1052         }
   1053 
   1054         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1055         if (ACPI_FAILURE (Status))
   1056         {
   1057             return (Status);
   1058         }
   1059 
   1060         ParentTable = DtPeekSubtable ();
   1061         DtInsertSubtable (ParentTable, Subtable);
   1062         DtPopSubtable ();
   1063     }
   1064 
   1065     return (AE_OK);
   1066 }
   1067 
   1068 
   1069 /******************************************************************************
   1070  *
   1071  * FUNCTION:    DtCompileHest
   1072  *
   1073  * PARAMETERS:  List                - Current field list pointer
   1074  *
   1075  * RETURN:      Status
   1076  *
   1077  * DESCRIPTION: Compile HEST.
   1078  *
   1079  *****************************************************************************/
   1080 
   1081 ACPI_STATUS
   1082 DtCompileHest (
   1083     void                    **List)
   1084 {
   1085     ACPI_STATUS             Status;
   1086     DT_SUBTABLE             *Subtable;
   1087     DT_SUBTABLE             *ParentTable;
   1088     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1089     DT_FIELD                *SubtableStart;
   1090     ACPI_DMTABLE_INFO       *InfoTable;
   1091     UINT16                  Type;
   1092     UINT32                  BankCount;
   1093 
   1094 
   1095     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
   1096         &Subtable);
   1097     if (ACPI_FAILURE (Status))
   1098     {
   1099         return (Status);
   1100     }
   1101 
   1102     ParentTable = DtPeekSubtable ();
   1103     DtInsertSubtable (ParentTable, Subtable);
   1104 
   1105     while (*PFieldList)
   1106     {
   1107         /* Get subtable type */
   1108 
   1109         SubtableStart = *PFieldList;
   1110         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
   1111 
   1112         switch (Type)
   1113         {
   1114         case ACPI_HEST_TYPE_IA32_CHECK:
   1115 
   1116             InfoTable = AcpiDmTableInfoHest0;
   1117             break;
   1118 
   1119         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   1120 
   1121             InfoTable = AcpiDmTableInfoHest1;
   1122             break;
   1123 
   1124         case ACPI_HEST_TYPE_IA32_NMI:
   1125 
   1126             InfoTable = AcpiDmTableInfoHest2;
   1127             break;
   1128 
   1129         case ACPI_HEST_TYPE_AER_ROOT_PORT:
   1130 
   1131             InfoTable = AcpiDmTableInfoHest6;
   1132             break;
   1133 
   1134         case ACPI_HEST_TYPE_AER_ENDPOINT:
   1135 
   1136             InfoTable = AcpiDmTableInfoHest7;
   1137             break;
   1138 
   1139         case ACPI_HEST_TYPE_AER_BRIDGE:
   1140 
   1141             InfoTable = AcpiDmTableInfoHest8;
   1142             break;
   1143 
   1144         case ACPI_HEST_TYPE_GENERIC_ERROR:
   1145 
   1146             InfoTable = AcpiDmTableInfoHest9;
   1147             break;
   1148 
   1149         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
   1150 
   1151             InfoTable = AcpiDmTableInfoHest10;
   1152             break;
   1153 
   1154         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   1155 
   1156             InfoTable = AcpiDmTableInfoHest11;
   1157             break;
   1158 
   1159         default:
   1160 
   1161             /* Cannot continue on unknown type */
   1162 
   1163             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
   1164             return (AE_ERROR);
   1165         }
   1166 
   1167         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1168         if (ACPI_FAILURE (Status))
   1169         {
   1170             return (Status);
   1171         }
   1172 
   1173         DtInsertSubtable (ParentTable, Subtable);
   1174 
   1175         /*
   1176          * Additional subtable data - IA32 Error Bank(s)
   1177          */
   1178         BankCount = 0;
   1179         switch (Type)
   1180         {
   1181         case ACPI_HEST_TYPE_IA32_CHECK:
   1182 
   1183             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
   1184                 Subtable->Buffer))->NumHardwareBanks;
   1185             break;
   1186 
   1187         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   1188 
   1189             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
   1190                 Subtable->Buffer))->NumHardwareBanks;
   1191             break;
   1192 
   1193         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   1194 
   1195             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
   1196                 Subtable->Buffer))->NumHardwareBanks;
   1197             break;
   1198 
   1199         default:
   1200 
   1201             break;
   1202         }
   1203 
   1204         while (BankCount)
   1205         {
   1206             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
   1207                 &Subtable);
   1208             if (ACPI_FAILURE (Status))
   1209             {
   1210                 return (Status);
   1211             }
   1212 
   1213             DtInsertSubtable (ParentTable, Subtable);
   1214             BankCount--;
   1215         }
   1216     }
   1217 
   1218     return (AE_OK);
   1219 }
   1220 
   1221 
   1222 /******************************************************************************
   1223  *
   1224  * FUNCTION:    DtCompileHmat
   1225  *
   1226  * PARAMETERS:  List                - Current field list pointer
   1227  *
   1228  * RETURN:      Status
   1229  *
   1230  * DESCRIPTION: Compile HMAT.
   1231  *
   1232  *****************************************************************************/
   1233 
   1234 ACPI_STATUS
   1235 DtCompileHmat (
   1236     void                    **List)
   1237 {
   1238     ACPI_STATUS             Status;
   1239     DT_SUBTABLE             *Subtable;
   1240     DT_SUBTABLE             *ParentTable;
   1241     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1242     DT_FIELD                *SubtableStart;
   1243     DT_FIELD                *EntryStart;
   1244     ACPI_HMAT_STRUCTURE     *HmatStruct;
   1245     ACPI_HMAT_LOCALITY      *HmatLocality;
   1246     ACPI_HMAT_CACHE         *HmatCache;
   1247     ACPI_DMTABLE_INFO       *InfoTable;
   1248     UINT32                  IntPDNumber;
   1249     UINT32                  TgtPDNumber;
   1250     UINT64                  EntryNumber;
   1251     UINT16                  SMBIOSHandleNumber;
   1252 
   1253 
   1254     ParentTable = DtPeekSubtable ();
   1255 
   1256     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
   1257         &Subtable);
   1258     if (ACPI_FAILURE (Status))
   1259     {
   1260         return (Status);
   1261     }
   1262     DtInsertSubtable (ParentTable, Subtable);
   1263 
   1264     while (*PFieldList)
   1265     {
   1266         /* Compile HMAT structure header */
   1267 
   1268         SubtableStart = *PFieldList;
   1269         Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
   1270             &Subtable);
   1271         if (ACPI_FAILURE (Status))
   1272         {
   1273             return (Status);
   1274         }
   1275         DtInsertSubtable (ParentTable, Subtable);
   1276 
   1277         HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
   1278         HmatStruct->Length = Subtable->Length;
   1279 
   1280         /* Compile HMAT structure body */
   1281 
   1282         switch (HmatStruct->Type)
   1283         {
   1284         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
   1285 
   1286             InfoTable = AcpiDmTableInfoHmat0;
   1287             break;
   1288 
   1289         case ACPI_HMAT_TYPE_LOCALITY:
   1290 
   1291             InfoTable = AcpiDmTableInfoHmat1;
   1292             break;
   1293 
   1294         case ACPI_HMAT_TYPE_CACHE:
   1295 
   1296             InfoTable = AcpiDmTableInfoHmat2;
   1297             break;
   1298 
   1299         default:
   1300 
   1301             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
   1302             return (AE_ERROR);
   1303         }
   1304 
   1305         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1306         if (ACPI_FAILURE (Status))
   1307         {
   1308             return (Status);
   1309         }
   1310         DtInsertSubtable (ParentTable, Subtable);
   1311         HmatStruct->Length += Subtable->Length;
   1312 
   1313         /* Compile HMAT structure additionals */
   1314 
   1315         switch (HmatStruct->Type)
   1316         {
   1317         case ACPI_HMAT_TYPE_LOCALITY:
   1318 
   1319             HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
   1320                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   1321 
   1322             /* Compile initiator proximity domain list */
   1323 
   1324             IntPDNumber = 0;
   1325             while (*PFieldList)
   1326             {
   1327                 Status = DtCompileTable (PFieldList,
   1328                     AcpiDmTableInfoHmat1a, &Subtable);
   1329                 if (ACPI_FAILURE (Status))
   1330                 {
   1331                     return (Status);
   1332                 }
   1333                 if (!Subtable)
   1334                 {
   1335                     break;
   1336                 }
   1337                 DtInsertSubtable (ParentTable, Subtable);
   1338                 HmatStruct->Length += Subtable->Length;
   1339                 IntPDNumber++;
   1340             }
   1341             HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
   1342 
   1343             /* Compile target proximity domain list */
   1344 
   1345             TgtPDNumber = 0;
   1346             while (*PFieldList)
   1347             {
   1348                 Status = DtCompileTable (PFieldList,
   1349                     AcpiDmTableInfoHmat1b, &Subtable);
   1350                 if (ACPI_FAILURE (Status))
   1351                 {
   1352                     return (Status);
   1353                 }
   1354                 if (!Subtable)
   1355                 {
   1356                     break;
   1357                 }
   1358                 DtInsertSubtable (ParentTable, Subtable);
   1359                 HmatStruct->Length += Subtable->Length;
   1360                 TgtPDNumber++;
   1361             }
   1362             HmatLocality->NumberOfTargetPDs = TgtPDNumber;
   1363 
   1364             /* Save start of the entries for reporting errors */
   1365 
   1366             EntryStart = *PFieldList;
   1367 
   1368             /* Compile latency/bandwidth entries */
   1369 
   1370             EntryNumber = 0;
   1371             while (*PFieldList)
   1372             {
   1373                 Status = DtCompileTable (PFieldList,
   1374                     AcpiDmTableInfoHmat1c, &Subtable);
   1375                 if (ACPI_FAILURE (Status))
   1376                 {
   1377                     return (Status);
   1378                 }
   1379                 if (!Subtable)
   1380                 {
   1381                     break;
   1382                 }
   1383                 DtInsertSubtable (ParentTable, Subtable);
   1384                 HmatStruct->Length += Subtable->Length;
   1385                 EntryNumber++;
   1386             }
   1387 
   1388             /* Validate number of entries */
   1389 
   1390             if (EntryNumber !=
   1391                 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
   1392             {
   1393                 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
   1394                 return (AE_ERROR);
   1395             }
   1396             break;
   1397 
   1398         case ACPI_HMAT_TYPE_CACHE:
   1399 
   1400             /* Compile SMBIOS handles */
   1401 
   1402             HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
   1403                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   1404             SMBIOSHandleNumber = 0;
   1405             while (*PFieldList)
   1406             {
   1407                 Status = DtCompileTable (PFieldList,
   1408                     AcpiDmTableInfoHmat2a, &Subtable);
   1409                 if (ACPI_FAILURE (Status))
   1410                 {
   1411                     return (Status);
   1412                 }
   1413                 if (!Subtable)
   1414                 {
   1415                     break;
   1416                 }
   1417                 DtInsertSubtable (ParentTable, Subtable);
   1418                 HmatStruct->Length += Subtable->Length;
   1419                 SMBIOSHandleNumber++;
   1420             }
   1421             HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
   1422             break;
   1423 
   1424         default:
   1425 
   1426             break;
   1427         }
   1428     }
   1429 
   1430     return (AE_OK);
   1431 }
   1432 
   1433 
   1434 /******************************************************************************
   1435  *
   1436  * FUNCTION:    DtCompileIort
   1437  *
   1438  * PARAMETERS:  List                - Current field list pointer
   1439  *
   1440  * RETURN:      Status
   1441  *
   1442  * DESCRIPTION: Compile IORT.
   1443  *
   1444  *****************************************************************************/
   1445 
   1446 ACPI_STATUS
   1447 DtCompileIort (
   1448     void                    **List)
   1449 {
   1450     ACPI_STATUS             Status;
   1451     DT_SUBTABLE             *Subtable;
   1452     DT_SUBTABLE             *ParentTable;
   1453     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1454     DT_FIELD                *SubtableStart;
   1455     ACPI_TABLE_IORT         *Iort;
   1456     ACPI_IORT_NODE          *IortNode;
   1457     ACPI_IORT_ITS_GROUP     *IortItsGroup;
   1458     ACPI_IORT_SMMU          *IortSmmu;
   1459     UINT32                  NodeNumber;
   1460     UINT32                  NodeLength;
   1461     UINT32                  IdMappingNumber;
   1462     UINT32                  ItsNumber;
   1463     UINT32                  ContextIrptNumber;
   1464     UINT32                  PmuIrptNumber;
   1465     UINT32                  PaddingLength;
   1466 
   1467 
   1468     ParentTable = DtPeekSubtable ();
   1469 
   1470     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
   1471         &Subtable);
   1472     if (ACPI_FAILURE (Status))
   1473     {
   1474         return (Status);
   1475     }
   1476     DtInsertSubtable (ParentTable, Subtable);
   1477 
   1478     /*
   1479      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   1480      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
   1481      */
   1482     Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
   1483         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
   1484 
   1485     /*
   1486      * OptionalPadding - Variable-length data
   1487      * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
   1488      * Optionally allows the generic data types to be used for filling
   1489      * this field.
   1490      */
   1491     Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
   1492     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
   1493         &Subtable);
   1494     if (ACPI_FAILURE (Status))
   1495     {
   1496         return (Status);
   1497     }
   1498     if (Subtable)
   1499     {
   1500         DtInsertSubtable (ParentTable, Subtable);
   1501         Iort->NodeOffset += Subtable->Length;
   1502     }
   1503     else
   1504     {
   1505         Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
   1506             AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
   1507         if (ACPI_FAILURE (Status))
   1508         {
   1509             return (Status);
   1510         }
   1511         Iort->NodeOffset += PaddingLength;
   1512     }
   1513 
   1514     NodeNumber = 0;
   1515     while (*PFieldList)
   1516     {
   1517         SubtableStart = *PFieldList;
   1518         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
   1519             &Subtable);
   1520         if (ACPI_FAILURE (Status))
   1521         {
   1522             return (Status);
   1523         }
   1524 
   1525         DtInsertSubtable (ParentTable, Subtable);
   1526         IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
   1527         NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
   1528 
   1529         DtPushSubtable (Subtable);
   1530         ParentTable = DtPeekSubtable ();
   1531 
   1532         switch (IortNode->Type)
   1533         {
   1534         case ACPI_IORT_NODE_ITS_GROUP:
   1535 
   1536             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
   1537                 &Subtable);
   1538             if (ACPI_FAILURE (Status))
   1539             {
   1540                 return (Status);
   1541             }
   1542 
   1543             DtInsertSubtable (ParentTable, Subtable);
   1544             IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
   1545             NodeLength += Subtable->Length;
   1546 
   1547             ItsNumber = 0;
   1548             while (*PFieldList)
   1549             {
   1550                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
   1551                     &Subtable);
   1552                 if (ACPI_FAILURE (Status))
   1553                 {
   1554                     return (Status);
   1555                 }
   1556                 if (!Subtable)
   1557                 {
   1558                     break;
   1559                 }
   1560 
   1561                 DtInsertSubtable (ParentTable, Subtable);
   1562                 NodeLength += Subtable->Length;
   1563                 ItsNumber++;
   1564             }
   1565 
   1566             IortItsGroup->ItsCount = ItsNumber;
   1567             break;
   1568 
   1569         case ACPI_IORT_NODE_NAMED_COMPONENT:
   1570 
   1571             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
   1572                 &Subtable);
   1573             if (ACPI_FAILURE (Status))
   1574             {
   1575                 return (Status);
   1576             }
   1577 
   1578             DtInsertSubtable (ParentTable, Subtable);
   1579             NodeLength += Subtable->Length;
   1580 
   1581             /*
   1582              * Padding - Variable-length data
   1583              * Optionally allows the offset of the ID mappings to be used
   1584              * for filling this field.
   1585              */
   1586             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
   1587                 &Subtable);
   1588             if (ACPI_FAILURE (Status))
   1589             {
   1590                 return (Status);
   1591             }
   1592 
   1593             if (Subtable)
   1594             {
   1595                 DtInsertSubtable (ParentTable, Subtable);
   1596                 NodeLength += Subtable->Length;
   1597             }
   1598             else
   1599             {
   1600                 if (NodeLength > IortNode->MappingOffset)
   1601                 {
   1602                     return (AE_BAD_DATA);
   1603                 }
   1604 
   1605                 if (NodeLength < IortNode->MappingOffset)
   1606                 {
   1607                     Status = DtCompilePadding (
   1608                         IortNode->MappingOffset - NodeLength,
   1609                         &Subtable);
   1610                     if (ACPI_FAILURE (Status))
   1611                     {
   1612                         return (Status);
   1613                     }
   1614 
   1615                     DtInsertSubtable (ParentTable, Subtable);
   1616                     NodeLength = IortNode->MappingOffset;
   1617                 }
   1618             }
   1619             break;
   1620 
   1621         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
   1622 
   1623             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
   1624                 &Subtable);
   1625             if (ACPI_FAILURE (Status))
   1626             {
   1627                 return (Status);
   1628             }
   1629 
   1630             DtInsertSubtable (ParentTable, Subtable);
   1631             NodeLength += Subtable->Length;
   1632             break;
   1633 
   1634         case ACPI_IORT_NODE_SMMU:
   1635 
   1636             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
   1637                 &Subtable);
   1638             if (ACPI_FAILURE (Status))
   1639             {
   1640                 return (Status);
   1641             }
   1642 
   1643             DtInsertSubtable (ParentTable, Subtable);
   1644             IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
   1645             NodeLength += Subtable->Length;
   1646 
   1647             /* Compile global interrupt array */
   1648 
   1649             IortSmmu->GlobalInterruptOffset = NodeLength;
   1650             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
   1651                 &Subtable);
   1652             if (ACPI_FAILURE (Status))
   1653             {
   1654                 return (Status);
   1655             }
   1656 
   1657             DtInsertSubtable (ParentTable, Subtable);
   1658             NodeLength += Subtable->Length;
   1659 
   1660             /* Compile context interrupt array */
   1661 
   1662             ContextIrptNumber = 0;
   1663             IortSmmu->ContextInterruptOffset = NodeLength;
   1664             while (*PFieldList)
   1665             {
   1666                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
   1667                     &Subtable);
   1668                 if (ACPI_FAILURE (Status))
   1669                 {
   1670                     return (Status);
   1671                 }
   1672 
   1673                 if (!Subtable)
   1674                 {
   1675                     break;
   1676                 }
   1677 
   1678                 DtInsertSubtable (ParentTable, Subtable);
   1679                 NodeLength += Subtable->Length;
   1680                 ContextIrptNumber++;
   1681             }
   1682 
   1683             IortSmmu->ContextInterruptCount = ContextIrptNumber;
   1684 
   1685             /* Compile PMU interrupt array */
   1686 
   1687             PmuIrptNumber = 0;
   1688             IortSmmu->PmuInterruptOffset = NodeLength;
   1689             while (*PFieldList)
   1690             {
   1691                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
   1692                     &Subtable);
   1693                 if (ACPI_FAILURE (Status))
   1694                 {
   1695                     return (Status);
   1696                 }
   1697 
   1698                 if (!Subtable)
   1699                 {
   1700                     break;
   1701                 }
   1702 
   1703                 DtInsertSubtable (ParentTable, Subtable);
   1704                 NodeLength += Subtable->Length;
   1705                 PmuIrptNumber++;
   1706             }
   1707 
   1708             IortSmmu->PmuInterruptCount = PmuIrptNumber;
   1709             break;
   1710 
   1711         case ACPI_IORT_NODE_SMMU_V3:
   1712 
   1713             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
   1714                 &Subtable);
   1715             if (ACPI_FAILURE (Status))
   1716             {
   1717                 return (Status);
   1718             }
   1719 
   1720             DtInsertSubtable (ParentTable, Subtable);
   1721             NodeLength += Subtable->Length;
   1722             break;
   1723 
   1724         default:
   1725 
   1726             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
   1727             return (AE_ERROR);
   1728         }
   1729 
   1730         /* Compile Array of ID mappings */
   1731 
   1732         IortNode->MappingOffset = NodeLength;
   1733         IdMappingNumber = 0;
   1734         while (*PFieldList)
   1735         {
   1736             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
   1737                 &Subtable);
   1738             if (ACPI_FAILURE (Status))
   1739             {
   1740                 return (Status);
   1741             }
   1742 
   1743             if (!Subtable)
   1744             {
   1745                 break;
   1746             }
   1747 
   1748             DtInsertSubtable (ParentTable, Subtable);
   1749             NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
   1750             IdMappingNumber++;
   1751         }
   1752 
   1753         IortNode->MappingCount = IdMappingNumber;
   1754         if (!IdMappingNumber)
   1755         {
   1756             IortNode->MappingOffset = 0;
   1757         }
   1758 
   1759         /*
   1760          * Node length can be determined by DT_LENGTH option
   1761          * IortNode->Length = NodeLength;
   1762          */
   1763         DtPopSubtable ();
   1764         ParentTable = DtPeekSubtable ();
   1765         NodeNumber++;
   1766     }
   1767 
   1768     Iort->NodeCount = NodeNumber;
   1769     return (AE_OK);
   1770 }
   1771 
   1772 
   1773 /******************************************************************************
   1774  *
   1775  * FUNCTION:    DtCompileIvrs
   1776  *
   1777  * PARAMETERS:  List                - Current field list pointer
   1778  *
   1779  * RETURN:      Status
   1780  *
   1781  * DESCRIPTION: Compile IVRS.
   1782  *
   1783  *****************************************************************************/
   1784 
   1785 ACPI_STATUS
   1786 DtCompileIvrs (
   1787     void                    **List)
   1788 {
   1789     ACPI_STATUS             Status;
   1790     DT_SUBTABLE             *Subtable;
   1791     DT_SUBTABLE             *ParentTable;
   1792     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1793     DT_FIELD                *SubtableStart;
   1794     ACPI_DMTABLE_INFO       *InfoTable;
   1795     ACPI_IVRS_HEADER        *IvrsHeader;
   1796     UINT8                   EntryType;
   1797 
   1798 
   1799     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
   1800         &Subtable);
   1801     if (ACPI_FAILURE (Status))
   1802     {
   1803         return (Status);
   1804     }
   1805 
   1806     ParentTable = DtPeekSubtable ();
   1807     DtInsertSubtable (ParentTable, Subtable);
   1808 
   1809     while (*PFieldList)
   1810     {
   1811         SubtableStart = *PFieldList;
   1812         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
   1813             &Subtable);
   1814         if (ACPI_FAILURE (Status))
   1815         {
   1816             return (Status);
   1817         }
   1818 
   1819         ParentTable = DtPeekSubtable ();
   1820         DtInsertSubtable (ParentTable, Subtable);
   1821         DtPushSubtable (Subtable);
   1822 
   1823         IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
   1824 
   1825         switch (IvrsHeader->Type)
   1826         {
   1827         case ACPI_IVRS_TYPE_HARDWARE:
   1828 
   1829             InfoTable = AcpiDmTableInfoIvrs0;
   1830             break;
   1831 
   1832         case ACPI_IVRS_TYPE_MEMORY1:
   1833         case ACPI_IVRS_TYPE_MEMORY2:
   1834         case ACPI_IVRS_TYPE_MEMORY3:
   1835 
   1836             InfoTable = AcpiDmTableInfoIvrs1;
   1837             break;
   1838 
   1839         default:
   1840 
   1841             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
   1842             return (AE_ERROR);
   1843         }
   1844 
   1845         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1846         if (ACPI_FAILURE (Status))
   1847         {
   1848             return (Status);
   1849         }
   1850 
   1851         ParentTable = DtPeekSubtable ();
   1852         DtInsertSubtable (ParentTable, Subtable);
   1853 
   1854         if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
   1855         {
   1856             while (*PFieldList &&
   1857                 !strcmp ((*PFieldList)->Name, "Entry Type"))
   1858             {
   1859                 SubtableStart = *PFieldList;
   1860                 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
   1861 
   1862                 switch (EntryType)
   1863                 {
   1864                 /* 4-byte device entries */
   1865 
   1866                 case ACPI_IVRS_TYPE_PAD4:
   1867                 case ACPI_IVRS_TYPE_ALL:
   1868                 case ACPI_IVRS_TYPE_SELECT:
   1869                 case ACPI_IVRS_TYPE_START:
   1870                 case ACPI_IVRS_TYPE_END:
   1871 
   1872                     InfoTable = AcpiDmTableInfoIvrs4;
   1873                     break;
   1874 
   1875                 /* 8-byte entries, type A */
   1876 
   1877                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
   1878                 case ACPI_IVRS_TYPE_ALIAS_START:
   1879 
   1880                     InfoTable = AcpiDmTableInfoIvrs8a;
   1881                     break;
   1882 
   1883                 /* 8-byte entries, type B */
   1884 
   1885                 case ACPI_IVRS_TYPE_PAD8:
   1886                 case ACPI_IVRS_TYPE_EXT_SELECT:
   1887                 case ACPI_IVRS_TYPE_EXT_START:
   1888 
   1889                     InfoTable = AcpiDmTableInfoIvrs8b;
   1890                     break;
   1891 
   1892                 /* 8-byte entries, type C */
   1893 
   1894                 case ACPI_IVRS_TYPE_SPECIAL:
   1895 
   1896                     InfoTable = AcpiDmTableInfoIvrs8c;
   1897                     break;
   1898 
   1899                 default:
   1900 
   1901                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
   1902                         "IVRS Device Entry");
   1903                     return (AE_ERROR);
   1904                 }
   1905 
   1906                 Status = DtCompileTable (PFieldList, InfoTable,
   1907                     &Subtable);
   1908                 if (ACPI_FAILURE (Status))
   1909                 {
   1910                     return (Status);
   1911                 }
   1912 
   1913                 DtInsertSubtable (ParentTable, Subtable);
   1914             }
   1915         }
   1916 
   1917         DtPopSubtable ();
   1918     }
   1919 
   1920     return (AE_OK);
   1921 }
   1922