Home | History | Annotate | Line # | Download | only in compiler
dttable1.c revision 1.1.1.6.2.2
      1 /******************************************************************************
      2  *
      3  * Module Name: dttable1.c - handling for specific ACPI tables
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2017, 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, TRUE);
     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, TRUE);
    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, TRUE);
    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, TRUE);
    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, TRUE);
    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, TRUE);
    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, TRUE);
    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, TRUE);
    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, TRUE);
    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, TRUE);
    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, TRUE);
    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, TRUE);
    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, TRUE);
    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, TRUE);
    491         if (ACPI_FAILURE (Status))
    492         {
    493             return (Status);
    494         }
    495 
    496         /* Update the device info header (zeros if no OEM data present) */
    497 
    498         DeviceInfo->OemDataOffset = 0;
    499         DeviceInfo->OemDataLength = 0;
    500 
    501         /* Optional subtable (OemData) */
    502 
    503         if (Subtable && Subtable->Length)
    504         {
    505             DeviceInfo->OemDataOffset = CurrentOffset;
    506             DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
    507 
    508             DtInsertSubtable (ParentTable, Subtable);
    509         }
    510 
    511         SubtableCount--;
    512         DtPopSubtable (); /* Get next Device Information subtable */
    513     }
    514 
    515     DtPopSubtable ();
    516     return (AE_OK);
    517 }
    518 
    519 
    520 /******************************************************************************
    521  *
    522  * FUNCTION:    DtCompileDmar
    523  *
    524  * PARAMETERS:  List                - Current field list pointer
    525  *
    526  * RETURN:      Status
    527  *
    528  * DESCRIPTION: Compile DMAR.
    529  *
    530  *****************************************************************************/
    531 
    532 ACPI_STATUS
    533 DtCompileDmar (
    534     void                    **List)
    535 {
    536     ACPI_STATUS             Status;
    537     DT_SUBTABLE             *Subtable;
    538     DT_SUBTABLE             *ParentTable;
    539     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    540     DT_FIELD                *SubtableStart;
    541     ACPI_DMTABLE_INFO       *InfoTable;
    542     ACPI_DMAR_HEADER        *DmarHeader;
    543     ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope;
    544     UINT32                  DeviceScopeLength;
    545     UINT32                  PciPathLength;
    546 
    547 
    548     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE);
    549     if (ACPI_FAILURE (Status))
    550     {
    551         return (Status);
    552     }
    553 
    554     ParentTable = DtPeekSubtable ();
    555     DtInsertSubtable (ParentTable, Subtable);
    556     DtPushSubtable (Subtable);
    557 
    558     while (*PFieldList)
    559     {
    560         /* DMAR Header */
    561 
    562         SubtableStart = *PFieldList;
    563         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
    564             &Subtable, TRUE);
    565         if (ACPI_FAILURE (Status))
    566         {
    567             return (Status);
    568         }
    569 
    570         ParentTable = DtPeekSubtable ();
    571         DtInsertSubtable (ParentTable, Subtable);
    572         DtPushSubtable (Subtable);
    573 
    574         DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer);
    575 
    576         switch (DmarHeader->Type)
    577         {
    578         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
    579 
    580             InfoTable = AcpiDmTableInfoDmar0;
    581             break;
    582 
    583         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
    584 
    585             InfoTable = AcpiDmTableInfoDmar1;
    586             break;
    587 
    588         case ACPI_DMAR_TYPE_ROOT_ATS:
    589 
    590             InfoTable = AcpiDmTableInfoDmar2;
    591             break;
    592 
    593         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
    594 
    595             InfoTable = AcpiDmTableInfoDmar3;
    596             break;
    597 
    598         case ACPI_DMAR_TYPE_NAMESPACE:
    599 
    600             InfoTable = AcpiDmTableInfoDmar4;
    601             break;
    602 
    603         default:
    604 
    605             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR");
    606             return (AE_ERROR);
    607         }
    608 
    609         /* DMAR Subtable */
    610 
    611         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
    612         if (ACPI_FAILURE (Status))
    613         {
    614             return (Status);
    615         }
    616 
    617         ParentTable = DtPeekSubtable ();
    618         DtInsertSubtable (ParentTable, Subtable);
    619 
    620         /*
    621          * Optional Device Scope subtables
    622          */
    623         if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
    624             (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
    625         {
    626             /* These types do not support device scopes */
    627 
    628             DtPopSubtable ();
    629             continue;
    630         }
    631 
    632         DtPushSubtable (Subtable);
    633         DeviceScopeLength = DmarHeader->Length - Subtable->Length -
    634             ParentTable->Length;
    635         while (DeviceScopeLength)
    636         {
    637             Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
    638                 &Subtable, FALSE);
    639             if (Status == AE_NOT_FOUND)
    640             {
    641                 break;
    642             }
    643 
    644             ParentTable = DtPeekSubtable ();
    645             DtInsertSubtable (ParentTable, Subtable);
    646             DtPushSubtable (Subtable);
    647 
    648             DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
    649 
    650             /* Optional PCI Paths */
    651 
    652             PciPathLength = DmarDeviceScope->Length - Subtable->Length;
    653             while (PciPathLength)
    654             {
    655                 Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
    656                     &Subtable, FALSE);
    657                 if (Status == AE_NOT_FOUND)
    658                 {
    659                     DtPopSubtable ();
    660                     break;
    661                 }
    662 
    663                 ParentTable = DtPeekSubtable ();
    664                 DtInsertSubtable (ParentTable, Subtable);
    665                 PciPathLength -= Subtable->Length;
    666             }
    667 
    668             DtPopSubtable ();
    669             DeviceScopeLength -= DmarDeviceScope->Length;
    670         }
    671 
    672         DtPopSubtable ();
    673         DtPopSubtable ();
    674     }
    675 
    676     return (AE_OK);
    677 }
    678 
    679 
    680 /******************************************************************************
    681  *
    682  * FUNCTION:    DtCompileDrtm
    683  *
    684  * PARAMETERS:  List                - Current field list pointer
    685  *
    686  * RETURN:      Status
    687  *
    688  * DESCRIPTION: Compile DRTM.
    689  *
    690  *****************************************************************************/
    691 
    692 ACPI_STATUS
    693 DtCompileDrtm (
    694     void                    **List)
    695 {
    696     ACPI_STATUS             Status;
    697     DT_SUBTABLE             *Subtable;
    698     DT_SUBTABLE             *ParentTable;
    699     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    700     UINT32                  Count;
    701     /* ACPI_TABLE_DRTM         *Drtm; */
    702     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
    703     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
    704     /* ACPI_DRTM_DPS_ID        *DrtmDps; */
    705 
    706 
    707     ParentTable = DtPeekSubtable ();
    708 
    709     /* Compile DRTM header */
    710 
    711     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
    712         &Subtable, TRUE);
    713     if (ACPI_FAILURE (Status))
    714     {
    715         return (Status);
    716     }
    717     DtInsertSubtable (ParentTable, Subtable);
    718 
    719     /*
    720      * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
    721      * should be taken to avoid accessing ACPI_TABLE_HADER fields.
    722      */
    723 #if 0
    724     Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
    725         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
    726 #endif
    727     /* Compile VTL */
    728 
    729     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
    730         &Subtable, TRUE);
    731     if (ACPI_FAILURE (Status))
    732     {
    733         return (Status);
    734     }
    735 
    736     DtInsertSubtable (ParentTable, Subtable);
    737     DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer);
    738 
    739     DtPushSubtable (Subtable);
    740     ParentTable = DtPeekSubtable ();
    741     Count = 0;
    742 
    743     while (*PFieldList)
    744     {
    745         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a,
    746             &Subtable, TRUE);
    747         if (ACPI_FAILURE (Status))
    748         {
    749             return (Status);
    750         }
    751         if (!Subtable)
    752         {
    753             break;
    754         }
    755         DtInsertSubtable (ParentTable, Subtable);
    756         Count++;
    757     }
    758 
    759     DrtmVtl->ValidatedTableCount = Count;
    760     DtPopSubtable ();
    761     ParentTable = DtPeekSubtable ();
    762 
    763     /* Compile RL */
    764 
    765     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
    766         &Subtable, TRUE);
    767     if (ACPI_FAILURE (Status))
    768     {
    769         return (Status);
    770     }
    771 
    772     DtInsertSubtable (ParentTable, Subtable);
    773     DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer);
    774 
    775     DtPushSubtable (Subtable);
    776     ParentTable = DtPeekSubtable ();
    777     Count = 0;
    778 
    779     while (*PFieldList)
    780     {
    781         Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a,
    782             &Subtable, TRUE);
    783         if (ACPI_FAILURE (Status))
    784         {
    785             return (Status);
    786         }
    787 
    788         if (!Subtable)
    789         {
    790             break;
    791         }
    792 
    793         DtInsertSubtable (ParentTable, Subtable);
    794         Count++;
    795     }
    796 
    797     DrtmRl->ResourceCount = Count;
    798     DtPopSubtable ();
    799     ParentTable = DtPeekSubtable ();
    800 
    801     /* Compile DPS */
    802 
    803     Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
    804         &Subtable, TRUE);
    805     if (ACPI_FAILURE (Status))
    806     {
    807         return (Status);
    808     }
    809     DtInsertSubtable (ParentTable, Subtable);
    810     /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/
    811 
    812 
    813     return (AE_OK);
    814 }
    815 
    816 
    817 /******************************************************************************
    818  *
    819  * FUNCTION:    DtCompileEinj
    820  *
    821  * PARAMETERS:  List                - Current field list pointer
    822  *
    823  * RETURN:      Status
    824  *
    825  * DESCRIPTION: Compile EINJ.
    826  *
    827  *****************************************************************************/
    828 
    829 ACPI_STATUS
    830 DtCompileEinj (
    831     void                    **List)
    832 {
    833     ACPI_STATUS             Status;
    834 
    835 
    836     Status = DtCompileTwoSubtables (List,
    837         AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
    838     return (Status);
    839 }
    840 
    841 
    842 /******************************************************************************
    843  *
    844  * FUNCTION:    DtCompileErst
    845  *
    846  * PARAMETERS:  List                - Current field list pointer
    847  *
    848  * RETURN:      Status
    849  *
    850  * DESCRIPTION: Compile ERST.
    851  *
    852  *****************************************************************************/
    853 
    854 ACPI_STATUS
    855 DtCompileErst (
    856     void                    **List)
    857 {
    858     ACPI_STATUS             Status;
    859 
    860 
    861     Status = DtCompileTwoSubtables (List,
    862         AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
    863     return (Status);
    864 }
    865 
    866 
    867 /******************************************************************************
    868  *
    869  * FUNCTION:    DtCompileGtdt
    870  *
    871  * PARAMETERS:  List                - Current field list pointer
    872  *
    873  * RETURN:      Status
    874  *
    875  * DESCRIPTION: Compile GTDT.
    876  *
    877  *****************************************************************************/
    878 
    879 ACPI_STATUS
    880 DtCompileGtdt (
    881     void                    **List)
    882 {
    883     ACPI_STATUS             Status;
    884     DT_SUBTABLE             *Subtable;
    885     DT_SUBTABLE             *ParentTable;
    886     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    887     DT_FIELD                *SubtableStart;
    888     ACPI_SUBTABLE_HEADER    *GtdtHeader;
    889     ACPI_DMTABLE_INFO       *InfoTable;
    890     UINT32                  GtCount;
    891 
    892 
    893     Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
    894         &Subtable, TRUE);
    895     if (ACPI_FAILURE (Status))
    896     {
    897         return (Status);
    898     }
    899 
    900     ParentTable = DtPeekSubtable ();
    901     DtInsertSubtable (ParentTable, Subtable);
    902 
    903     while (*PFieldList)
    904     {
    905         SubtableStart = *PFieldList;
    906         Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
    907             &Subtable, TRUE);
    908         if (ACPI_FAILURE (Status))
    909         {
    910             return (Status);
    911         }
    912 
    913         ParentTable = DtPeekSubtable ();
    914         DtInsertSubtable (ParentTable, Subtable);
    915         DtPushSubtable (Subtable);
    916 
    917         GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
    918 
    919         switch (GtdtHeader->Type)
    920         {
    921         case ACPI_GTDT_TYPE_TIMER_BLOCK:
    922 
    923             InfoTable = AcpiDmTableInfoGtdt0;
    924             break;
    925 
    926         case ACPI_GTDT_TYPE_WATCHDOG:
    927 
    928             InfoTable = AcpiDmTableInfoGtdt1;
    929             break;
    930 
    931         default:
    932 
    933             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT");
    934             return (AE_ERROR);
    935         }
    936 
    937         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
    938         if (ACPI_FAILURE (Status))
    939         {
    940             return (Status);
    941         }
    942 
    943         ParentTable = DtPeekSubtable ();
    944         DtInsertSubtable (ParentTable, Subtable);
    945 
    946         /*
    947          * Additional GT block subtable data
    948          */
    949 
    950         switch (GtdtHeader->Type)
    951         {
    952         case ACPI_GTDT_TYPE_TIMER_BLOCK:
    953 
    954             DtPushSubtable (Subtable);
    955             ParentTable = DtPeekSubtable ();
    956 
    957             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
    958                 Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount;
    959 
    960             while (GtCount)
    961             {
    962                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a,
    963                     &Subtable, TRUE);
    964                 if (ACPI_FAILURE (Status))
    965                 {
    966                     return (Status);
    967                 }
    968 
    969                 DtInsertSubtable (ParentTable, Subtable);
    970                 GtCount--;
    971             }
    972 
    973             DtPopSubtable ();
    974             break;
    975 
    976         default:
    977 
    978             break;
    979         }
    980 
    981         DtPopSubtable ();
    982     }
    983 
    984     return (AE_OK);
    985 }
    986 
    987 
    988 /******************************************************************************
    989  *
    990  * FUNCTION:    DtCompileFpdt
    991  *
    992  * PARAMETERS:  List                - Current field list pointer
    993  *
    994  * RETURN:      Status
    995  *
    996  * DESCRIPTION: Compile FPDT.
    997  *
    998  *****************************************************************************/
    999 
   1000 ACPI_STATUS
   1001 DtCompileFpdt (
   1002     void                    **List)
   1003 {
   1004     ACPI_STATUS             Status;
   1005     ACPI_FPDT_HEADER        *FpdtHeader;
   1006     DT_SUBTABLE             *Subtable;
   1007     DT_SUBTABLE             *ParentTable;
   1008     ACPI_DMTABLE_INFO       *InfoTable;
   1009     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1010     DT_FIELD                *SubtableStart;
   1011 
   1012 
   1013     while (*PFieldList)
   1014     {
   1015         SubtableStart = *PFieldList;
   1016         Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr,
   1017             &Subtable, TRUE);
   1018         if (ACPI_FAILURE (Status))
   1019         {
   1020             return (Status);
   1021         }
   1022 
   1023         ParentTable = DtPeekSubtable ();
   1024         DtInsertSubtable (ParentTable, Subtable);
   1025         DtPushSubtable (Subtable);
   1026 
   1027         FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
   1028 
   1029         switch (FpdtHeader->Type)
   1030         {
   1031         case ACPI_FPDT_TYPE_BOOT:
   1032 
   1033             InfoTable = AcpiDmTableInfoFpdt0;
   1034             break;
   1035 
   1036         case ACPI_FPDT_TYPE_S3PERF:
   1037 
   1038             InfoTable = AcpiDmTableInfoFpdt1;
   1039             break;
   1040 
   1041         default:
   1042 
   1043             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT");
   1044             return (AE_ERROR);
   1045             break;
   1046         }
   1047 
   1048         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
   1049         if (ACPI_FAILURE (Status))
   1050         {
   1051             return (Status);
   1052         }
   1053 
   1054         ParentTable = DtPeekSubtable ();
   1055         DtInsertSubtable (ParentTable, Subtable);
   1056         DtPopSubtable ();
   1057     }
   1058 
   1059     return (AE_OK);
   1060 }
   1061 
   1062 
   1063 /******************************************************************************
   1064  *
   1065  * FUNCTION:    DtCompileHest
   1066  *
   1067  * PARAMETERS:  List                - Current field list pointer
   1068  *
   1069  * RETURN:      Status
   1070  *
   1071  * DESCRIPTION: Compile HEST.
   1072  *
   1073  *****************************************************************************/
   1074 
   1075 ACPI_STATUS
   1076 DtCompileHest (
   1077     void                    **List)
   1078 {
   1079     ACPI_STATUS             Status;
   1080     DT_SUBTABLE             *Subtable;
   1081     DT_SUBTABLE             *ParentTable;
   1082     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1083     DT_FIELD                *SubtableStart;
   1084     ACPI_DMTABLE_INFO       *InfoTable;
   1085     UINT16                  Type;
   1086     UINT32                  BankCount;
   1087 
   1088 
   1089     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest,
   1090         &Subtable, TRUE);
   1091     if (ACPI_FAILURE (Status))
   1092     {
   1093         return (Status);
   1094     }
   1095 
   1096     ParentTable = DtPeekSubtable ();
   1097     DtInsertSubtable (ParentTable, Subtable);
   1098 
   1099     while (*PFieldList)
   1100     {
   1101         /* Get subtable type */
   1102 
   1103         SubtableStart = *PFieldList;
   1104         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
   1105 
   1106         switch (Type)
   1107         {
   1108         case ACPI_HEST_TYPE_IA32_CHECK:
   1109 
   1110             InfoTable = AcpiDmTableInfoHest0;
   1111             break;
   1112 
   1113         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   1114 
   1115             InfoTable = AcpiDmTableInfoHest1;
   1116             break;
   1117 
   1118         case ACPI_HEST_TYPE_IA32_NMI:
   1119 
   1120             InfoTable = AcpiDmTableInfoHest2;
   1121             break;
   1122 
   1123         case ACPI_HEST_TYPE_AER_ROOT_PORT:
   1124 
   1125             InfoTable = AcpiDmTableInfoHest6;
   1126             break;
   1127 
   1128         case ACPI_HEST_TYPE_AER_ENDPOINT:
   1129 
   1130             InfoTable = AcpiDmTableInfoHest7;
   1131             break;
   1132 
   1133         case ACPI_HEST_TYPE_AER_BRIDGE:
   1134 
   1135             InfoTable = AcpiDmTableInfoHest8;
   1136             break;
   1137 
   1138         case ACPI_HEST_TYPE_GENERIC_ERROR:
   1139 
   1140             InfoTable = AcpiDmTableInfoHest9;
   1141             break;
   1142 
   1143         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
   1144 
   1145             InfoTable = AcpiDmTableInfoHest10;
   1146             break;
   1147 
   1148         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   1149 
   1150             InfoTable = AcpiDmTableInfoHest11;
   1151             break;
   1152 
   1153         default:
   1154 
   1155             /* Cannot continue on unknown type */
   1156 
   1157             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
   1158             return (AE_ERROR);
   1159         }
   1160 
   1161         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
   1162         if (ACPI_FAILURE (Status))
   1163         {
   1164             return (Status);
   1165         }
   1166 
   1167         DtInsertSubtable (ParentTable, Subtable);
   1168 
   1169         /*
   1170          * Additional subtable data - IA32 Error Bank(s)
   1171          */
   1172         BankCount = 0;
   1173         switch (Type)
   1174         {
   1175         case ACPI_HEST_TYPE_IA32_CHECK:
   1176 
   1177             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
   1178                 Subtable->Buffer))->NumHardwareBanks;
   1179             break;
   1180 
   1181         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
   1182 
   1183             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
   1184                 Subtable->Buffer))->NumHardwareBanks;
   1185             break;
   1186 
   1187         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
   1188 
   1189             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
   1190                 Subtable->Buffer))->NumHardwareBanks;
   1191             break;
   1192 
   1193         default:
   1194 
   1195             break;
   1196         }
   1197 
   1198         while (BankCount)
   1199         {
   1200             Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
   1201                 &Subtable, TRUE);
   1202             if (ACPI_FAILURE (Status))
   1203             {
   1204                 return (Status);
   1205             }
   1206 
   1207             DtInsertSubtable (ParentTable, Subtable);
   1208             BankCount--;
   1209         }
   1210     }
   1211 
   1212     return (AE_OK);
   1213 }
   1214 
   1215 
   1216 /******************************************************************************
   1217  *
   1218  * FUNCTION:    DtCompileHmat
   1219  *
   1220  * PARAMETERS:  List                - Current field list pointer
   1221  *
   1222  * RETURN:      Status
   1223  *
   1224  * DESCRIPTION: Compile HMAT.
   1225  *
   1226  *****************************************************************************/
   1227 
   1228 ACPI_STATUS
   1229 DtCompileHmat (
   1230     void                    **List)
   1231 {
   1232     ACPI_STATUS             Status;
   1233     DT_SUBTABLE             *Subtable;
   1234     DT_SUBTABLE             *ParentTable;
   1235     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1236     DT_FIELD                *SubtableStart;
   1237     DT_FIELD                *EntryStart;
   1238     ACPI_HMAT_STRUCTURE     *HmatStruct;
   1239     ACPI_HMAT_LOCALITY      *HmatLocality;
   1240     ACPI_HMAT_CACHE         *HmatCache;
   1241     ACPI_DMTABLE_INFO       *InfoTable;
   1242     UINT32                  IntPDNumber;
   1243     UINT32                  TgtPDNumber;
   1244     UINT64                  EntryNumber;
   1245     UINT16                  SMBIOSHandleNumber;
   1246 
   1247 
   1248     ParentTable = DtPeekSubtable ();
   1249 
   1250     Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
   1251         &Subtable, TRUE);
   1252     if (ACPI_FAILURE (Status))
   1253     {
   1254         return (Status);
   1255     }
   1256     DtInsertSubtable (ParentTable, Subtable);
   1257 
   1258     while (*PFieldList)
   1259     {
   1260         /* Compile HMAT structure header */
   1261 
   1262         SubtableStart = *PFieldList;
   1263         Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
   1264             &Subtable, TRUE);
   1265         if (ACPI_FAILURE (Status))
   1266         {
   1267             return (Status);
   1268         }
   1269         DtInsertSubtable (ParentTable, Subtable);
   1270 
   1271         HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
   1272         HmatStruct->Length = Subtable->Length;
   1273 
   1274         /* Compile HMAT structure body */
   1275 
   1276         switch (HmatStruct->Type)
   1277         {
   1278         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
   1279 
   1280             InfoTable = AcpiDmTableInfoHmat0;
   1281             break;
   1282 
   1283         case ACPI_HMAT_TYPE_LOCALITY:
   1284 
   1285             InfoTable = AcpiDmTableInfoHmat1;
   1286             break;
   1287 
   1288         case ACPI_HMAT_TYPE_CACHE:
   1289 
   1290             InfoTable = AcpiDmTableInfoHmat2;
   1291             break;
   1292 
   1293         default:
   1294 
   1295             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
   1296             return (AE_ERROR);
   1297         }
   1298 
   1299         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
   1300         if (ACPI_FAILURE (Status))
   1301         {
   1302             return (Status);
   1303         }
   1304         DtInsertSubtable (ParentTable, Subtable);
   1305         HmatStruct->Length += Subtable->Length;
   1306 
   1307         /* Compile HMAT structure additionals */
   1308 
   1309         switch (HmatStruct->Type)
   1310         {
   1311         case ACPI_HMAT_TYPE_LOCALITY:
   1312 
   1313             HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
   1314                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   1315 
   1316             /* Compile initiator proximity domain list */
   1317 
   1318             IntPDNumber = 0;
   1319             while (*PFieldList)
   1320             {
   1321                 Status = DtCompileTable (PFieldList,
   1322                     AcpiDmTableInfoHmat1a, &Subtable, TRUE);
   1323                 if (ACPI_FAILURE (Status))
   1324                 {
   1325                     return (Status);
   1326                 }
   1327                 if (!Subtable)
   1328                 {
   1329                     break;
   1330                 }
   1331                 DtInsertSubtable (ParentTable, Subtable);
   1332                 HmatStruct->Length += Subtable->Length;
   1333                 IntPDNumber++;
   1334             }
   1335             HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
   1336 
   1337             /* Compile target proximity domain list */
   1338 
   1339             TgtPDNumber = 0;
   1340             while (*PFieldList)
   1341             {
   1342                 Status = DtCompileTable (PFieldList,
   1343                     AcpiDmTableInfoHmat1b, &Subtable, TRUE);
   1344                 if (ACPI_FAILURE (Status))
   1345                 {
   1346                     return (Status);
   1347                 }
   1348                 if (!Subtable)
   1349                 {
   1350                     break;
   1351                 }
   1352                 DtInsertSubtable (ParentTable, Subtable);
   1353                 HmatStruct->Length += Subtable->Length;
   1354                 TgtPDNumber++;
   1355             }
   1356             HmatLocality->NumberOfTargetPDs = TgtPDNumber;
   1357 
   1358             /* Save start of the entries for reporting errors */
   1359 
   1360             EntryStart = *PFieldList;
   1361 
   1362             /* Compile latency/bandwidth entries */
   1363 
   1364             EntryNumber = 0;
   1365             while (*PFieldList)
   1366             {
   1367                 Status = DtCompileTable (PFieldList,
   1368                     AcpiDmTableInfoHmat1c, &Subtable, TRUE);
   1369                 if (ACPI_FAILURE (Status))
   1370                 {
   1371                     return (Status);
   1372                 }
   1373                 if (!Subtable)
   1374                 {
   1375                     break;
   1376                 }
   1377                 DtInsertSubtable (ParentTable, Subtable);
   1378                 HmatStruct->Length += Subtable->Length;
   1379                 EntryNumber++;
   1380             }
   1381 
   1382             /* Validate number of entries */
   1383 
   1384             if (EntryNumber !=
   1385                 ((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
   1386             {
   1387                 DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
   1388                 return (AE_ERROR);
   1389             }
   1390             break;
   1391 
   1392         case ACPI_HMAT_TYPE_CACHE:
   1393 
   1394             /* Compile SMBIOS handles */
   1395 
   1396             HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
   1397                 Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
   1398             SMBIOSHandleNumber = 0;
   1399             while (*PFieldList)
   1400             {
   1401                 Status = DtCompileTable (PFieldList,
   1402                     AcpiDmTableInfoHmat2a, &Subtable, TRUE);
   1403                 if (ACPI_FAILURE (Status))
   1404                 {
   1405                     return (Status);
   1406                 }
   1407                 if (!Subtable)
   1408                 {
   1409                     break;
   1410                 }
   1411                 DtInsertSubtable (ParentTable, Subtable);
   1412                 HmatStruct->Length += Subtable->Length;
   1413                 SMBIOSHandleNumber++;
   1414             }
   1415             HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
   1416             break;
   1417 
   1418         default:
   1419 
   1420             break;
   1421         }
   1422     }
   1423 
   1424     return (AE_OK);
   1425 }
   1426 
   1427 
   1428 /******************************************************************************
   1429  *
   1430  * FUNCTION:    DtCompileIort
   1431  *
   1432  * PARAMETERS:  List                - Current field list pointer
   1433  *
   1434  * RETURN:      Status
   1435  *
   1436  * DESCRIPTION: Compile IORT.
   1437  *
   1438  *****************************************************************************/
   1439 
   1440 ACPI_STATUS
   1441 DtCompileIort (
   1442     void                    **List)
   1443 {
   1444     ACPI_STATUS             Status;
   1445     DT_SUBTABLE             *Subtable;
   1446     DT_SUBTABLE             *ParentTable;
   1447     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1448     DT_FIELD                *SubtableStart;
   1449     ACPI_TABLE_IORT         *Iort;
   1450     ACPI_IORT_NODE          *IortNode;
   1451     ACPI_IORT_ITS_GROUP     *IortItsGroup;
   1452     ACPI_IORT_SMMU          *IortSmmu;
   1453     UINT32                  NodeNumber;
   1454     UINT32                  NodeLength;
   1455     UINT32                  IdMappingNumber;
   1456     UINT32                  ItsNumber;
   1457     UINT32                  ContextIrptNumber;
   1458     UINT32                  PmuIrptNumber;
   1459     UINT32                  PaddingLength;
   1460 
   1461 
   1462     ParentTable = DtPeekSubtable ();
   1463 
   1464     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort,
   1465         &Subtable, TRUE);
   1466     if (ACPI_FAILURE (Status))
   1467     {
   1468         return (Status);
   1469     }
   1470     DtInsertSubtable (ParentTable, Subtable);
   1471 
   1472     /*
   1473      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   1474      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
   1475      */
   1476     Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
   1477         Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
   1478 
   1479     /*
   1480      * OptionalPadding - Variable-length data
   1481      * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT))
   1482      * Optionally allows the generic data types to be used for filling
   1483      * this field.
   1484      */
   1485     Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
   1486     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
   1487         &Subtable, TRUE);
   1488     if (ACPI_FAILURE (Status))
   1489     {
   1490         return (Status);
   1491     }
   1492     if (Subtable)
   1493     {
   1494         DtInsertSubtable (ParentTable, Subtable);
   1495         Iort->NodeOffset += Subtable->Length;
   1496     }
   1497     else
   1498     {
   1499         Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList),
   1500             AcpiDmTableInfoIortHdr[0].Name, &PaddingLength);
   1501         if (ACPI_FAILURE (Status))
   1502         {
   1503             return (Status);
   1504         }
   1505         Iort->NodeOffset += PaddingLength;
   1506     }
   1507 
   1508     NodeNumber = 0;
   1509     while (*PFieldList)
   1510     {
   1511         SubtableStart = *PFieldList;
   1512         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr,
   1513             &Subtable, TRUE);
   1514         if (ACPI_FAILURE (Status))
   1515         {
   1516             return (Status);
   1517         }
   1518 
   1519         DtInsertSubtable (ParentTable, Subtable);
   1520         IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer);
   1521         NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
   1522 
   1523         DtPushSubtable (Subtable);
   1524         ParentTable = DtPeekSubtable ();
   1525 
   1526         switch (IortNode->Type)
   1527         {
   1528         case ACPI_IORT_NODE_ITS_GROUP:
   1529 
   1530             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0,
   1531                 &Subtable, TRUE);
   1532             if (ACPI_FAILURE (Status))
   1533             {
   1534                 return (Status);
   1535             }
   1536 
   1537             DtInsertSubtable (ParentTable, Subtable);
   1538             IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer);
   1539             NodeLength += Subtable->Length;
   1540 
   1541             ItsNumber = 0;
   1542             while (*PFieldList)
   1543             {
   1544                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a,
   1545                     &Subtable, TRUE);
   1546                 if (ACPI_FAILURE (Status))
   1547                 {
   1548                     return (Status);
   1549                 }
   1550                 if (!Subtable)
   1551                 {
   1552                     break;
   1553                 }
   1554 
   1555                 DtInsertSubtable (ParentTable, Subtable);
   1556                 NodeLength += Subtable->Length;
   1557                 ItsNumber++;
   1558             }
   1559 
   1560             IortItsGroup->ItsCount = ItsNumber;
   1561             break;
   1562 
   1563         case ACPI_IORT_NODE_NAMED_COMPONENT:
   1564 
   1565             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1,
   1566                 &Subtable, TRUE);
   1567             if (ACPI_FAILURE (Status))
   1568             {
   1569                 return (Status);
   1570             }
   1571 
   1572             DtInsertSubtable (ParentTable, Subtable);
   1573             NodeLength += Subtable->Length;
   1574 
   1575             /*
   1576              * Padding - Variable-length data
   1577              * Optionally allows the offset of the ID mappings to be used
   1578              * for filling this field.
   1579              */
   1580             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
   1581                 &Subtable, TRUE);
   1582             if (ACPI_FAILURE (Status))
   1583             {
   1584                 return (Status);
   1585             }
   1586 
   1587             if (Subtable)
   1588             {
   1589                 DtInsertSubtable (ParentTable, Subtable);
   1590                 NodeLength += Subtable->Length;
   1591             }
   1592             else
   1593             {
   1594                 if (NodeLength > IortNode->MappingOffset)
   1595                 {
   1596                     return (AE_BAD_DATA);
   1597                 }
   1598 
   1599                 if (NodeLength < IortNode->MappingOffset)
   1600                 {
   1601                     Status = DtCompilePadding (
   1602                         IortNode->MappingOffset - NodeLength,
   1603                         &Subtable);
   1604                     if (ACPI_FAILURE (Status))
   1605                     {
   1606                         return (Status);
   1607                     }
   1608 
   1609                     DtInsertSubtable (ParentTable, Subtable);
   1610                     NodeLength = IortNode->MappingOffset;
   1611                 }
   1612             }
   1613             break;
   1614 
   1615         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
   1616 
   1617             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2,
   1618                 &Subtable, TRUE);
   1619             if (ACPI_FAILURE (Status))
   1620             {
   1621                 return (Status);
   1622             }
   1623 
   1624             DtInsertSubtable (ParentTable, Subtable);
   1625             NodeLength += Subtable->Length;
   1626             break;
   1627 
   1628         case ACPI_IORT_NODE_SMMU:
   1629 
   1630             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
   1631                 &Subtable, TRUE);
   1632             if (ACPI_FAILURE (Status))
   1633             {
   1634                 return (Status);
   1635             }
   1636 
   1637             DtInsertSubtable (ParentTable, Subtable);
   1638             IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
   1639             NodeLength += Subtable->Length;
   1640 
   1641             /* Compile global interrupt array */
   1642 
   1643             IortSmmu->GlobalInterruptOffset = NodeLength;
   1644             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
   1645                 &Subtable, TRUE);
   1646             if (ACPI_FAILURE (Status))
   1647             {
   1648                 return (Status);
   1649             }
   1650 
   1651             DtInsertSubtable (ParentTable, Subtable);
   1652             NodeLength += Subtable->Length;
   1653 
   1654             /* Compile context interrupt array */
   1655 
   1656             ContextIrptNumber = 0;
   1657             IortSmmu->ContextInterruptOffset = NodeLength;
   1658             while (*PFieldList)
   1659             {
   1660                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
   1661                     &Subtable, TRUE);
   1662                 if (ACPI_FAILURE (Status))
   1663                 {
   1664                     return (Status);
   1665                 }
   1666 
   1667                 if (!Subtable)
   1668                 {
   1669                     break;
   1670                 }
   1671 
   1672                 DtInsertSubtable (ParentTable, Subtable);
   1673                 NodeLength += Subtable->Length;
   1674                 ContextIrptNumber++;
   1675             }
   1676 
   1677             IortSmmu->ContextInterruptCount = ContextIrptNumber;
   1678 
   1679             /* Compile PMU interrupt array */
   1680 
   1681             PmuIrptNumber = 0;
   1682             IortSmmu->PmuInterruptOffset = NodeLength;
   1683             while (*PFieldList)
   1684             {
   1685                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
   1686                     &Subtable, TRUE);
   1687                 if (ACPI_FAILURE (Status))
   1688                 {
   1689                     return (Status);
   1690                 }
   1691 
   1692                 if (!Subtable)
   1693                 {
   1694                     break;
   1695                 }
   1696 
   1697                 DtInsertSubtable (ParentTable, Subtable);
   1698                 NodeLength += Subtable->Length;
   1699                 PmuIrptNumber++;
   1700             }
   1701 
   1702             IortSmmu->PmuInterruptCount = PmuIrptNumber;
   1703             break;
   1704 
   1705         case ACPI_IORT_NODE_SMMU_V3:
   1706 
   1707             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
   1708                 &Subtable, TRUE);
   1709             if (ACPI_FAILURE (Status))
   1710             {
   1711                 return (Status);
   1712             }
   1713 
   1714             DtInsertSubtable (ParentTable, Subtable);
   1715             NodeLength += Subtable->Length;
   1716             break;
   1717 
   1718         default:
   1719 
   1720             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
   1721             return (AE_ERROR);
   1722         }
   1723 
   1724         /* Compile Array of ID mappings */
   1725 
   1726         IortNode->MappingOffset = NodeLength;
   1727         IdMappingNumber = 0;
   1728         while (*PFieldList)
   1729         {
   1730             Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
   1731                 &Subtable, TRUE);
   1732             if (ACPI_FAILURE (Status))
   1733             {
   1734                 return (Status);
   1735             }
   1736 
   1737             if (!Subtable)
   1738             {
   1739                 break;
   1740             }
   1741 
   1742             DtInsertSubtable (ParentTable, Subtable);
   1743             NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
   1744             IdMappingNumber++;
   1745         }
   1746 
   1747         IortNode->MappingCount = IdMappingNumber;
   1748         if (!IdMappingNumber)
   1749         {
   1750             IortNode->MappingOffset = 0;
   1751         }
   1752 
   1753         /*
   1754          * Node length can be determined by DT_LENGTH option
   1755          * IortNode->Length = NodeLength;
   1756          */
   1757         DtPopSubtable ();
   1758         ParentTable = DtPeekSubtable ();
   1759         NodeNumber++;
   1760     }
   1761 
   1762     Iort->NodeCount = NodeNumber;
   1763     return (AE_OK);
   1764 }
   1765 
   1766 
   1767 /******************************************************************************
   1768  *
   1769  * FUNCTION:    DtCompileIvrs
   1770  *
   1771  * PARAMETERS:  List                - Current field list pointer
   1772  *
   1773  * RETURN:      Status
   1774  *
   1775  * DESCRIPTION: Compile IVRS.
   1776  *
   1777  *****************************************************************************/
   1778 
   1779 ACPI_STATUS
   1780 DtCompileIvrs (
   1781     void                    **List)
   1782 {
   1783     ACPI_STATUS             Status;
   1784     DT_SUBTABLE             *Subtable;
   1785     DT_SUBTABLE             *ParentTable;
   1786     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1787     DT_FIELD                *SubtableStart;
   1788     ACPI_DMTABLE_INFO       *InfoTable;
   1789     ACPI_IVRS_HEADER        *IvrsHeader;
   1790     UINT8                   EntryType;
   1791 
   1792 
   1793     Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs,
   1794         &Subtable, TRUE);
   1795     if (ACPI_FAILURE (Status))
   1796     {
   1797         return (Status);
   1798     }
   1799 
   1800     ParentTable = DtPeekSubtable ();
   1801     DtInsertSubtable (ParentTable, Subtable);
   1802 
   1803     while (*PFieldList)
   1804     {
   1805         SubtableStart = *PFieldList;
   1806         Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
   1807             &Subtable, TRUE);
   1808         if (ACPI_FAILURE (Status))
   1809         {
   1810             return (Status);
   1811         }
   1812 
   1813         ParentTable = DtPeekSubtable ();
   1814         DtInsertSubtable (ParentTable, Subtable);
   1815         DtPushSubtable (Subtable);
   1816 
   1817         IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer);
   1818 
   1819         switch (IvrsHeader->Type)
   1820         {
   1821         case ACPI_IVRS_TYPE_HARDWARE:
   1822 
   1823             InfoTable = AcpiDmTableInfoIvrs0;
   1824             break;
   1825 
   1826         case ACPI_IVRS_TYPE_MEMORY1:
   1827         case ACPI_IVRS_TYPE_MEMORY2:
   1828         case ACPI_IVRS_TYPE_MEMORY3:
   1829 
   1830             InfoTable = AcpiDmTableInfoIvrs1;
   1831             break;
   1832 
   1833         default:
   1834 
   1835             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS");
   1836             return (AE_ERROR);
   1837         }
   1838 
   1839         Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE);
   1840         if (ACPI_FAILURE (Status))
   1841         {
   1842             return (Status);
   1843         }
   1844 
   1845         ParentTable = DtPeekSubtable ();
   1846         DtInsertSubtable (ParentTable, Subtable);
   1847 
   1848         if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE)
   1849         {
   1850             while (*PFieldList &&
   1851                 !strcmp ((*PFieldList)->Name, "Entry Type"))
   1852             {
   1853                 SubtableStart = *PFieldList;
   1854                 DtCompileInteger (&EntryType, *PFieldList, 1, 0);
   1855 
   1856                 switch (EntryType)
   1857                 {
   1858                 /* 4-byte device entries */
   1859 
   1860                 case ACPI_IVRS_TYPE_PAD4:
   1861                 case ACPI_IVRS_TYPE_ALL:
   1862                 case ACPI_IVRS_TYPE_SELECT:
   1863                 case ACPI_IVRS_TYPE_START:
   1864                 case ACPI_IVRS_TYPE_END:
   1865 
   1866                     InfoTable = AcpiDmTableInfoIvrs4;
   1867                     break;
   1868 
   1869                 /* 8-byte entries, type A */
   1870 
   1871                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
   1872                 case ACPI_IVRS_TYPE_ALIAS_START:
   1873 
   1874                     InfoTable = AcpiDmTableInfoIvrs8a;
   1875                     break;
   1876 
   1877                 /* 8-byte entries, type B */
   1878 
   1879                 case ACPI_IVRS_TYPE_PAD8:
   1880                 case ACPI_IVRS_TYPE_EXT_SELECT:
   1881                 case ACPI_IVRS_TYPE_EXT_START:
   1882 
   1883                     InfoTable = AcpiDmTableInfoIvrs8b;
   1884                     break;
   1885 
   1886                 /* 8-byte entries, type C */
   1887 
   1888                 case ACPI_IVRS_TYPE_SPECIAL:
   1889 
   1890                     InfoTable = AcpiDmTableInfoIvrs8c;
   1891                     break;
   1892 
   1893                 default:
   1894 
   1895                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart,
   1896                         "IVRS Device Entry");
   1897                     return (AE_ERROR);
   1898                 }
   1899 
   1900                 Status = DtCompileTable (PFieldList, InfoTable,
   1901                     &Subtable, TRUE);
   1902                 if (ACPI_FAILURE (Status))
   1903                 {
   1904                     return (Status);
   1905                 }
   1906 
   1907                 DtInsertSubtable (ParentTable, Subtable);
   1908             }
   1909         }
   1910 
   1911         DtPopSubtable ();
   1912     }
   1913 
   1914     return (AE_OK);
   1915 }
   1916