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