Home | History | Annotate | Line # | Download | only in compiler
dttable1.c revision 1.1.1.10
      1 /******************************************************************************
      2  *
      3  * Module Name: dttable1.c - handling for specific ACPI tables
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2020, 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 separate 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     ACPI_TABLE_HEADER       *Header;
    898 
    899 
    900     ParentTable = DtPeekSubtable ();
    901 
    902     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
    903 
    904     /* Compile the main table */
    905 
    906     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
    907         &Subtable);
    908     if (ACPI_FAILURE (Status))
    909     {
    910         return (Status);
    911     }
    912 
    913     /* GTDT revision 3 later contains 2 extra fields before subtables */
    914 
    915     if (Header->Revision > 2)
    916     {
    917         ParentTable = DtPeekSubtable ();
    918         DtInsertSubtable (ParentTable, Subtable);
    919 
    920         Status = DtCompileTable (PFieldList,
    921             AcpiDmTableInfoGtdtEl2, &Subtable);
    922         if (ACPI_FAILURE (Status))
    923         {
    924             return (Status);
    925         }
    926     }
    927 
    928     ParentTable = DtPeekSubtable ();
    929     DtInsertSubtable (ParentTable, Subtable);
    930 
    931     while (*PFieldList)
    932     {
    933         SubtableStart = *PFieldList;
    934         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
    935             &Subtable);
    936         if (ACPI_FAILURE (Status))
    937         {
    938             return (Status);
    939         }
    940 
    941         ParentTable = DtPeekSubtable ();
    942         DtInsertSubtable (ParentTable, Subtable);
    943         DtPushSubtable (Subtable);
    944 
    945         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
    946 
    947         switch (GtdtHeader->Type)
    948         {
    949         case ACPI_GTDT_TYPE_TIMER_BLOCK:
    950 
    951             InfoTable = AcpiDmTableInfoGtdt0;
    952             break;
    953 
    954         case ACPI_GTDT_TYPE_WATCHDOG:
    955 
    956             InfoTable = AcpiDmTableInfoGtdt1;
    957             break;
    958 
    959         default:
    960 
    961             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
    962             return (AE_ERROR);
    963         }
    964 
    965         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    966         if (ACPI_FAILURE (Status))
    967         {
    968             return (Status);
    969         }
    970 
    971         ParentTable = DtPeekSubtable ();
    972         DtInsertSubtable (ParentTable, Subtable);
    973 
    974         /*
    975          * Additional GT block subtable data
    976          */
    977 
    978         switch (GtdtHeader->Type)
    979         {
    980         case ACPI_GTDT_TYPE_TIMER_BLOCK:
    981 
    982             DtPushSubtable (Subtable);
    983             ParentTable = DtPeekSubtable ();
    984 
    985             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
    986                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
    987 
    988             while (GtCount)
    989             {
    990                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
    991                     &Subtable);
    992                 if (ACPI_FAILURE (Status))
    993                 {
    994                     return (Status);
    995                 }
    996 
    997                 DtInsertSubtable (ParentTable, Subtable);
    998                 GtCount--;
    999             }
   1000 
   1001             DtPopSubtable ();
   1002             break;
   1003 
   1004         default:
   1005 
   1006             break;
   1007         }
   1008 
   1009         DtPopSubtable ();
   1010     }
   1011 
   1012     return (AE_OK);
   1013 }
   1014 
   1015 
   1016 /******************************************************************************
   1017  *
   1018  * FUNCTION:    DtCompileFpdt
   1019  *
   1020  * PARAMETERS:  List                - Current field list pointer
   1021  *
   1022  * RETURN:      Status
   1023  *
   1024  * DESCRIPTION: Compile FPDT.
   1025  *
   1026  *****************************************************************************/
   1027 
   1028 ACPI_STATUS
   1029 DtCompileFpdt (
   1030     void                    **List)
   1031 {
   1032     ACPI_STATUS             Status;
   1033     ACPI_FPDT_HEADER        *FpdtHeader;
   1034     DT_SUBTABLE             *Subtable;
   1035     DT_SUBTABLE             *ParentTable;
   1036     ACPI_DMTABLE_INFO       *InfoTable;
   1037     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1038     DT_FIELD                *SubtableStart;
   1039 
   1040 
   1041     while (*PFieldList)
   1042     {
   1043         SubtableStart = *PFieldList;
   1044         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
   1045             &Subtable);
   1046         if (ACPI_FAILURE (Status))
   1047         {
   1048             return (Status);
   1049         }
   1050 
   1051         ParentTable = DtPeekSubtable ();
   1052         DtInsertSubtable (ParentTable, Subtable);
   1053         DtPushSubtable (Subtable);
   1054 
   1055         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
   1056 
   1057         switch (FpdtHeader->Type)
   1058         {
   1059         case ACPI_FPDT_TYPE_BOOT:
   1060 
   1061             InfoTable = AcpiDmTableInfoFpdt0;
   1062             break;
   1063 
   1064         case ACPI_FPDT_TYPE_S3PERF:
   1065 
   1066             InfoTable = AcpiDmTableInfoFpdt1;
   1067             break;
   1068 
   1069         default:
   1070 
   1071             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
   1072             return (AE_ERROR);
   1073             break;
   1074         }
   1075 
   1076         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1077         if (ACPI_FAILURE (Status))
   1078         {
   1079             return (Status);
   1080         }
   1081 
   1082         ParentTable = DtPeekSubtable ();
   1083         DtInsertSubtable (ParentTable, Subtable);
   1084         DtPopSubtable ();
   1085     }
   1086 
   1087     return (AE_OK);
   1088 }
   1089 
   1090 
   1091 /******************************************************************************
   1092  *
   1093  * FUNCTION:    DtCompileHest
   1094  *
   1095  * PARAMETERS:  List                - Current field list pointer
   1096  *
   1097  * RETURN:      Status
   1098  *
   1099  * DESCRIPTION: Compile HEST.
   1100  *
   1101  *****************************************************************************/
   1102 
   1103 ACPI_STATUS
   1104 DtCompileHest (
   1105     void                    **List)
   1106 {
   1107     ACPI_STATUS             Status;
   1108     DT_SUBTABLE             *Subtable;
   1109     DT_SUBTABLE             *ParentTable;
   1110     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1111     DT_FIELD                *SubtableStart;
   1112     ACPI_DMTABLE_INFO       *InfoTable;
   1113     UINT16                  Type;
   1114     UINT32                  BankCount;
   1115 
   1116 
   1117     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
   1118         &Subtable);
   1119     if (ACPI_FAILURE (Status))
   1120     {
   1121         return (Status);
   1122     }
   1123 
   1124     ParentTable = DtPeekSubtable ();
   1125     DtInsertSubtable (ParentTable, Subtable);
   1126 
   1127     while (*PFieldList)
   1128     {
   1129         /* Get subtable type */
   1130 
   1131         SubtableStart = *PFieldList;
   1132         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
   1133 
   1134         switch (Type)
   1135         {
   1136         case ACPI_HEST_TYPE_IA32_CHECK:
   1137 
   1138             InfoTable = AcpiDmTableInfoHest0;
   1139             break;
   1140 
   1141         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   1142 
   1143             InfoTable = AcpiDmTableInfoHest1;
   1144             break;
   1145 
   1146         case ACPI_HEST_TYPE_IA32_NMI:
   1147 
   1148             InfoTable = AcpiDmTableInfoHest2;
   1149             break;
   1150 
   1151         case ACPI_HEST_TYPE_AER_ROOT_PORT:
   1152 
   1153             InfoTable = AcpiDmTableInfoHest6;
   1154             break;
   1155 
   1156         case ACPI_HEST_TYPE_AER_ENDPOINT:
   1157 
   1158             InfoTable = AcpiDmTableInfoHest7;
   1159             break;
   1160 
   1161         case ACPI_HEST_TYPE_AER_BRIDGE:
   1162 
   1163             InfoTable = AcpiDmTableInfoHest8;
   1164             break;
   1165 
   1166         case ACPI_HEST_TYPE_GENERIC_ERROR:
   1167 
   1168             InfoTable = AcpiDmTableInfoHest9;
   1169             break;
   1170 
   1171         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
   1172 
   1173             InfoTable = AcpiDmTableInfoHest10;
   1174             break;
   1175 
   1176         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   1177 
   1178             InfoTable = AcpiDmTableInfoHest11;
   1179             break;
   1180 
   1181         default:
   1182 
   1183             /* Cannot continue on unknown type */
   1184 
   1185             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
   1186             return (AE_ERROR);
   1187         }
   1188 
   1189         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1190         if (ACPI_FAILURE (Status))
   1191         {
   1192             return (Status);
   1193         }
   1194 
   1195         DtInsertSubtable (ParentTable, Subtable);
   1196 
   1197         /*
   1198          * Additional subtable data - IA32 Error Bank(s)
   1199          */
   1200         BankCount = 0;
   1201         switch (Type)
   1202         {
   1203         case ACPI_HEST_TYPE_IA32_CHECK:
   1204 
   1205             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
   1206                 Subtable->Buffer))->NumHardwareBanks;
   1207             break;
   1208 
   1209         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   1210 
   1211             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
   1212                 Subtable->Buffer))->NumHardwareBanks;
   1213             break;
   1214 
   1215         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   1216 
   1217             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
   1218                 Subtable->Buffer))->NumHardwareBanks;
   1219             break;
   1220 
   1221         default:
   1222 
   1223             break;
   1224         }
   1225 
   1226         while (BankCount)
   1227         {
   1228             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
   1229                 &Subtable);
   1230             if (ACPI_FAILURE (Status))
   1231             {
   1232                 return (Status);
   1233             }
   1234 
   1235             DtInsertSubtable (ParentTable, Subtable);
   1236             BankCount--;
   1237         }
   1238     }
   1239 
   1240     return (AE_OK);
   1241 }
   1242 
   1243 
   1244 /******************************************************************************
   1245  *
   1246  * FUNCTION:    DtCompileHmat
   1247  *
   1248  * PARAMETERS:  List                - Current field list pointer
   1249  *
   1250  * RETURN:      Status
   1251  *
   1252  * DESCRIPTION: Compile HMAT.
   1253  *
   1254  *****************************************************************************/
   1255 
   1256 ACPI_STATUS
   1257 DtCompileHmat (
   1258     void                    **List)
   1259 {
   1260     ACPI_STATUS             Status;
   1261     DT_SUBTABLE             *Subtable;
   1262     DT_SUBTABLE             *ParentTable;
   1263     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1264     DT_FIELD                *SubtableStart;
   1265     DT_FIELD                *EntryStart;
   1266     ACPI_HMAT_STRUCTURE     *HmatStruct;
   1267     ACPI_HMAT_LOCALITY      *HmatLocality;
   1268     ACPI_HMAT_CACHE         *HmatCache;
   1269     ACPI_DMTABLE_INFO       *InfoTable;
   1270     UINT32                  IntPDNumber;
   1271     UINT32                  TgtPDNumber;
   1272     UINT64                  EntryNumber;
   1273     UINT16                  SMBIOSHandleNumber;
   1274 
   1275 
   1276     ParentTable = DtPeekSubtable ();
   1277 
   1278     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
   1279         &Subtable);
   1280     if (ACPI_FAILURE (Status))
   1281     {
   1282         return (Status);
   1283     }
   1284     DtInsertSubtable (ParentTable, Subtable);
   1285 
   1286     while (*PFieldList)
   1287     {
   1288         /* Compile HMAT structure header */
   1289 
   1290         SubtableStart = *PFieldList;
   1291         Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
   1292             &Subtable);
   1293         if (ACPI_FAILURE (Status))
   1294         {
   1295             return (Status);
   1296         }
   1297         DtInsertSubtable (ParentTable, Subtable);
   1298 
   1299         HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
   1300         HmatStruct->Length = Subtable->Length;
   1301 
   1302         /* Compile HMAT structure body */
   1303 
   1304         switch (HmatStruct->Type)
   1305         {
   1306         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
   1307 
   1308             InfoTable = AcpiDmTableInfoHmat0;
   1309             break;
   1310 
   1311         case ACPI_HMAT_TYPE_LOCALITY:
   1312 
   1313             InfoTable = AcpiDmTableInfoHmat1;
   1314             break;
   1315 
   1316         case ACPI_HMAT_TYPE_CACHE:
   1317 
   1318             InfoTable = AcpiDmTableInfoHmat2;
   1319             break;
   1320 
   1321         default:
   1322 
   1323             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
   1324             return (AE_ERROR);
   1325         }
   1326 
   1327         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1328         if (ACPI_FAILURE (Status))
   1329         {
   1330             return (Status);
   1331         }
   1332         DtInsertSubtable (ParentTable, Subtable);
   1333         HmatStruct->Length += Subtable->Length;
   1334 
   1335         /* Compile HMAT structure additionals */
   1336 
   1337         switch (HmatStruct->Type)
   1338         {
   1339         case ACPI_HMAT_TYPE_LOCALITY:
   1340 
   1341             HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
   1342                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   1343 
   1344             /* Compile initiator proximity domain list */
   1345 
   1346             IntPDNumber = 0;
   1347             while (*PFieldList)
   1348             {
   1349                 Status = DtCompileTable (PFieldList,
   1350                     AcpiDmTableInfoHmat1a, &Subtable);
   1351                 if (ACPI_FAILURE (Status))
   1352                 {
   1353                     return (Status);
   1354                 }
   1355                 if (!Subtable)
   1356                 {
   1357                     break;
   1358                 }
   1359                 DtInsertSubtable (ParentTable, Subtable);
   1360                 HmatStruct->Length += Subtable->Length;
   1361                 IntPDNumber++;
   1362             }
   1363             HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
   1364 
   1365             /* Compile target proximity domain list */
   1366 
   1367             TgtPDNumber = 0;
   1368             while (*PFieldList)
   1369             {
   1370                 Status = DtCompileTable (PFieldList,
   1371                     AcpiDmTableInfoHmat1b, &Subtable);
   1372                 if (ACPI_FAILURE (Status))
   1373                 {
   1374                     return (Status);
   1375                 }
   1376                 if (!Subtable)
   1377                 {
   1378                     break;
   1379                 }
   1380                 DtInsertSubtable (ParentTable, Subtable);
   1381                 HmatStruct->Length += Subtable->Length;
   1382                 TgtPDNumber++;
   1383             }
   1384             HmatLocality->NumberOfTargetPDs = TgtPDNumber;
   1385 
   1386             /* Save start of the entries for reporting errors */
   1387 
   1388             EntryStart = *PFieldList;
   1389 
   1390             /* Compile latency/bandwidth entries */
   1391 
   1392             EntryNumber = 0;
   1393             while (*PFieldList)
   1394             {
   1395                 Status = DtCompileTable (PFieldList,
   1396                     AcpiDmTableInfoHmat1c, &Subtable);
   1397                 if (ACPI_FAILURE (Status))
   1398                 {
   1399                     return (Status);
   1400                 }
   1401                 if (!Subtable)
   1402                 {
   1403                     break;
   1404                 }
   1405                 DtInsertSubtable (ParentTable, Subtable);
   1406                 HmatStruct->Length += Subtable->Length;
   1407                 EntryNumber++;
   1408             }
   1409 
   1410             /* Validate number of entries */
   1411 
   1412             if (EntryNumber !=
   1413                 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
   1414             {
   1415                 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
   1416                 return (AE_ERROR);
   1417             }
   1418             break;
   1419 
   1420         case ACPI_HMAT_TYPE_CACHE:
   1421 
   1422             /* Compile SMBIOS handles */
   1423 
   1424             HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
   1425                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   1426             SMBIOSHandleNumber = 0;
   1427             while (*PFieldList)
   1428             {
   1429                 Status = DtCompileTable (PFieldList,
   1430                     AcpiDmTableInfoHmat2a, &Subtable);
   1431                 if (ACPI_FAILURE (Status))
   1432                 {
   1433                     return (Status);
   1434                 }
   1435                 if (!Subtable)
   1436                 {
   1437                     break;
   1438                 }
   1439                 DtInsertSubtable (ParentTable, Subtable);
   1440                 HmatStruct->Length += Subtable->Length;
   1441                 SMBIOSHandleNumber++;
   1442             }
   1443             HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
   1444             break;
   1445 
   1446         default:
   1447 
   1448             break;
   1449         }
   1450     }
   1451 
   1452     return (AE_OK);
   1453 }
   1454 
   1455 
   1456 /******************************************************************************
   1457  *
   1458  * FUNCTION:    DtCompileIort
   1459  *
   1460  * PARAMETERS:  List                - Current field list pointer
   1461  *
   1462  * RETURN:      Status
   1463  *
   1464  * DESCRIPTION: Compile IORT.
   1465  *
   1466  *****************************************************************************/
   1467 
   1468 ACPI_STATUS
   1469 DtCompileIort (
   1470     void                    **List)
   1471 {
   1472     ACPI_STATUS             Status;
   1473     DT_SUBTABLE             *Subtable;
   1474     DT_SUBTABLE             *ParentTable;
   1475     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1476     DT_FIELD                *SubtableStart;
   1477     ACPI_TABLE_IORT         *Iort;
   1478     ACPI_IORT_NODE          *IortNode;
   1479     ACPI_IORT_ITS_GROUP     *IortItsGroup;
   1480     ACPI_IORT_SMMU          *IortSmmu;
   1481     UINT32                  NodeNumber;
   1482     UINT32                  NodeLength;
   1483     UINT32                  IdMappingNumber;
   1484     UINT32                  ItsNumber;
   1485     UINT32                  ContextIrptNumber;
   1486     UINT32                  PmuIrptNumber;
   1487     UINT32                  PaddingLength;
   1488 
   1489 
   1490     ParentTable = DtPeekSubtable ();
   1491 
   1492     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
   1493         &Subtable);
   1494     if (ACPI_FAILURE (Status))
   1495     {
   1496         return (Status);
   1497     }
   1498     DtInsertSubtable (ParentTable, Subtable);
   1499 
   1500     /*
   1501      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   1502      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
   1503      */
   1504     Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
   1505         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
   1506 
   1507     /*
   1508      * OptionalPadding - Variable-length data
   1509      * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
   1510      * Optionally allows the generic data types to be used for filling
   1511      * this field.
   1512      */
   1513     Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
   1514     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
   1515         &Subtable);
   1516     if (ACPI_FAILURE (Status))
   1517     {
   1518         return (Status);
   1519     }
   1520     if (Subtable)
   1521     {
   1522         DtInsertSubtable (ParentTable, Subtable);
   1523         Iort->NodeOffset += Subtable->Length;
   1524     }
   1525     else
   1526     {
   1527         Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
   1528             AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
   1529         if (ACPI_FAILURE (Status))
   1530         {
   1531             return (Status);
   1532         }
   1533         Iort->NodeOffset += PaddingLength;
   1534     }
   1535 
   1536     NodeNumber = 0;
   1537     while (*PFieldList)
   1538     {
   1539         SubtableStart = *PFieldList;
   1540         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
   1541             &Subtable);
   1542         if (ACPI_FAILURE (Status))
   1543         {
   1544             return (Status);
   1545         }
   1546 
   1547         DtInsertSubtable (ParentTable, Subtable);
   1548         IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
   1549         NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
   1550 
   1551         DtPushSubtable (Subtable);
   1552         ParentTable = DtPeekSubtable ();
   1553 
   1554         switch (IortNode->Type)
   1555         {
   1556         case ACPI_IORT_NODE_ITS_GROUP:
   1557 
   1558             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
   1559                 &Subtable);
   1560             if (ACPI_FAILURE (Status))
   1561             {
   1562                 return (Status);
   1563             }
   1564 
   1565             DtInsertSubtable (ParentTable, Subtable);
   1566             IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
   1567             NodeLength += Subtable->Length;
   1568 
   1569             ItsNumber = 0;
   1570             while (*PFieldList)
   1571             {
   1572                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
   1573                     &Subtable);
   1574                 if (ACPI_FAILURE (Status))
   1575                 {
   1576                     return (Status);
   1577                 }
   1578                 if (!Subtable)
   1579                 {
   1580                     break;
   1581                 }
   1582 
   1583                 DtInsertSubtable (ParentTable, Subtable);
   1584                 NodeLength += Subtable->Length;
   1585                 ItsNumber++;
   1586             }
   1587 
   1588             IortItsGroup->ItsCount = ItsNumber;
   1589             break;
   1590 
   1591         case ACPI_IORT_NODE_NAMED_COMPONENT:
   1592 
   1593             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
   1594                 &Subtable);
   1595             if (ACPI_FAILURE (Status))
   1596             {
   1597                 return (Status);
   1598             }
   1599 
   1600             DtInsertSubtable (ParentTable, Subtable);
   1601             NodeLength += Subtable->Length;
   1602 
   1603             /*
   1604              * Padding - Variable-length data
   1605              * Optionally allows the offset of the ID mappings to be used
   1606              * for filling this field.
   1607              */
   1608             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
   1609                 &Subtable);
   1610             if (ACPI_FAILURE (Status))
   1611             {
   1612                 return (Status);
   1613             }
   1614 
   1615             if (Subtable)
   1616             {
   1617                 DtInsertSubtable (ParentTable, Subtable);
   1618                 NodeLength += Subtable->Length;
   1619             }
   1620             else
   1621             {
   1622                 if (NodeLength > IortNode->MappingOffset)
   1623                 {
   1624                     return (AE_BAD_DATA);
   1625                 }
   1626 
   1627                 if (NodeLength < IortNode->MappingOffset)
   1628                 {
   1629                     Status = DtCompilePadding (
   1630                         IortNode->MappingOffset - NodeLength,
   1631                         &Subtable);
   1632                     if (ACPI_FAILURE (Status))
   1633                     {
   1634                         return (Status);
   1635                     }
   1636 
   1637                     DtInsertSubtable (ParentTable, Subtable);
   1638                     NodeLength = IortNode->MappingOffset;
   1639                 }
   1640             }
   1641             break;
   1642 
   1643         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
   1644 
   1645             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
   1646                 &Subtable);
   1647             if (ACPI_FAILURE (Status))
   1648             {
   1649                 return (Status);
   1650             }
   1651 
   1652             DtInsertSubtable (ParentTable, Subtable);
   1653             NodeLength += Subtable->Length;
   1654             break;
   1655 
   1656         case ACPI_IORT_NODE_SMMU:
   1657 
   1658             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
   1659                 &Subtable);
   1660             if (ACPI_FAILURE (Status))
   1661             {
   1662                 return (Status);
   1663             }
   1664 
   1665             DtInsertSubtable (ParentTable, Subtable);
   1666             IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
   1667             NodeLength += Subtable->Length;
   1668 
   1669             /* Compile global interrupt array */
   1670 
   1671             IortSmmu->GlobalInterruptOffset = NodeLength;
   1672             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
   1673                 &Subtable);
   1674             if (ACPI_FAILURE (Status))
   1675             {
   1676                 return (Status);
   1677             }
   1678 
   1679             DtInsertSubtable (ParentTable, Subtable);
   1680             NodeLength += Subtable->Length;
   1681 
   1682             /* Compile context interrupt array */
   1683 
   1684             ContextIrptNumber = 0;
   1685             IortSmmu->ContextInterruptOffset = NodeLength;
   1686             while (*PFieldList)
   1687             {
   1688                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
   1689                     &Subtable);
   1690                 if (ACPI_FAILURE (Status))
   1691                 {
   1692                     return (Status);
   1693                 }
   1694 
   1695                 if (!Subtable)
   1696                 {
   1697                     break;
   1698                 }
   1699 
   1700                 DtInsertSubtable (ParentTable, Subtable);
   1701                 NodeLength += Subtable->Length;
   1702                 ContextIrptNumber++;
   1703             }
   1704 
   1705             IortSmmu->ContextInterruptCount = ContextIrptNumber;
   1706 
   1707             /* Compile PMU interrupt array */
   1708 
   1709             PmuIrptNumber = 0;
   1710             IortSmmu->PmuInterruptOffset = NodeLength;
   1711             while (*PFieldList)
   1712             {
   1713                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
   1714                     &Subtable);
   1715                 if (ACPI_FAILURE (Status))
   1716                 {
   1717                     return (Status);
   1718                 }
   1719 
   1720                 if (!Subtable)
   1721                 {
   1722                     break;
   1723                 }
   1724 
   1725                 DtInsertSubtable (ParentTable, Subtable);
   1726                 NodeLength += Subtable->Length;
   1727                 PmuIrptNumber++;
   1728             }
   1729 
   1730             IortSmmu->PmuInterruptCount = PmuIrptNumber;
   1731             break;
   1732 
   1733         case ACPI_IORT_NODE_SMMU_V3:
   1734 
   1735             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
   1736                 &Subtable);
   1737             if (ACPI_FAILURE (Status))
   1738             {
   1739                 return (Status);
   1740             }
   1741 
   1742             DtInsertSubtable (ParentTable, Subtable);
   1743             NodeLength += Subtable->Length;
   1744             break;
   1745 
   1746         case ACPI_IORT_NODE_PMCG:
   1747 
   1748             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
   1749                 &Subtable);
   1750             if (ACPI_FAILURE (Status))
   1751             {
   1752                 return (Status);
   1753             }
   1754 
   1755             DtInsertSubtable (ParentTable, Subtable);
   1756             NodeLength += Subtable->Length;
   1757             break;
   1758 
   1759         default:
   1760 
   1761             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
   1762             return (AE_ERROR);
   1763         }
   1764 
   1765         /* Compile Array of ID mappings */
   1766 
   1767         IortNode->MappingOffset = NodeLength;
   1768         IdMappingNumber = 0;
   1769         while (*PFieldList)
   1770         {
   1771             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
   1772                 &Subtable);
   1773             if (ACPI_FAILURE (Status))
   1774             {
   1775                 return (Status);
   1776             }
   1777 
   1778             if (!Subtable)
   1779             {
   1780                 break;
   1781             }
   1782 
   1783             DtInsertSubtable (ParentTable, Subtable);
   1784             NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
   1785             IdMappingNumber++;
   1786         }
   1787 
   1788         IortNode->MappingCount = IdMappingNumber;
   1789         if (!IdMappingNumber)
   1790         {
   1791             IortNode->MappingOffset = 0;
   1792         }
   1793 
   1794         /*
   1795          * Node length can be determined by DT_LENGTH option
   1796          * IortNode->Length = NodeLength;
   1797          */
   1798         DtPopSubtable ();
   1799         ParentTable = DtPeekSubtable ();
   1800         NodeNumber++;
   1801     }
   1802 
   1803     Iort->NodeCount = NodeNumber;
   1804     return (AE_OK);
   1805 }
   1806 
   1807 
   1808 /******************************************************************************
   1809  *
   1810  * FUNCTION:    DtCompileIvrs
   1811  *
   1812  * PARAMETERS:  List                - Current field list pointer
   1813  *
   1814  * RETURN:      Status
   1815  *
   1816  * DESCRIPTION: Compile IVRS.
   1817  *
   1818  *****************************************************************************/
   1819 
   1820 ACPI_STATUS
   1821 DtCompileIvrs (
   1822     void                    **List)
   1823 {
   1824     ACPI_STATUS             Status;
   1825     DT_SUBTABLE             *Subtable;
   1826     DT_SUBTABLE             *ParentTable;
   1827     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1828     DT_FIELD                *SubtableStart;
   1829     ACPI_DMTABLE_INFO       *InfoTable;
   1830     ACPI_IVRS_HEADER        *IvrsHeader;
   1831     UINT8                   EntryType;
   1832 
   1833 
   1834     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
   1835         &Subtable);
   1836     if (ACPI_FAILURE (Status))
   1837     {
   1838         return (Status);
   1839     }
   1840 
   1841     ParentTable = DtPeekSubtable ();
   1842     DtInsertSubtable (ParentTable, Subtable);
   1843 
   1844     while (*PFieldList)
   1845     {
   1846         SubtableStart = *PFieldList;
   1847         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
   1848             &Subtable);
   1849         if (ACPI_FAILURE (Status))
   1850         {
   1851             return (Status);
   1852         }
   1853 
   1854         ParentTable = DtPeekSubtable ();
   1855         DtInsertSubtable (ParentTable, Subtable);
   1856         DtPushSubtable (Subtable);
   1857 
   1858         IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
   1859 
   1860         switch (IvrsHeader->Type)
   1861         {
   1862         case ACPI_IVRS_TYPE_HARDWARE1:
   1863 
   1864             InfoTable = AcpiDmTableInfoIvrs0;
   1865             break;
   1866 
   1867         case ACPI_IVRS_TYPE_HARDWARE2:
   1868 
   1869             InfoTable = AcpiDmTableInfoIvrs01;
   1870             break;
   1871 
   1872         case ACPI_IVRS_TYPE_MEMORY1:
   1873         case ACPI_IVRS_TYPE_MEMORY2:
   1874         case ACPI_IVRS_TYPE_MEMORY3:
   1875 
   1876             InfoTable = AcpiDmTableInfoIvrs1;
   1877             break;
   1878 
   1879         default:
   1880 
   1881             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
   1882             return (AE_ERROR);
   1883         }
   1884 
   1885         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1886         if (ACPI_FAILURE (Status))
   1887         {
   1888             return (Status);
   1889         }
   1890 
   1891         ParentTable = DtPeekSubtable ();
   1892         DtInsertSubtable (ParentTable, Subtable);
   1893 
   1894         if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE1 ||
   1895             IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE2)
   1896         {
   1897             while (*PFieldList &&
   1898                 !strcmp ((*PFieldList)->Name, "Entry Type"))
   1899             {
   1900                 SubtableStart = *PFieldList;
   1901                 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
   1902 
   1903                 switch (EntryType)
   1904                 {
   1905                 /* 4-byte device entries */
   1906 
   1907                 case ACPI_IVRS_TYPE_PAD4:
   1908                 case ACPI_IVRS_TYPE_ALL:
   1909                 case ACPI_IVRS_TYPE_SELECT:
   1910                 case ACPI_IVRS_TYPE_START:
   1911                 case ACPI_IVRS_TYPE_END:
   1912 
   1913                     InfoTable = AcpiDmTableInfoIvrs4;
   1914                     break;
   1915 
   1916                 /* 8-byte entries, type A */
   1917 
   1918                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
   1919                 case ACPI_IVRS_TYPE_ALIAS_START:
   1920 
   1921                     InfoTable = AcpiDmTableInfoIvrs8a;
   1922                     break;
   1923 
   1924                 /* 8-byte entries, type B */
   1925 
   1926                 case ACPI_IVRS_TYPE_PAD8:
   1927                 case ACPI_IVRS_TYPE_EXT_SELECT:
   1928                 case ACPI_IVRS_TYPE_EXT_START:
   1929 
   1930                     InfoTable = AcpiDmTableInfoIvrs8b;
   1931                     break;
   1932 
   1933                 /* 8-byte entries, type C */
   1934 
   1935                 case ACPI_IVRS_TYPE_SPECIAL:
   1936 
   1937                     InfoTable = AcpiDmTableInfoIvrs8c;
   1938                     break;
   1939 
   1940                 default:
   1941 
   1942                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
   1943                         "IVRS Device Entry");
   1944                     return (AE_ERROR);
   1945                 }
   1946 
   1947                 Status = DtCompileTable (PFieldList, InfoTable,
   1948                     &Subtable);
   1949                 if (ACPI_FAILURE (Status))
   1950                 {
   1951                     return (Status);
   1952                 }
   1953 
   1954                 DtInsertSubtable (ParentTable, Subtable);
   1955             }
   1956         }
   1957 
   1958         DtPopSubtable ();
   1959     }
   1960 
   1961     return (AE_OK);
   1962 }
   1963