Home | History | Annotate | Line # | Download | only in compiler
dttable2.c revision 1.1.1.18
      1 /******************************************************************************
      2  *
      3  * Module Name: dttable2.c - handling for specific ACPI tables
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2023, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 /* Compile all complex data tables, signatures starting with L-Z */
     45 
     46 #include "aslcompiler.h"
     47 
     48 #define _COMPONENT          DT_COMPILER
     49         ACPI_MODULE_NAME    ("dttable2")
     50 
     51 
     52 /******************************************************************************
     53  *
     54  * FUNCTION:    DtCompileLpit
     55  *
     56  * PARAMETERS:  List                - Current field list pointer
     57  *
     58  * RETURN:      Status
     59  *
     60  * DESCRIPTION: Compile LPIT.
     61  *
     62  *****************************************************************************/
     63 
     64 ACPI_STATUS
     65 DtCompileLpit (
     66     void                    **List)
     67 {
     68     ACPI_STATUS             Status;
     69     DT_SUBTABLE             *Subtable;
     70     DT_SUBTABLE             *ParentTable;
     71     DT_FIELD                **PFieldList = (DT_FIELD **) List;
     72     DT_FIELD                *SubtableStart;
     73     ACPI_DMTABLE_INFO       *InfoTable;
     74     ACPI_LPIT_HEADER        *LpitHeader;
     75 
     76 
     77     /* Note: Main table consists only of the standard ACPI table header */
     78 
     79     while (*PFieldList)
     80     {
     81         SubtableStart = *PFieldList;
     82 
     83         /* LPIT Subtable header */
     84 
     85         Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr,
     86             &Subtable);
     87         if (ACPI_FAILURE (Status))
     88         {
     89             return (Status);
     90         }
     91 
     92         ParentTable = DtPeekSubtable ();
     93         DtInsertSubtable (ParentTable, Subtable);
     94         DtPushSubtable (Subtable);
     95 
     96         LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer);
     97 
     98         switch (LpitHeader->Type)
     99         {
    100         case ACPI_LPIT_TYPE_NATIVE_CSTATE:
    101 
    102             InfoTable = AcpiDmTableInfoLpit0;
    103             break;
    104 
    105         default:
    106 
    107             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT");
    108             return (AE_ERROR);
    109         }
    110 
    111         /* LPIT Subtable */
    112 
    113         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    114         if (ACPI_FAILURE (Status))
    115         {
    116             return (Status);
    117         }
    118 
    119         ParentTable = DtPeekSubtable ();
    120         DtInsertSubtable (ParentTable, Subtable);
    121         DtPopSubtable ();
    122     }
    123 
    124     return (AE_OK);
    125 }
    126 
    127 
    128 /******************************************************************************
    129  *
    130  * FUNCTION:    DtCompileMadt
    131  *
    132  * PARAMETERS:  List                - Current field list pointer
    133  *
    134  * RETURN:      Status
    135  *
    136  * DESCRIPTION: Compile MADT.
    137  *
    138  *****************************************************************************/
    139 
    140 ACPI_STATUS
    141 DtCompileMadt (
    142     void                    **List)
    143 {
    144     ACPI_STATUS             Status;
    145     DT_SUBTABLE             *Subtable;
    146     DT_SUBTABLE             *ParentTable;
    147     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    148     DT_FIELD                *SubtableStart;
    149     ACPI_TABLE_HEADER       *Table;
    150     ACPI_SUBTABLE_HEADER    *MadtHeader;
    151     ACPI_DMTABLE_INFO       *InfoTable;
    152     UINT8                   Revision;
    153 
    154 
    155     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt,
    156         &Subtable);
    157     if (ACPI_FAILURE (Status))
    158     {
    159         return (Status);
    160     }
    161 
    162     ParentTable = DtPeekSubtable ();
    163     DtInsertSubtable (ParentTable, Subtable);
    164 
    165     Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
    166     Revision = Table->Revision;
    167 
    168     while (*PFieldList)
    169     {
    170         SubtableStart = *PFieldList;
    171         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr,
    172             &Subtable);
    173         if (ACPI_FAILURE (Status))
    174         {
    175             return (Status);
    176         }
    177 
    178         ParentTable = DtPeekSubtable ();
    179         DtInsertSubtable (ParentTable, Subtable);
    180         DtPushSubtable (Subtable);
    181 
    182         MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
    183 
    184         switch (MadtHeader->Type)
    185         {
    186         case ACPI_MADT_TYPE_LOCAL_APIC:
    187 
    188             InfoTable = AcpiDmTableInfoMadt0;
    189             break;
    190 
    191         case ACPI_MADT_TYPE_IO_APIC:
    192 
    193             InfoTable = AcpiDmTableInfoMadt1;
    194             break;
    195 
    196         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
    197 
    198             InfoTable = AcpiDmTableInfoMadt2;
    199             break;
    200 
    201         case ACPI_MADT_TYPE_NMI_SOURCE:
    202 
    203             InfoTable = AcpiDmTableInfoMadt3;
    204             break;
    205 
    206         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
    207 
    208             InfoTable = AcpiDmTableInfoMadt4;
    209             break;
    210 
    211         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
    212 
    213             InfoTable = AcpiDmTableInfoMadt5;
    214             break;
    215 
    216         case ACPI_MADT_TYPE_IO_SAPIC:
    217 
    218             InfoTable = AcpiDmTableInfoMadt6;
    219             break;
    220 
    221         case ACPI_MADT_TYPE_LOCAL_SAPIC:
    222 
    223             InfoTable = AcpiDmTableInfoMadt7;
    224             break;
    225 
    226         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
    227 
    228             InfoTable = AcpiDmTableInfoMadt8;
    229             break;
    230 
    231         case ACPI_MADT_TYPE_LOCAL_X2APIC:
    232 
    233             InfoTable = AcpiDmTableInfoMadt9;
    234             break;
    235 
    236         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
    237 
    238             InfoTable = AcpiDmTableInfoMadt10;
    239             break;
    240 
    241         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
    242 
    243             if (Revision > 6)
    244                     InfoTable = AcpiDmTableInfoMadt11b;
    245             else if (Revision == 6)
    246                     InfoTable = AcpiDmTableInfoMadt11a;
    247             else
    248                     InfoTable = AcpiDmTableInfoMadt11;
    249             break;
    250 
    251         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
    252 
    253             InfoTable = AcpiDmTableInfoMadt12;
    254             break;
    255 
    256         case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
    257 
    258             InfoTable = AcpiDmTableInfoMadt13;
    259             break;
    260 
    261         case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
    262 
    263             InfoTable = Revision > 6 ? AcpiDmTableInfoMadt14a
    264                                      : AcpiDmTableInfoMadt14;
    265             break;
    266 
    267         case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
    268 
    269             InfoTable = Revision > 6 ? AcpiDmTableInfoMadt15a
    270                                      : AcpiDmTableInfoMadt15;
    271 
    272             break;
    273 
    274         case ACPI_MADT_TYPE_MULTIPROC_WAKEUP:
    275 
    276             InfoTable = AcpiDmTableInfoMadt16;
    277             break;
    278 
    279         case ACPI_MADT_TYPE_CORE_PIC:
    280 
    281             InfoTable = AcpiDmTableInfoMadt17;
    282             break;
    283 
    284         case ACPI_MADT_TYPE_LIO_PIC:
    285 
    286             InfoTable = AcpiDmTableInfoMadt18;
    287             break;
    288 
    289         case ACPI_MADT_TYPE_HT_PIC:
    290 
    291             InfoTable = AcpiDmTableInfoMadt19;
    292             break;
    293 
    294         case ACPI_MADT_TYPE_EIO_PIC:
    295 
    296             InfoTable = AcpiDmTableInfoMadt20;
    297             break;
    298 
    299         case ACPI_MADT_TYPE_MSI_PIC:
    300 
    301             InfoTable = AcpiDmTableInfoMadt21;
    302             break;
    303 
    304         case ACPI_MADT_TYPE_BIO_PIC:
    305 
    306             InfoTable = AcpiDmTableInfoMadt22;
    307             break;
    308 
    309         case ACPI_MADT_TYPE_LPC_PIC:
    310 
    311             InfoTable = AcpiDmTableInfoMadt23;
    312             break;
    313 
    314         case ACPI_MADT_TYPE_RINTC:
    315 
    316             InfoTable = AcpiDmTableInfoMadt24;
    317             break;
    318 
    319         case ACPI_MADT_TYPE_IMSIC:
    320 
    321             InfoTable = AcpiDmTableInfoMadt25;
    322             break;
    323 
    324         case ACPI_MADT_TYPE_APLIC:
    325 
    326             InfoTable = AcpiDmTableInfoMadt26;
    327             break;
    328 
    329         case ACPI_MADT_TYPE_PLIC:
    330 
    331             InfoTable = AcpiDmTableInfoMadt27;
    332             break;
    333 
    334         default:
    335 
    336             if (MadtHeader->Type >= ACPI_MADT_TYPE_OEM_RESERVED)
    337             {
    338                 InfoTable = AcpiDmTableInfoMadt128;
    339             }
    340             else
    341             {
    342                 DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
    343                 return (AE_ERROR);
    344             }
    345 
    346             break;
    347         }
    348 
    349         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    350         if (ACPI_FAILURE (Status))
    351         {
    352             return (Status);
    353         }
    354 
    355         ParentTable = DtPeekSubtable ();
    356         DtInsertSubtable (ParentTable, Subtable);
    357         DtPopSubtable ();
    358     }
    359 
    360     return (AE_OK);
    361 }
    362 
    363 
    364 /******************************************************************************
    365  *
    366  * FUNCTION:    DtCompileMcfg
    367  *
    368  * PARAMETERS:  List                - Current field list pointer
    369  *
    370  * RETURN:      Status
    371  *
    372  * DESCRIPTION: Compile MCFG.
    373  *
    374  *****************************************************************************/
    375 
    376 ACPI_STATUS
    377 DtCompileMcfg (
    378     void                    **List)
    379 {
    380     ACPI_STATUS             Status;
    381 
    382 
    383     Status = DtCompileTwoSubtables (List,
    384         AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
    385     return (Status);
    386 }
    387 
    388 /******************************************************************************
    389  *
    390  * FUNCTION:    DtCompileMpam
    391  *
    392  * PARAMETERS:  List                - Current field list pointer
    393  *
    394  * RETURN:      Status
    395  *
    396  * DESCRIPTION: Compile MPAM.
    397  *
    398  *****************************************************************************/
    399 
    400 ACPI_STATUS
    401 DtCompileMpam (
    402     void                    **List)
    403 {
    404     ACPI_STATUS             Status;
    405     DT_SUBTABLE             *ParentTable;
    406     DT_SUBTABLE             *Subtable;
    407     DT_FIELD                *SubtableStart;
    408     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    409     ACPI_MPAM_MSC_NODE      *MpamMscNode;
    410     ACPI_MPAM_RESOURCE_NODE *MpamResourceNode;
    411     UINT32                  FuncDepsCount;
    412     UINT32                  RisLength;
    413     ACPI_DMTABLE_INFO       *InfoTable;
    414 
    415     ParentTable = DtPeekSubtable ();
    416 
    417     while (*PFieldList)
    418     {
    419         SubtableStart = *PFieldList;
    420 
    421         /* Main MSC Node table */
    422         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam0,
    423             &Subtable);
    424         if (ACPI_FAILURE (Status))
    425         {
    426             return (Status);
    427         }
    428 
    429         MpamMscNode = ACPI_CAST_PTR (ACPI_MPAM_MSC_NODE, Subtable->Buffer);
    430 
    431         ParentTable = DtPeekSubtable ();
    432         DtInsertSubtable (ParentTable, Subtable);
    433         DtPushSubtable (Subtable);
    434 
    435         ParentTable = DtPeekSubtable ();
    436 
    437         /*
    438          * RIS(es) per MSC node have variable lengths depending on how many RISes there and
    439          * any how many functional dependencies per RIS. Calculate it in order
    440          * to properly set the overall MSC length.
    441          */
    442         RisLength = 0;
    443 
    444         /* Iterate over RIS subtables per MSC node */
    445         for (UINT32 ris = 0; ris < MpamMscNode->NumResourceNodes; ris++)
    446         {
    447             /* Compile RIS subtable */
    448             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1,
    449                 &Subtable);
    450             if (ACPI_FAILURE (Status))
    451             {
    452                 return (Status);
    453             }
    454 
    455             MpamResourceNode = ACPI_CAST_PTR (ACPI_MPAM_RESOURCE_NODE, Subtable->Buffer);
    456             DtInsertSubtable (ParentTable, Subtable);
    457             DtPushSubtable (Subtable);
    458 
    459             ParentTable = DtPeekSubtable ();
    460 
    461             switch (MpamResourceNode->LocatorType)
    462             {
    463                 case ACPI_MPAM_LOCATION_TYPE_PROCESSOR_CACHE:
    464                     InfoTable = AcpiDmTableInfoMpam1A;
    465                     break;
    466                 case ACPI_MPAM_LOCATION_TYPE_MEMORY:
    467                     InfoTable = AcpiDmTableInfoMpam1B;
    468                     break;
    469                 case ACPI_MPAM_LOCATION_TYPE_SMMU:
    470                     InfoTable = AcpiDmTableInfoMpam1C;
    471                     break;
    472                 case ACPI_MPAM_LOCATION_TYPE_MEMORY_CACHE:
    473                     InfoTable = AcpiDmTableInfoMpam1D;
    474                     break;
    475                 case ACPI_MPAM_LOCATION_TYPE_ACPI_DEVICE:
    476                     InfoTable = AcpiDmTableInfoMpam1E;
    477                     break;
    478                 case ACPI_MPAM_LOCATION_TYPE_INTERCONNECT:
    479                     InfoTable = AcpiDmTableInfoMpam1F;
    480                     break;
    481                 case ACPI_MPAM_LOCATION_TYPE_UNKNOWN:
    482                     InfoTable = AcpiDmTableInfoMpam1G;
    483                 default:
    484                     DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "Resource Locator Type");
    485                     return (AE_ERROR);
    486             }
    487 
    488             /* Compile Resource Locator Table */
    489             Status = DtCompileTable (PFieldList, InfoTable,
    490                 &Subtable);
    491 
    492             if (ACPI_FAILURE (Status))
    493             {
    494                 return (Status);
    495             }
    496 
    497             DtInsertSubtable (ParentTable, Subtable);
    498 
    499             /* Compile the number of functional dependencies per RIS */
    500             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1Deps,
    501                 &Subtable);
    502 
    503             if (ACPI_FAILURE (Status))
    504             {
    505                 return (Status);
    506             }
    507 
    508             DtInsertSubtable (ParentTable, Subtable);
    509             FuncDepsCount = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
    510 
    511             RisLength += sizeof(ACPI_MPAM_RESOURCE_NODE) +
    512                 FuncDepsCount * sizeof(ACPI_MPAM_FUNC_DEPS);
    513 
    514             /* Iterate over functional dependencies per RIS */
    515             for (UINT32 funcDep = 0; funcDep < FuncDepsCount; funcDep++)
    516             {
    517                 /* Compiler functional dependencies table */
    518                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam2,
    519                     &Subtable);
    520 
    521                 if (ACPI_FAILURE (Status))
    522                 {
    523                     return (Status);
    524                 }
    525 
    526                 DtInsertSubtable (ParentTable, Subtable);
    527             }
    528 
    529             DtPopSubtable ();
    530         }
    531 
    532         /* Check if the length of the MSC is correct and override with the correct length */
    533         if (MpamMscNode->Length != sizeof(ACPI_MPAM_MSC_NODE) + RisLength)
    534         {
    535             MpamMscNode->Length = (UINT16) (sizeof(ACPI_MPAM_MSC_NODE) + RisLength);
    536             DbgPrint (ASL_DEBUG_OUTPUT, "Overriding MSC->Length: %X\n", MpamMscNode->Length);
    537         }
    538 
    539         DtPopSubtable ();
    540     }
    541 
    542     return (AE_OK);
    543 }
    544 
    545 
    546 /******************************************************************************
    547  *
    548  * FUNCTION:    DtCompileMpst
    549  *
    550  * PARAMETERS:  List                - Current field list pointer
    551  *
    552  * RETURN:      Status
    553  *
    554  * DESCRIPTION: Compile MPST.
    555  *
    556  *****************************************************************************/
    557 
    558 ACPI_STATUS
    559 DtCompileMpst (
    560     void                    **List)
    561 {
    562     ACPI_STATUS             Status;
    563     DT_SUBTABLE             *Subtable;
    564     DT_SUBTABLE             *ParentTable;
    565     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    566     ACPI_MPST_CHANNEL       *MpstChannelInfo;
    567     ACPI_MPST_POWER_NODE    *MpstPowerNode;
    568     ACPI_MPST_DATA_HDR      *MpstDataHeader;
    569     UINT16                  SubtableCount;
    570     UINT32                  PowerStateCount;
    571     UINT32                  ComponentCount;
    572 
    573 
    574     /* Main table */
    575 
    576     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable);
    577     if (ACPI_FAILURE (Status))
    578     {
    579         return (Status);
    580     }
    581 
    582     ParentTable = DtPeekSubtable ();
    583     DtInsertSubtable (ParentTable, Subtable);
    584     DtPushSubtable (Subtable);
    585 
    586     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
    587     SubtableCount = MpstChannelInfo->PowerNodeCount;
    588 
    589     while (*PFieldList && SubtableCount)
    590     {
    591         /* Subtable: Memory Power Node(s) */
    592 
    593         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
    594             &Subtable);
    595         if (ACPI_FAILURE (Status))
    596         {
    597             return (Status);
    598         }
    599 
    600         ParentTable = DtPeekSubtable ();
    601         DtInsertSubtable (ParentTable, Subtable);
    602         DtPushSubtable (Subtable);
    603 
    604         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
    605         PowerStateCount = MpstPowerNode->NumPowerStates;
    606         ComponentCount = MpstPowerNode->NumPhysicalComponents;
    607 
    608         ParentTable = DtPeekSubtable ();
    609 
    610         /* Sub-subtables - Memory Power State Structure(s) */
    611 
    612         while (*PFieldList && PowerStateCount)
    613         {
    614             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
    615                 &Subtable);
    616             if (ACPI_FAILURE (Status))
    617             {
    618                 return (Status);
    619             }
    620 
    621             DtInsertSubtable (ParentTable, Subtable);
    622             PowerStateCount--;
    623         }
    624 
    625         /* Sub-subtables - Physical Component ID Structure(s) */
    626 
    627         while (*PFieldList && ComponentCount)
    628         {
    629             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
    630                 &Subtable);
    631             if (ACPI_FAILURE (Status))
    632             {
    633                 return (Status);
    634             }
    635 
    636             DtInsertSubtable (ParentTable, Subtable);
    637             ComponentCount--;
    638         }
    639 
    640         SubtableCount--;
    641         DtPopSubtable ();
    642     }
    643 
    644     /* Subtable: Count of Memory Power State Characteristic structures */
    645 
    646     DtPopSubtable ();
    647 
    648     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable);
    649     if (ACPI_FAILURE (Status))
    650     {
    651         return (Status);
    652     }
    653 
    654     ParentTable = DtPeekSubtable ();
    655     DtInsertSubtable (ParentTable, Subtable);
    656     DtPushSubtable (Subtable);
    657 
    658     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
    659     SubtableCount = MpstDataHeader->CharacteristicsCount;
    660 
    661     ParentTable = DtPeekSubtable ();
    662 
    663     /* Subtable: Memory Power State Characteristics structure(s) */
    664 
    665     while (*PFieldList && SubtableCount)
    666     {
    667         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
    668             &Subtable);
    669         if (ACPI_FAILURE (Status))
    670         {
    671             return (Status);
    672         }
    673 
    674         DtInsertSubtable (ParentTable, Subtable);
    675         SubtableCount--;
    676     }
    677 
    678     DtPopSubtable ();
    679     return (AE_OK);
    680 }
    681 
    682 
    683 /******************************************************************************
    684  *
    685  * FUNCTION:    DtCompileMsct
    686  *
    687  * PARAMETERS:  List                - Current field list pointer
    688  *
    689  * RETURN:      Status
    690  *
    691  * DESCRIPTION: Compile MSCT.
    692  *
    693  *****************************************************************************/
    694 
    695 ACPI_STATUS
    696 DtCompileMsct (
    697     void                    **List)
    698 {
    699     ACPI_STATUS             Status;
    700 
    701 
    702     Status = DtCompileTwoSubtables (List,
    703         AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
    704     return (Status);
    705 }
    706 
    707 
    708 /******************************************************************************
    709  *
    710  * FUNCTION:    DtCompileNfit
    711  *
    712  * PARAMETERS:  List                - Current field list pointer
    713  *
    714  * RETURN:      Status
    715  *
    716  * DESCRIPTION: Compile NFIT.
    717  *
    718  *****************************************************************************/
    719 
    720 ACPI_STATUS
    721 DtCompileNfit (
    722     void                    **List)
    723 {
    724     ACPI_STATUS             Status;
    725     DT_SUBTABLE             *Subtable;
    726     DT_SUBTABLE             *ParentTable;
    727     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    728     DT_FIELD                *SubtableStart;
    729     ACPI_NFIT_HEADER        *NfitHeader;
    730     ACPI_DMTABLE_INFO       *InfoTable;
    731     UINT32                  Count;
    732     ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
    733     ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
    734 
    735 
    736     /* Main table */
    737 
    738     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
    739         &Subtable);
    740     if (ACPI_FAILURE (Status))
    741     {
    742         return (Status);
    743     }
    744 
    745     ParentTable = DtPeekSubtable ();
    746     DtInsertSubtable (ParentTable, Subtable);
    747     DtPushSubtable (Subtable);
    748 
    749     /* Subtables */
    750 
    751     while (*PFieldList)
    752     {
    753         SubtableStart = *PFieldList;
    754         Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
    755             &Subtable);
    756         if (ACPI_FAILURE (Status))
    757         {
    758             return (Status);
    759         }
    760 
    761         ParentTable = DtPeekSubtable ();
    762         DtInsertSubtable (ParentTable, Subtable);
    763         DtPushSubtable (Subtable);
    764 
    765         NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
    766 
    767         switch (NfitHeader->Type)
    768         {
    769         case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
    770 
    771             InfoTable = AcpiDmTableInfoNfit0;
    772             break;
    773 
    774         case ACPI_NFIT_TYPE_MEMORY_MAP:
    775 
    776             InfoTable = AcpiDmTableInfoNfit1;
    777             break;
    778 
    779         case ACPI_NFIT_TYPE_INTERLEAVE:
    780 
    781             Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
    782             InfoTable = AcpiDmTableInfoNfit2;
    783             break;
    784 
    785         case ACPI_NFIT_TYPE_SMBIOS:
    786 
    787             InfoTable = AcpiDmTableInfoNfit3;
    788             break;
    789 
    790         case ACPI_NFIT_TYPE_CONTROL_REGION:
    791 
    792             InfoTable = AcpiDmTableInfoNfit4;
    793             break;
    794 
    795         case ACPI_NFIT_TYPE_DATA_REGION:
    796 
    797             InfoTable = AcpiDmTableInfoNfit5;
    798             break;
    799 
    800         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
    801 
    802             Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
    803             InfoTable = AcpiDmTableInfoNfit6;
    804             break;
    805 
    806         case ACPI_NFIT_TYPE_CAPABILITIES:
    807 
    808             InfoTable = AcpiDmTableInfoNfit7;
    809             break;
    810 
    811         default:
    812 
    813             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
    814             return (AE_ERROR);
    815         }
    816 
    817         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    818         if (ACPI_FAILURE (Status))
    819         {
    820             return (Status);
    821         }
    822 
    823         ParentTable = DtPeekSubtable ();
    824         DtInsertSubtable (ParentTable, Subtable);
    825         DtPopSubtable ();
    826 
    827         switch (NfitHeader->Type)
    828         {
    829         case ACPI_NFIT_TYPE_INTERLEAVE:
    830 
    831             Count = 0;
    832             DtPushSubtable (Subtable);
    833             while (*PFieldList)
    834             {
    835                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
    836                     &Subtable);
    837                 if (ACPI_FAILURE (Status))
    838                 {
    839                     return (Status);
    840                 }
    841 
    842                 if (!Subtable)
    843                 {
    844                     DtPopSubtable ();
    845                     break;
    846                 }
    847 
    848                 ParentTable = DtPeekSubtable ();
    849                 DtInsertSubtable (ParentTable, Subtable);
    850                 Count++;
    851             }
    852 
    853             Interleave->LineCount = Count;
    854             break;
    855 
    856         case ACPI_NFIT_TYPE_SMBIOS:
    857 
    858             if (*PFieldList)
    859             {
    860                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
    861                     &Subtable);
    862                 if (ACPI_FAILURE (Status))
    863                 {
    864                     return (Status);
    865                 }
    866 
    867                 if (Subtable)
    868                 {
    869                     DtInsertSubtable (ParentTable, Subtable);
    870                 }
    871             }
    872             break;
    873 
    874         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
    875 
    876             Count = 0;
    877             DtPushSubtable (Subtable);
    878             while (*PFieldList)
    879             {
    880                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
    881                     &Subtable);
    882                 if (ACPI_FAILURE (Status))
    883                 {
    884                     return (Status);
    885                 }
    886 
    887                 if (!Subtable)
    888                 {
    889                     DtPopSubtable ();
    890                     break;
    891                 }
    892 
    893                 ParentTable = DtPeekSubtable ();
    894                 DtInsertSubtable (ParentTable, Subtable);
    895                 Count++;
    896             }
    897 
    898             Hint->HintCount = (UINT16) Count;
    899             break;
    900 
    901         default:
    902             break;
    903         }
    904     }
    905 
    906     return (AE_OK);
    907 }
    908 
    909 
    910 /******************************************************************************
    911  *
    912  * FUNCTION:    DtCompilePcct
    913  *
    914  * PARAMETERS:  List                - Current field list pointer
    915  *
    916  * RETURN:      Status
    917  *
    918  * DESCRIPTION: Compile PCCT.
    919  *
    920  *****************************************************************************/
    921 
    922 ACPI_STATUS
    923 DtCompilePcct (
    924     void                    **List)
    925 {
    926     ACPI_STATUS             Status;
    927     DT_SUBTABLE             *Subtable;
    928     DT_SUBTABLE             *ParentTable;
    929     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    930     DT_FIELD                *SubtableStart;
    931     ACPI_SUBTABLE_HEADER    *PcctHeader;
    932     ACPI_DMTABLE_INFO       *InfoTable;
    933 
    934 
    935     /* Main table */
    936 
    937     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
    938         &Subtable);
    939     if (ACPI_FAILURE (Status))
    940     {
    941         return (Status);
    942     }
    943 
    944     ParentTable = DtPeekSubtable ();
    945     DtInsertSubtable (ParentTable, Subtable);
    946 
    947     /* Subtables */
    948 
    949     while (*PFieldList)
    950     {
    951         SubtableStart = *PFieldList;
    952         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
    953             &Subtable);
    954         if (ACPI_FAILURE (Status))
    955         {
    956             return (Status);
    957         }
    958 
    959         ParentTable = DtPeekSubtable ();
    960         DtInsertSubtable (ParentTable, Subtable);
    961         DtPushSubtable (Subtable);
    962 
    963         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
    964 
    965         switch (PcctHeader->Type)
    966         {
    967         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
    968 
    969             InfoTable = AcpiDmTableInfoPcct0;
    970             break;
    971 
    972         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
    973 
    974             InfoTable = AcpiDmTableInfoPcct1;
    975             break;
    976 
    977         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
    978 
    979             InfoTable = AcpiDmTableInfoPcct2;
    980             break;
    981 
    982         case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
    983 
    984             InfoTable = AcpiDmTableInfoPcct3;
    985             break;
    986 
    987         case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
    988 
    989             InfoTable = AcpiDmTableInfoPcct4;
    990             break;
    991 
    992         case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE:
    993 
    994             InfoTable = AcpiDmTableInfoPcct5;
    995             break;
    996 
    997         default:
    998 
    999             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
   1000             return (AE_ERROR);
   1001         }
   1002 
   1003         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1004         if (ACPI_FAILURE (Status))
   1005         {
   1006             return (Status);
   1007         }
   1008 
   1009         ParentTable = DtPeekSubtable ();
   1010         DtInsertSubtable (ParentTable, Subtable);
   1011         DtPopSubtable ();
   1012     }
   1013 
   1014     return (AE_OK);
   1015 }
   1016 
   1017 
   1018 /******************************************************************************
   1019  *
   1020  * FUNCTION:    DtCompilePdtt
   1021  *
   1022  * PARAMETERS:  List                - Current field list pointer
   1023  *
   1024  * RETURN:      Status
   1025  *
   1026  * DESCRIPTION: Compile PDTT.
   1027  *
   1028  *****************************************************************************/
   1029 
   1030 ACPI_STATUS
   1031 DtCompilePdtt (
   1032     void                    **List)
   1033 {
   1034     ACPI_STATUS             Status;
   1035     DT_SUBTABLE             *Subtable;
   1036     DT_SUBTABLE             *ParentTable;
   1037     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1038     ACPI_TABLE_PDTT         *PdttHeader;
   1039     UINT32                  Count = 0;
   1040 
   1041 
   1042     /* Main table */
   1043 
   1044     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable);
   1045     if (ACPI_FAILURE (Status))
   1046     {
   1047         return (Status);
   1048     }
   1049 
   1050     ParentTable = DtPeekSubtable ();
   1051     DtInsertSubtable (ParentTable, Subtable);
   1052 
   1053     PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer);
   1054     PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT);
   1055 
   1056     /* There is only one type of subtable at this time, no need to decode */
   1057 
   1058     while (*PFieldList)
   1059     {
   1060         /* List of subchannel IDs, each 2 bytes */
   1061 
   1062         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0,
   1063             &Subtable);
   1064         if (ACPI_FAILURE (Status))
   1065         {
   1066             return (Status);
   1067         }
   1068 
   1069         DtInsertSubtable (ParentTable, Subtable);
   1070         Count++;
   1071     }
   1072 
   1073     PdttHeader->TriggerCount = (UINT8) Count;
   1074     return (AE_OK);
   1075 }
   1076 
   1077 
   1078 /******************************************************************************
   1079  *
   1080  * FUNCTION:    DtCompilePhat
   1081  *
   1082  * PARAMETERS:  List                - Current field list pointer
   1083  *
   1084  * RETURN:      Status
   1085  *
   1086  * DESCRIPTION: Compile Phat.
   1087  *
   1088  *****************************************************************************/
   1089 
   1090 ACPI_STATUS
   1091 DtCompilePhat (
   1092     void                    **List)
   1093 {
   1094     ACPI_STATUS             Status = AE_OK;
   1095     DT_SUBTABLE             *Subtable;
   1096     DT_SUBTABLE             *ParentTable;
   1097     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1098     ACPI_PHAT_HEADER        *PhatHeader;
   1099     ACPI_DMTABLE_INFO       *Info;
   1100     ACPI_PHAT_VERSION_DATA  *VersionData;
   1101     UINT32                  DeviceDataLength;
   1102     UINT32                  RecordCount;
   1103     DT_FIELD                *DataOffsetField;
   1104     DT_FIELD                *DevicePathField;
   1105     UINT32                  TableOffset = 0;
   1106     UINT32                  DataOffsetValue;
   1107     UINT32                  i;
   1108 
   1109 
   1110     /* The table consists of subtables */
   1111 
   1112     while (*PFieldList)
   1113     {
   1114         /* Compile the common subtable header */
   1115 
   1116         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable);
   1117         if (ACPI_FAILURE (Status))
   1118         {
   1119             return (Status);
   1120         }
   1121 
   1122         TableOffset += Subtable->Length;
   1123         DbgPrint (ASL_DEBUG_OUTPUT, "0 Subtable->Length: %X\n", Subtable->Length);
   1124 
   1125         ParentTable = DtPeekSubtable ();
   1126         DtInsertSubtable (ParentTable, Subtable);
   1127         DtPushSubtable (Subtable);
   1128 
   1129         PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer);
   1130 
   1131         switch (PhatHeader->Type)
   1132         {
   1133         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
   1134 
   1135             /* Compile the middle portion of the Firmware Version Data */
   1136 
   1137             Info = AcpiDmTableInfoPhat0;
   1138             PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA);
   1139             DataOffsetField = NULL;
   1140             break;
   1141 
   1142         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
   1143 
   1144             DbgPrint (ASL_DEBUG_OUTPUT, "1 Offset: %X, Name: \"%s\" Length: %X\n",
   1145                 (*PFieldList)->TableOffset, (*PFieldList)->Name, Subtable->Length);
   1146 
   1147             DataOffsetField = *PFieldList;
   1148 
   1149             /* Walk the field list to get to the "Device-specific data Offset" field */
   1150 
   1151             TableOffset = sizeof (ACPI_PHAT_HEALTH_DATA);
   1152             for (i = 0; i < 3; i++)
   1153             {
   1154                 DataOffsetField = DataOffsetField->Next;
   1155                 DbgPrint (ASL_DEBUG_OUTPUT, "2 Offset: %X, Name: \"%s\" Length: %X Value: %s:\n",
   1156                     TableOffset, DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value);
   1157             }
   1158 
   1159             /* Convert DataOffsetField->Value (a char * string) to an integer value */
   1160 
   1161             sscanf (DataOffsetField->Value, "%X", &DataOffsetValue);
   1162 
   1163             /*
   1164              * Get the next field (Device Path):
   1165              * DataOffsetField points to "Device-Specific Offset", next field is
   1166              * "Device Path".
   1167              */
   1168             DevicePathField = DataOffsetField->Next;
   1169 
   1170             /* Compute the size of the input ASCII string as a unicode string (*2 + 2) */
   1171 
   1172             DevicePathField->StringLength = (strlen ((const char *) DevicePathField->Value) * 2) + 2;
   1173             TableOffset += DevicePathField->StringLength;
   1174 
   1175             DbgPrint (ASL_DEBUG_OUTPUT, "3 Offset: %X, Length: %X devicepathLength: %X\n",
   1176                 TableOffset, Subtable->Length, DevicePathField->StringLength);
   1177 
   1178             /* Set the DataOffsetField to the current TableOffset */
   1179             /* Must set the DataOffsetField here (not later) */
   1180 
   1181             if (DataOffsetValue != 0)
   1182             {
   1183                 snprintf (DataOffsetField->Value, Subtable->Length, "%X", TableOffset);
   1184             }
   1185 
   1186             DbgPrint (ASL_DEBUG_OUTPUT, "4 Offset: %X, Length: %X\n", TableOffset, Subtable->Length);
   1187 
   1188             DbgPrint (ASL_DEBUG_OUTPUT, "5 TableOffset: %X, DataOffsetField->StringLength: "
   1189                 "%X DevicePathField Length: %X DevicePathField->Value: %s, DataOffsetField->Value: %s DataOffsetField->ByteOffset %X\n",
   1190                 TableOffset, DataOffsetField->StringLength, DevicePathField->StringLength,
   1191                 DevicePathField->Value, DataOffsetField->Value, DataOffsetField->ByteOffset);
   1192 
   1193             /* Compile the middle portion of the Health Data Record */
   1194 
   1195             Info = AcpiDmTableInfoPhat1;
   1196             PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA);
   1197             break;
   1198 
   1199         default:
   1200 
   1201             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
   1202             return (AE_ERROR);
   1203         }
   1204 
   1205         /* Compile either the Version Data or the Health Data */
   1206 
   1207         Status = DtCompileTable (PFieldList, Info, &Subtable);
   1208         if (ACPI_FAILURE (Status))
   1209         {
   1210             return (Status);
   1211         }
   1212 
   1213         DbgPrint (ASL_DEBUG_OUTPUT, "6 Offset: %X, Name: \"%s\" SubtableLength: %X\n",
   1214             TableOffset /* - StartTableOffset*/, (*PFieldList)->Name, Subtable->Length);
   1215 
   1216         ParentTable = DtPeekSubtable ();
   1217         DtInsertSubtable (ParentTable, Subtable);
   1218 
   1219         switch (PhatHeader->Type)
   1220         {
   1221         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
   1222 
   1223             VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA,
   1224                 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER)));
   1225             RecordCount = VersionData->ElementCount;
   1226 
   1227             /* Compile all of the Version Elements */
   1228 
   1229             while (RecordCount)
   1230             {
   1231                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a,
   1232                     &Subtable);
   1233                 if (ACPI_FAILURE (Status))
   1234                 {
   1235                     return (Status);
   1236                 }
   1237 
   1238                 ParentTable = DtPeekSubtable ();
   1239                 DtInsertSubtable (ParentTable, Subtable);
   1240 
   1241                 TableOffset += Subtable->Length;
   1242                 RecordCount--;
   1243                 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT);
   1244             }
   1245 
   1246             DtPopSubtable ();
   1247             break;
   1248 
   1249         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
   1250 
   1251             /* Compile the Device Path */
   1252 
   1253             DeviceDataLength = Subtable->Length;
   1254             TableOffset += Subtable->Length;
   1255 
   1256             DbgPrint (ASL_DEBUG_OUTPUT, "7 Device Path Length: %X FieldName: \"%s\" FieldLength: "
   1257                 "%s FieldValue: %s SubtableLength: %X TableOffset: %X\n", DeviceDataLength,
   1258                 (*PFieldList)->Name, DataOffsetField->Value, (*PFieldList)->Value,
   1259                 Subtable->Length, TableOffset);
   1260 
   1261             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable);
   1262             if (ACPI_FAILURE (Status))
   1263             {
   1264                 return (Status);
   1265             }
   1266             ParentTable = DtPeekSubtable ();
   1267             DtInsertSubtable (ParentTable, Subtable);
   1268 
   1269             /* *PFieldList will be null if previous field was at the end-of-ParseTree (EOF) */
   1270 
   1271             if (!*PFieldList)
   1272             {
   1273                 DbgPrint (ASL_DEBUG_OUTPUT, "8 Exit on end-of-ParseTree\n");
   1274                 return (AE_OK);
   1275             }
   1276 
   1277             DbgPrint (ASL_DEBUG_OUTPUT, "9 Device Data Length: %X FieldName: \"%s"
   1278                 " TableOffset: %X FieldLength: %X Field Value: %s SubtableLength: %X\n",
   1279                 DeviceDataLength, (*PFieldList)->Name, TableOffset,
   1280                 (*PFieldList)->StringLength, (*PFieldList)->Value, Subtable->Length);
   1281 
   1282             PhatHeader->Length += (UINT16) Subtable->Length;
   1283 
   1284             /* Convert DataOffsetField->Value (a hex char * string) to an integer value */
   1285 
   1286             sscanf (DataOffsetField->Value, "%X", &DataOffsetValue);
   1287 
   1288             DbgPrint (ASL_DEBUG_OUTPUT, "10 Device-Specific Offset: %X Table Offset: %X\n",
   1289                 DataOffsetValue, TableOffset);
   1290             if (DataOffsetValue != 0)
   1291             {
   1292                 /* Compile Device-Specific Data - only if the Data Offset is non-zero */
   1293 
   1294                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable);
   1295                 if (ACPI_FAILURE (Status))
   1296                 {
   1297                     return (Status);
   1298                 }
   1299 
   1300                 DbgPrint (ASL_DEBUG_OUTPUT, "11 Subtable: %p Table Offset: %X\n",
   1301                     Subtable, TableOffset);
   1302                 if (Subtable)
   1303                 {
   1304                     DbgPrint (ASL_DEBUG_OUTPUT, "12 Device Specific Offset: "
   1305                         "%X FieldName \"%s\" SubtableLength %X\n",
   1306                         DeviceDataLength, DataOffsetField->Name, Subtable->Length);
   1307 
   1308                     DeviceDataLength += Subtable->Length;
   1309 
   1310                     ParentTable = DtPeekSubtable ();
   1311                     DtInsertSubtable (ParentTable, Subtable);
   1312 
   1313                     PhatHeader->Length += (UINT16) Subtable->Length;
   1314                 }
   1315             }
   1316 
   1317             DtPopSubtable ();
   1318 
   1319             DbgPrint (ASL_DEBUG_OUTPUT, "13 FieldName: \"%s\" FieldLength: %X Field Value: %s\n",
   1320                 DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value);
   1321             break;
   1322 
   1323         default:
   1324 
   1325             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
   1326             return (AE_ERROR);
   1327         }
   1328     }
   1329 
   1330     return (Status);
   1331 }
   1332 
   1333 
   1334 /******************************************************************************
   1335  *
   1336  * FUNCTION:    DtCompilePmtt
   1337  *
   1338  * PARAMETERS:  List                - Current field list pointer
   1339  *
   1340  * RETURN:      Status
   1341  *
   1342  * DESCRIPTION: Compile PMTT.
   1343  *
   1344  *****************************************************************************/
   1345 
   1346 ACPI_STATUS
   1347 DtCompilePmtt (
   1348     void                    **List)
   1349 {
   1350     ACPI_STATUS             Status;
   1351     DT_SUBTABLE             *Subtable;
   1352     DT_SUBTABLE             *ParentTable;
   1353     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1354     DT_FIELD                *SubtableStart;
   1355     UINT16                  Type;
   1356 
   1357 
   1358     /* Main table */
   1359 
   1360     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable);
   1361     if (ACPI_FAILURE (Status))
   1362     {
   1363         return (Status);
   1364     }
   1365 
   1366     ParentTable = DtPeekSubtable ();
   1367     DtInsertSubtable (ParentTable, Subtable);
   1368     DtPushSubtable (Subtable);
   1369 
   1370     /* Subtables */
   1371 
   1372     while (*PFieldList)
   1373     {
   1374         SubtableStart = *PFieldList;
   1375         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
   1376 
   1377         switch (Type)
   1378         {
   1379         case ACPI_PMTT_TYPE_SOCKET:
   1380 
   1381             /* Subtable: Socket Structure */
   1382 
   1383             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n");
   1384 
   1385             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
   1386                 &Subtable);
   1387             if (ACPI_FAILURE (Status))
   1388             {
   1389                 return (Status);
   1390             }
   1391 
   1392             break;
   1393 
   1394         case ACPI_PMTT_TYPE_CONTROLLER:
   1395 
   1396             /* Subtable: Memory Controller Structure */
   1397 
   1398             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n");
   1399 
   1400             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
   1401                 &Subtable);
   1402             if (ACPI_FAILURE (Status))
   1403             {
   1404                 return (Status);
   1405             }
   1406 
   1407             break;
   1408 
   1409         case ACPI_PMTT_TYPE_DIMM:
   1410 
   1411             /* Subtable: Physical Component (DIMM) Structure */
   1412 
   1413             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n");
   1414             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
   1415                 &Subtable);
   1416             if (ACPI_FAILURE (Status))
   1417             {
   1418                 return (Status);
   1419             }
   1420 
   1421             break;
   1422 
   1423         case ACPI_PMTT_TYPE_VENDOR:
   1424 
   1425             /* Subtable: Vendor-specific Structure */
   1426 
   1427             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n");
   1428             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor,
   1429                 &Subtable);
   1430             if (ACPI_FAILURE (Status))
   1431             {
   1432                 return (Status);
   1433             }
   1434 
   1435             break;
   1436 
   1437         default:
   1438 
   1439             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
   1440             return (AE_ERROR);
   1441         }
   1442 
   1443         DtInsertSubtable (ParentTable, Subtable);
   1444     }
   1445 
   1446     return (Status);
   1447 }
   1448 
   1449 
   1450 /******************************************************************************
   1451  *
   1452  * FUNCTION:    DtCompilePptt
   1453  *
   1454  * PARAMETERS:  List                - Current field list pointer
   1455  *
   1456  * RETURN:      Status
   1457  *
   1458  * DESCRIPTION: Compile PPTT.
   1459  *
   1460  *****************************************************************************/
   1461 
   1462 ACPI_STATUS
   1463 DtCompilePptt (
   1464     void                    **List)
   1465 {
   1466     ACPI_STATUS             Status;
   1467     ACPI_SUBTABLE_HEADER    *PpttHeader;
   1468     ACPI_PPTT_PROCESSOR     *PpttProcessor = NULL;
   1469     DT_SUBTABLE             *Subtable;
   1470     DT_SUBTABLE             *ParentTable;
   1471     ACPI_DMTABLE_INFO       *InfoTable;
   1472     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1473     DT_FIELD                *SubtableStart;
   1474     ACPI_TABLE_HEADER       *PpttAcpiHeader;
   1475 
   1476 
   1477     ParentTable = DtPeekSubtable ();
   1478     while (*PFieldList)
   1479     {
   1480         SubtableStart = *PFieldList;
   1481 
   1482         /* Compile PPTT subtable header */
   1483 
   1484         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr,
   1485             &Subtable);
   1486         if (ACPI_FAILURE (Status))
   1487         {
   1488             return (Status);
   1489         }
   1490         DtInsertSubtable (ParentTable, Subtable);
   1491         PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
   1492         PpttHeader->Length = (UINT8)(Subtable->Length);
   1493 
   1494         switch (PpttHeader->Type)
   1495         {
   1496         case ACPI_PPTT_TYPE_PROCESSOR:
   1497 
   1498             InfoTable = AcpiDmTableInfoPptt0;
   1499             break;
   1500 
   1501         case ACPI_PPTT_TYPE_CACHE:
   1502 
   1503             InfoTable = AcpiDmTableInfoPptt1;
   1504             break;
   1505 
   1506         case ACPI_PPTT_TYPE_ID:
   1507 
   1508             InfoTable = AcpiDmTableInfoPptt2;
   1509             break;
   1510 
   1511         default:
   1512 
   1513             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT");
   1514             return (AE_ERROR);
   1515         }
   1516 
   1517         /* Compile PPTT subtable body */
   1518 
   1519         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1520         if (ACPI_FAILURE (Status))
   1521         {
   1522             return (Status);
   1523         }
   1524         DtInsertSubtable (ParentTable, Subtable);
   1525         PpttHeader->Length += (UINT8)(Subtable->Length);
   1526 
   1527         /* Compile PPTT subtable additional */
   1528 
   1529         switch (PpttHeader->Type)
   1530         {
   1531         case ACPI_PPTT_TYPE_PROCESSOR:
   1532 
   1533             PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR,
   1534                 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER));
   1535             if (PpttProcessor)
   1536             {
   1537                 /* Compile initiator proximity domain list */
   1538 
   1539                 PpttProcessor->NumberOfPrivResources = 0;
   1540                 while (*PFieldList)
   1541                 {
   1542                     Status = DtCompileTable (PFieldList,
   1543                         AcpiDmTableInfoPptt0a, &Subtable);
   1544                     if (ACPI_FAILURE (Status))
   1545                     {
   1546                         return (Status);
   1547                     }
   1548                     if (!Subtable)
   1549                     {
   1550                         break;
   1551                     }
   1552 
   1553                     DtInsertSubtable (ParentTable, Subtable);
   1554                     PpttHeader->Length += (UINT8)(Subtable->Length);
   1555                     PpttProcessor->NumberOfPrivResources++;
   1556                 }
   1557             }
   1558             break;
   1559 
   1560         case ACPI_PPTT_TYPE_CACHE:
   1561 
   1562             PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
   1563                 AslGbl_RootTable->Buffer);
   1564             if (PpttAcpiHeader->Revision < 3)
   1565             {
   1566                 break;
   1567             }
   1568             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a,
   1569                 &Subtable);
   1570             DtInsertSubtable (ParentTable, Subtable);
   1571             PpttHeader->Length += (UINT8)(Subtable->Length);
   1572             break;
   1573 
   1574         default:
   1575 
   1576             break;
   1577         }
   1578     }
   1579 
   1580     return (AE_OK);
   1581 }
   1582 
   1583 
   1584 /******************************************************************************
   1585  *
   1586  * FUNCTION:    DtCompilePrmt
   1587  *
   1588  * PARAMETERS:  List                - Current field list pointer
   1589  *
   1590  * RETURN:      Status
   1591  *
   1592  * DESCRIPTION: Compile PRMT.
   1593  *
   1594  *****************************************************************************/
   1595 
   1596 ACPI_STATUS
   1597 DtCompilePrmt (
   1598     void                    **List)
   1599 {
   1600     ACPI_STATUS             Status;
   1601     ACPI_TABLE_PRMT_HEADER  *PrmtHeader;
   1602     ACPI_PRMT_MODULE_INFO   *PrmtModuleInfo;
   1603     DT_SUBTABLE             *Subtable;
   1604     DT_SUBTABLE             *ParentTable;
   1605     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1606     UINT32                  i, j;
   1607 
   1608     ParentTable = DtPeekSubtable ();
   1609 
   1610     /* Compile PRMT subtable header */
   1611 
   1612     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr,
   1613         &Subtable);
   1614     if (ACPI_FAILURE (Status))
   1615     {
   1616         return (Status);
   1617     }
   1618     DtInsertSubtable (ParentTable, Subtable);
   1619     PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer);
   1620 
   1621     for (i = 0; i < PrmtHeader->ModuleInfoCount; i++)
   1622     {
   1623         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule,
   1624             &Subtable);
   1625         if (ACPI_FAILURE (Status))
   1626         {
   1627             return (Status);
   1628         }
   1629         DtInsertSubtable (ParentTable, Subtable);
   1630         PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer);
   1631 
   1632         for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++)
   1633         {
   1634             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler,
   1635                 &Subtable);
   1636             if (ACPI_FAILURE (Status))
   1637             {
   1638                 return (Status);
   1639             }
   1640             DtInsertSubtable (ParentTable, Subtable);
   1641         }
   1642     }
   1643 
   1644     return (AE_OK);
   1645 }
   1646 
   1647 
   1648 /******************************************************************************
   1649  *
   1650  * FUNCTION:    DtCompileRas2
   1651  *
   1652  * PARAMETERS:  List                - Current field list pointer
   1653  *
   1654  * RETURN:      Status
   1655  *
   1656  * DESCRIPTION: Compile RAS2.
   1657  *
   1658  *****************************************************************************/
   1659 
   1660 ACPI_STATUS
   1661 DtCompileRas2 (
   1662     void                    **List)
   1663 {
   1664     ACPI_STATUS             Status;
   1665     DT_SUBTABLE             *Subtable;
   1666     DT_SUBTABLE             *ParentTable;
   1667     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1668     ACPI_TABLE_RAS2         *Ras2Header;
   1669     UINT32                  Count = 0;
   1670 
   1671 
   1672     /* Main table */
   1673 
   1674     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2, &Subtable);
   1675     if (ACPI_FAILURE (Status))
   1676     {
   1677         return (Status);
   1678     }
   1679 
   1680     ParentTable = DtPeekSubtable ();
   1681     DtInsertSubtable (ParentTable, Subtable);
   1682 
   1683     Ras2Header = ACPI_CAST_PTR (ACPI_TABLE_RAS2, ParentTable->Buffer);
   1684 
   1685     /* There is only one type of subtable at this time, no need to decode */
   1686 
   1687     while (*PFieldList)
   1688     {
   1689         /* List of RAS2 PCC descriptors, each 8 bytes */
   1690 
   1691         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2PccDesc,
   1692             &Subtable);
   1693         if (ACPI_FAILURE (Status))
   1694         {
   1695             return (Status);
   1696         }
   1697 
   1698         DtInsertSubtable (ParentTable, Subtable);
   1699         Count++;
   1700     }
   1701 
   1702     Ras2Header->NumPccDescs = (UINT8) Count;
   1703     return (AE_OK);
   1704 }
   1705 
   1706 
   1707 /******************************************************************************
   1708  *
   1709  * FUNCTION:    DtCompileRgrt
   1710  *
   1711  * PARAMETERS:  List                - Current field list pointer
   1712  *
   1713  * RETURN:      Status
   1714  *
   1715  * DESCRIPTION: Compile RGRT.
   1716  *
   1717  *****************************************************************************/
   1718 
   1719 ACPI_STATUS
   1720 DtCompileRgrt (
   1721     void                    **List)
   1722 {
   1723     ACPI_STATUS             Status;
   1724     DT_SUBTABLE             *Subtable;
   1725     DT_SUBTABLE             *ParentTable;
   1726     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1727 
   1728 
   1729     /* Compile the main table */
   1730 
   1731     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt,
   1732         &Subtable);
   1733     if (ACPI_FAILURE (Status))
   1734     {
   1735         return (Status);
   1736     }
   1737 
   1738     ParentTable = DtPeekSubtable ();
   1739     DtInsertSubtable (ParentTable, Subtable);
   1740 
   1741     /* Compile the "Subtable" -- actually just the binary (PNG) image */
   1742 
   1743     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0,
   1744         &Subtable);
   1745     if (ACPI_FAILURE (Status))
   1746     {
   1747         return (Status);
   1748     }
   1749 
   1750     DtInsertSubtable (ParentTable, Subtable);
   1751     return (AE_OK);
   1752 }
   1753 
   1754 
   1755 /******************************************************************************
   1756  *
   1757  * FUNCTION:    DtCompileRhct
   1758  *
   1759  * PARAMETERS:  List                - Current field list pointer
   1760  *
   1761  * RETURN:      Status
   1762  *
   1763  * DESCRIPTION: Compile RHCT.
   1764  *
   1765  *****************************************************************************/
   1766 
   1767 ACPI_STATUS
   1768 DtCompileRhct (
   1769     void                    **List)
   1770 {
   1771     ACPI_STATUS             Status;
   1772     ACPI_RHCT_NODE_HEADER   *RhctHeader;
   1773     ACPI_RHCT_HART_INFO     *RhctHartInfo = NULL;
   1774     DT_SUBTABLE             *Subtable;
   1775     DT_SUBTABLE             *ParentTable;
   1776     ACPI_DMTABLE_INFO       *InfoTable;
   1777     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1778     DT_FIELD                *SubtableStart;
   1779 
   1780 
   1781     /* Compile the main table */
   1782 
   1783     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhct,
   1784         &Subtable);
   1785     if (ACPI_FAILURE (Status))
   1786     {
   1787         return (Status);
   1788     }
   1789 
   1790     ParentTable = DtPeekSubtable ();
   1791     while (*PFieldList)
   1792     {
   1793         SubtableStart = *PFieldList;
   1794 
   1795         /* Compile RHCT subtable header */
   1796 
   1797         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctNodeHdr,
   1798             &Subtable);
   1799         if (ACPI_FAILURE (Status))
   1800         {
   1801             return (Status);
   1802         }
   1803         DtInsertSubtable (ParentTable, Subtable);
   1804         RhctHeader = ACPI_CAST_PTR (ACPI_RHCT_NODE_HEADER, Subtable->Buffer);
   1805         RhctHeader->Length = (UINT16)(Subtable->Length);
   1806 
   1807         switch (RhctHeader->Type)
   1808         {
   1809         case ACPI_RHCT_NODE_TYPE_ISA_STRING:
   1810 
   1811             InfoTable = AcpiDmTableInfoRhctIsa1;
   1812             break;
   1813 
   1814         case ACPI_RHCT_NODE_TYPE_HART_INFO:
   1815 
   1816             InfoTable = AcpiDmTableInfoRhctHartInfo1;
   1817             break;
   1818 
   1819         case ACPI_RHCT_NODE_TYPE_CMO:
   1820 
   1821             InfoTable = AcpiDmTableInfoRhctCmo1;
   1822             break;
   1823 
   1824         case ACPI_RHCT_NODE_TYPE_MMU:
   1825 
   1826             InfoTable = AcpiDmTableInfoRhctMmu1;
   1827             break;
   1828 
   1829         default:
   1830 
   1831             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RHCT");
   1832             return (AE_ERROR);
   1833         }
   1834 
   1835         /* Compile RHCT subtable body */
   1836 
   1837         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1838         if (ACPI_FAILURE (Status))
   1839         {
   1840             return (Status);
   1841         }
   1842         DtInsertSubtable (ParentTable, Subtable);
   1843         RhctHeader->Length += (UINT16)(Subtable->Length);
   1844 
   1845         /* Compile RHCT subtable additionals */
   1846 
   1847         switch (RhctHeader->Type)
   1848         {
   1849         case ACPI_RHCT_NODE_TYPE_HART_INFO:
   1850 
   1851             RhctHartInfo = ACPI_SUB_PTR (ACPI_RHCT_HART_INFO,
   1852                 Subtable->Buffer, sizeof (ACPI_RHCT_NODE_HEADER));
   1853             if (RhctHartInfo)
   1854             {
   1855 
   1856                 RhctHartInfo->NumOffsets = 0;
   1857                 while (*PFieldList)
   1858                 {
   1859                     Status = DtCompileTable (PFieldList,
   1860                         AcpiDmTableInfoRhctHartInfo2, &Subtable);
   1861                     if (ACPI_FAILURE (Status))
   1862                     {
   1863                         return (Status);
   1864                     }
   1865                     if (!Subtable)
   1866                     {
   1867                         break;
   1868                     }
   1869 
   1870                     DtInsertSubtable (ParentTable, Subtable);
   1871                     RhctHeader->Length += (UINT16)(Subtable->Length);
   1872                     RhctHartInfo->NumOffsets++;
   1873                 }
   1874             }
   1875             break;
   1876 
   1877         default:
   1878 
   1879             break;
   1880         }
   1881     }
   1882 
   1883     return (AE_OK);
   1884 }
   1885 
   1886 
   1887 /******************************************************************************
   1888  *
   1889  * FUNCTION:    DtCompileRsdt
   1890  *
   1891  * PARAMETERS:  List                - Current field list pointer
   1892  *
   1893  * RETURN:      Status
   1894  *
   1895  * DESCRIPTION: Compile RSDT.
   1896  *
   1897  *****************************************************************************/
   1898 
   1899 ACPI_STATUS
   1900 DtCompileRsdt (
   1901     void                    **List)
   1902 {
   1903     DT_SUBTABLE             *Subtable;
   1904     DT_SUBTABLE             *ParentTable;
   1905     DT_FIELD                *FieldList = *(DT_FIELD **) List;
   1906     UINT32                  Address;
   1907 
   1908 
   1909     ParentTable = DtPeekSubtable ();
   1910 
   1911     while (FieldList)
   1912     {
   1913         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
   1914 
   1915         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
   1916         DtInsertSubtable (ParentTable, Subtable);
   1917         FieldList = FieldList->Next;
   1918     }
   1919 
   1920     return (AE_OK);
   1921 }
   1922 
   1923 
   1924 /******************************************************************************
   1925  *
   1926  * FUNCTION:    DtCompileS3pt
   1927  *
   1928  * PARAMETERS:  PFieldList          - Current field list pointer
   1929  *
   1930  * RETURN:      Status
   1931  *
   1932  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
   1933  *
   1934  *****************************************************************************/
   1935 
   1936 ACPI_STATUS
   1937 DtCompileS3pt (
   1938     DT_FIELD                **PFieldList)
   1939 {
   1940     ACPI_STATUS             Status;
   1941     ACPI_FPDT_HEADER        *S3ptHeader;
   1942     DT_SUBTABLE             *Subtable;
   1943     DT_SUBTABLE             *ParentTable;
   1944     ACPI_DMTABLE_INFO       *InfoTable;
   1945     DT_FIELD                *SubtableStart;
   1946 
   1947 
   1948     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
   1949         &AslGbl_RootTable);
   1950     if (ACPI_FAILURE (Status))
   1951     {
   1952         return (Status);
   1953     }
   1954 
   1955     DtPushSubtable (AslGbl_RootTable);
   1956 
   1957     while (*PFieldList)
   1958     {
   1959         SubtableStart = *PFieldList;
   1960         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
   1961             &Subtable);
   1962         if (ACPI_FAILURE (Status))
   1963         {
   1964             return (Status);
   1965         }
   1966 
   1967         ParentTable = DtPeekSubtable ();
   1968         DtInsertSubtable (ParentTable, Subtable);
   1969         DtPushSubtable (Subtable);
   1970 
   1971         S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
   1972 
   1973         switch (S3ptHeader->Type)
   1974         {
   1975         case ACPI_S3PT_TYPE_RESUME:
   1976 
   1977             InfoTable = AcpiDmTableInfoS3pt0;
   1978             break;
   1979 
   1980         case ACPI_S3PT_TYPE_SUSPEND:
   1981 
   1982             InfoTable = AcpiDmTableInfoS3pt1;
   1983             break;
   1984 
   1985         default:
   1986 
   1987             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
   1988             return (AE_ERROR);
   1989         }
   1990 
   1991         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1992         if (ACPI_FAILURE (Status))
   1993         {
   1994             return (Status);
   1995         }
   1996 
   1997         ParentTable = DtPeekSubtable ();
   1998         DtInsertSubtable (ParentTable, Subtable);
   1999         DtPopSubtable ();
   2000     }
   2001 
   2002     return (AE_OK);
   2003 }
   2004 
   2005 
   2006 /******************************************************************************
   2007  *
   2008  * FUNCTION:    DtCompileSdev
   2009  *
   2010  * PARAMETERS:  List                - Current field list pointer
   2011  *
   2012  * RETURN:      Status
   2013  *
   2014  * DESCRIPTION: Compile SDEV.
   2015  *
   2016  *****************************************************************************/
   2017 
   2018 ACPI_STATUS
   2019 DtCompileSdev (
   2020     void                    **List)
   2021 {
   2022     ACPI_STATUS                 Status;
   2023     ACPI_SDEV_HEADER            *SdevHeader;
   2024     ACPI_SDEV_HEADER            *SecureComponentHeader;
   2025     DT_SUBTABLE                 *Subtable;
   2026     DT_SUBTABLE                 *ParentTable;
   2027     ACPI_DMTABLE_INFO           *InfoTable;
   2028     ACPI_DMTABLE_INFO           *SecureComponentInfoTable = NULL;
   2029     DT_FIELD                    **PFieldList = (DT_FIELD **) List;
   2030     DT_FIELD                    *SubtableStart;
   2031     ACPI_SDEV_PCIE              *Pcie = NULL;
   2032     ACPI_SDEV_NAMESPACE         *Namesp = NULL;
   2033     UINT32                      EntryCount;
   2034     ACPI_SDEV_SECURE_COMPONENT  *SecureComponent = NULL;
   2035     UINT16                      ComponentLength = 0;
   2036 
   2037 
   2038     /* Subtables */
   2039 
   2040     while (*PFieldList)
   2041     {
   2042         /* Compile common SDEV subtable header */
   2043 
   2044         SubtableStart = *PFieldList;
   2045         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
   2046             &Subtable);
   2047         if (ACPI_FAILURE (Status))
   2048         {
   2049             return (Status);
   2050         }
   2051 
   2052         ParentTable = DtPeekSubtable ();
   2053         DtInsertSubtable (ParentTable, Subtable);
   2054         DtPushSubtable (Subtable);
   2055 
   2056         SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
   2057         SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
   2058 
   2059         switch (SdevHeader->Type)
   2060         {
   2061         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
   2062 
   2063             InfoTable = AcpiDmTableInfoSdev0;
   2064             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
   2065             SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
   2066                 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE)));
   2067             break;
   2068 
   2069         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
   2070 
   2071             InfoTable = AcpiDmTableInfoSdev1;
   2072             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
   2073             break;
   2074 
   2075         default:
   2076 
   2077             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
   2078             return (AE_ERROR);
   2079         }
   2080 
   2081         /* Compile SDEV subtable body */
   2082 
   2083         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   2084         if (ACPI_FAILURE (Status))
   2085         {
   2086             return (Status);
   2087         }
   2088 
   2089         ParentTable = DtPeekSubtable ();
   2090         DtInsertSubtable (ParentTable, Subtable);
   2091 
   2092         /* Optional data fields are appended to the main subtable body */
   2093 
   2094         switch (SdevHeader->Type)
   2095         {
   2096         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
   2097 
   2098             /*
   2099              * Device Id Offset will be be calculated differently depending on
   2100              * the presence of secure access components.
   2101              */
   2102             Namesp->DeviceIdOffset = 0;
   2103             ComponentLength = 0;
   2104 
   2105             /* If the secure access component exists, get the structures */
   2106 
   2107             if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
   2108             {
   2109                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b,
   2110                     &Subtable);
   2111                 if (ACPI_FAILURE (Status))
   2112                 {
   2113                     return (Status);
   2114                 }
   2115                 ParentTable = DtPeekSubtable ();
   2116                 DtInsertSubtable (ParentTable, Subtable);
   2117 
   2118                 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
   2119 
   2120                 /* Compile a secure access component header */
   2121 
   2122                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr,
   2123                     &Subtable);
   2124                 if (ACPI_FAILURE (Status))
   2125                 {
   2126                     return (Status);
   2127                 }
   2128                 ParentTable = DtPeekSubtable ();
   2129                 DtInsertSubtable (ParentTable, Subtable);
   2130 
   2131                 /* Compile the secure access component */
   2132 
   2133                 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
   2134                 switch (SecureComponentHeader->Type)
   2135                 {
   2136                 case ACPI_SDEV_TYPE_ID_COMPONENT:
   2137 
   2138                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
   2139                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT);
   2140                     ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT);
   2141                     break;
   2142 
   2143                 case ACPI_SDEV_TYPE_MEM_COMPONENT:
   2144 
   2145                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
   2146                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT);
   2147                     ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT);
   2148                     break;
   2149 
   2150                 default:
   2151 
   2152                     /* Any other secure component types are undefined */
   2153 
   2154                     return (AE_ERROR);
   2155                 }
   2156 
   2157                 Status = DtCompileTable (PFieldList, SecureComponentInfoTable,
   2158                     &Subtable);
   2159                 if (ACPI_FAILURE (Status))
   2160                 {
   2161                     return (Status);
   2162                 }
   2163                 ParentTable = DtPeekSubtable ();
   2164                 DtInsertSubtable (ParentTable, Subtable);
   2165 
   2166                 SecureComponent->SecureComponentOffset =
   2167                     sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT);
   2168                 SecureComponent->SecureComponentLength = ComponentLength;
   2169 
   2170 
   2171                 /*
   2172                  * Add the secure component to the subtable to be added for the
   2173                  * the namespace subtable's length
   2174                  */
   2175                 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT);
   2176             }
   2177 
   2178             /* Append DeviceId namespace string */
   2179 
   2180             Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
   2181                 &Subtable);
   2182             if (ACPI_FAILURE (Status))
   2183             {
   2184                 return (Status);
   2185             }
   2186 
   2187             if (!Subtable)
   2188             {
   2189                 break;
   2190             }
   2191 
   2192             ParentTable = DtPeekSubtable ();
   2193             DtInsertSubtable (ParentTable, Subtable);
   2194 
   2195             Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE);
   2196 
   2197             Namesp->DeviceIdLength = (UINT16) Subtable->Length;
   2198 
   2199             /* Append Vendor data */
   2200 
   2201             Namesp->VendorDataLength = 0;
   2202             Namesp->VendorDataOffset = 0;
   2203 
   2204             if (*PFieldList)
   2205             {
   2206                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
   2207                     &Subtable);
   2208                 if (ACPI_FAILURE (Status))
   2209                 {
   2210                     return (Status);
   2211                 }
   2212 
   2213                 if (Subtable)
   2214                 {
   2215                     ParentTable = DtPeekSubtable ();
   2216                     DtInsertSubtable (ParentTable, Subtable);
   2217 
   2218                     Namesp->VendorDataOffset =
   2219                         Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
   2220                     Namesp->VendorDataLength =
   2221                         (UINT16) Subtable->Length;
   2222 
   2223                     /* Final size of entire namespace structure */
   2224 
   2225                     SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) +
   2226                         Subtable->Length + Namesp->DeviceIdLength) + ComponentLength;
   2227                 }
   2228             }
   2229 
   2230             break;
   2231 
   2232         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
   2233 
   2234             /* Append the PCIe path info first */
   2235 
   2236             EntryCount = 0;
   2237             while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
   2238             {
   2239                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
   2240                     &Subtable);
   2241                 if (ACPI_FAILURE (Status))
   2242                 {
   2243                     return (Status);
   2244                 }
   2245 
   2246                 if (!Subtable)
   2247                 {
   2248                     DtPopSubtable ();
   2249                     break;
   2250                 }
   2251 
   2252                 ParentTable = DtPeekSubtable ();
   2253                 DtInsertSubtable (ParentTable, Subtable);
   2254                 EntryCount++;
   2255             }
   2256 
   2257             /* Path offset will point immediately after the main subtable */
   2258 
   2259             Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
   2260             Pcie->PathLength = (UINT16)
   2261                 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
   2262 
   2263             /* Append the Vendor Data last */
   2264 
   2265             Pcie->VendorDataLength = 0;
   2266             Pcie->VendorDataOffset = 0;
   2267 
   2268             if (*PFieldList)
   2269             {
   2270                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
   2271                     &Subtable);
   2272                 if (ACPI_FAILURE (Status))
   2273                 {
   2274                     return (Status);
   2275                 }
   2276 
   2277                 if (Subtable)
   2278                 {
   2279                     ParentTable = DtPeekSubtable ();
   2280                     DtInsertSubtable (ParentTable, Subtable);
   2281 
   2282                     Pcie->VendorDataOffset =
   2283                         Pcie->PathOffset + Pcie->PathLength;
   2284                     Pcie->VendorDataLength = (UINT16)
   2285                         Subtable->Length;
   2286                 }
   2287             }
   2288 
   2289             SdevHeader->Length =
   2290                 sizeof (ACPI_SDEV_PCIE) +
   2291                 Pcie->PathLength + Pcie->VendorDataLength;
   2292             break;
   2293 
   2294         default:
   2295 
   2296             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
   2297             return (AE_ERROR);
   2298         }
   2299 
   2300         DtPopSubtable ();
   2301     }
   2302 
   2303     return (AE_OK);
   2304 }
   2305 
   2306 
   2307 /******************************************************************************
   2308  *
   2309  * FUNCTION:    DtCompileSlic
   2310  *
   2311  * PARAMETERS:  List                - Current field list pointer
   2312  *
   2313  * RETURN:      Status
   2314  *
   2315  * DESCRIPTION: Compile SLIC.
   2316  *
   2317  *****************************************************************************/
   2318 
   2319 ACPI_STATUS
   2320 DtCompileSlic (
   2321     void                    **List)
   2322 {
   2323     ACPI_STATUS             Status;
   2324     DT_SUBTABLE             *Subtable;
   2325     DT_SUBTABLE             *ParentTable;
   2326     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2327 
   2328 
   2329     while (*PFieldList)
   2330     {
   2331         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
   2332             &Subtable);
   2333         if (ACPI_FAILURE (Status))
   2334         {
   2335             return (Status);
   2336         }
   2337 
   2338         ParentTable = DtPeekSubtable ();
   2339         DtInsertSubtable (ParentTable, Subtable);
   2340         DtPushSubtable (Subtable);
   2341         DtPopSubtable ();
   2342     }
   2343 
   2344     return (AE_OK);
   2345 }
   2346 
   2347 
   2348 /******************************************************************************
   2349  *
   2350  * FUNCTION:    DtCompileSlit
   2351  *
   2352  * PARAMETERS:  List                - Current field list pointer
   2353  *
   2354  * RETURN:      Status
   2355  *
   2356  * DESCRIPTION: Compile SLIT.
   2357  *
   2358  *****************************************************************************/
   2359 
   2360 ACPI_STATUS
   2361 DtCompileSlit (
   2362     void                    **List)
   2363 {
   2364     ACPI_STATUS             Status;
   2365     DT_SUBTABLE             *Subtable;
   2366     DT_SUBTABLE             *ParentTable;
   2367     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2368     DT_FIELD                *FieldList;
   2369     DT_FIELD                *EndOfFieldList = NULL;
   2370     UINT32                  Localities;
   2371     UINT32                  LocalityListLength;
   2372     UINT8                   *LocalityBuffer;
   2373 
   2374 
   2375     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
   2376         &Subtable);
   2377     if (ACPI_FAILURE (Status))
   2378     {
   2379         return (Status);
   2380     }
   2381 
   2382     ParentTable = DtPeekSubtable ();
   2383     DtInsertSubtable (ParentTable, Subtable);
   2384 
   2385     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
   2386     LocalityBuffer = UtLocalCalloc (Localities);
   2387     LocalityListLength = 0;
   2388 
   2389     /* Compile each locality buffer */
   2390 
   2391     FieldList = *PFieldList;
   2392     while (FieldList)
   2393     {
   2394         DtCompileBuffer (LocalityBuffer,
   2395             FieldList->Value, FieldList, Localities);
   2396 
   2397         LocalityListLength++;
   2398         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
   2399         DtInsertSubtable (ParentTable, Subtable);
   2400         EndOfFieldList = FieldList;
   2401         FieldList = FieldList->Next;
   2402     }
   2403 
   2404     if (LocalityListLength != Localities)
   2405     {
   2406         sprintf(AslGbl_MsgBuffer,
   2407             "Found %u entries, must match LocalityCount: %u",
   2408             LocalityListLength, Localities);
   2409         DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer);
   2410         ACPI_FREE (LocalityBuffer);
   2411         return (AE_LIMIT);
   2412     }
   2413 
   2414     ACPI_FREE (LocalityBuffer);
   2415     return (AE_OK);
   2416 }
   2417 
   2418 
   2419 /******************************************************************************
   2420  *
   2421  * FUNCTION:    DtCompileSrat
   2422  *
   2423  * PARAMETERS:  List                - Current field list pointer
   2424  *
   2425  * RETURN:      Status
   2426  *
   2427  * DESCRIPTION: Compile SRAT.
   2428  *
   2429  *****************************************************************************/
   2430 
   2431 ACPI_STATUS
   2432 DtCompileSrat (
   2433     void                    **List)
   2434 {
   2435     ACPI_STATUS             Status;
   2436     DT_SUBTABLE             *Subtable;
   2437     DT_SUBTABLE             *ParentTable;
   2438     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2439     DT_FIELD                *SubtableStart;
   2440     ACPI_SUBTABLE_HEADER    *SratHeader;
   2441     ACPI_DMTABLE_INFO       *InfoTable;
   2442 
   2443 
   2444     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
   2445         &Subtable);
   2446     if (ACPI_FAILURE (Status))
   2447     {
   2448         return (Status);
   2449     }
   2450 
   2451     ParentTable = DtPeekSubtable ();
   2452     DtInsertSubtable (ParentTable, Subtable);
   2453 
   2454     while (*PFieldList)
   2455     {
   2456         SubtableStart = *PFieldList;
   2457         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
   2458             &Subtable);
   2459         if (ACPI_FAILURE (Status))
   2460         {
   2461             return (Status);
   2462         }
   2463 
   2464         ParentTable = DtPeekSubtable ();
   2465         DtInsertSubtable (ParentTable, Subtable);
   2466         DtPushSubtable (Subtable);
   2467 
   2468         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
   2469 
   2470         switch (SratHeader->Type)
   2471         {
   2472         case ACPI_SRAT_TYPE_CPU_AFFINITY:
   2473 
   2474             InfoTable = AcpiDmTableInfoSrat0;
   2475             break;
   2476 
   2477         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
   2478 
   2479             InfoTable = AcpiDmTableInfoSrat1;
   2480             break;
   2481 
   2482         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
   2483 
   2484             InfoTable = AcpiDmTableInfoSrat2;
   2485             break;
   2486 
   2487         case ACPI_SRAT_TYPE_GICC_AFFINITY:
   2488 
   2489             InfoTable = AcpiDmTableInfoSrat3;
   2490             break;
   2491 
   2492         case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
   2493 
   2494             InfoTable = AcpiDmTableInfoSrat4;
   2495             break;
   2496 
   2497         case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
   2498 
   2499             InfoTable = AcpiDmTableInfoSrat5;
   2500             break;
   2501 
   2502         case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY:
   2503 
   2504             InfoTable = AcpiDmTableInfoSrat6;
   2505             break;
   2506 
   2507         case ACPI_SRAT_TYPE_RINTC_AFFINITY:
   2508 
   2509             InfoTable = AcpiDmTableInfoSrat7;
   2510             break;
   2511 
   2512         default:
   2513 
   2514             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
   2515             return (AE_ERROR);
   2516         }
   2517 
   2518         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   2519         if (ACPI_FAILURE (Status))
   2520         {
   2521             return (Status);
   2522         }
   2523 
   2524         ParentTable = DtPeekSubtable ();
   2525         DtInsertSubtable (ParentTable, Subtable);
   2526         DtPopSubtable ();
   2527     }
   2528 
   2529     return (AE_OK);
   2530 }
   2531 
   2532 
   2533 /******************************************************************************
   2534  *
   2535  * FUNCTION:    DtCompileStao
   2536  *
   2537  * PARAMETERS:  PFieldList          - Current field list pointer
   2538  *
   2539  * RETURN:      Status
   2540  *
   2541  * DESCRIPTION: Compile STAO.
   2542  *
   2543  *****************************************************************************/
   2544 
   2545 ACPI_STATUS
   2546 DtCompileStao (
   2547     void                    **List)
   2548 {
   2549     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2550     DT_SUBTABLE             *Subtable;
   2551     DT_SUBTABLE             *ParentTable;
   2552     ACPI_STATUS             Status;
   2553 
   2554 
   2555     /* Compile the main table */
   2556 
   2557     Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
   2558         &Subtable);
   2559     if (ACPI_FAILURE (Status))
   2560     {
   2561         return (Status);
   2562     }
   2563 
   2564     ParentTable = DtPeekSubtable ();
   2565     DtInsertSubtable (ParentTable, Subtable);
   2566 
   2567     /* Compile each ASCII namestring as a subtable */
   2568 
   2569     while (*PFieldList)
   2570     {
   2571         Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
   2572             &Subtable);
   2573         if (ACPI_FAILURE (Status))
   2574         {
   2575             return (Status);
   2576         }
   2577 
   2578         ParentTable = DtPeekSubtable ();
   2579         DtInsertSubtable (ParentTable, Subtable);
   2580     }
   2581 
   2582     return (AE_OK);
   2583 }
   2584 
   2585 
   2586 /******************************************************************************
   2587  *
   2588  * FUNCTION:    DtCompileSvkl
   2589  *
   2590  * PARAMETERS:  PFieldList          - Current field list pointer
   2591  *
   2592  * RETURN:      Status
   2593  *
   2594  * DESCRIPTION: Compile SVKL.
   2595  *
   2596  * NOTES: SVKL is essentially a flat table, with a small main table and
   2597  *          a variable number of a single type of subtable.
   2598  *
   2599  *****************************************************************************/
   2600 
   2601 ACPI_STATUS
   2602 DtCompileSvkl (
   2603     void                    **List)
   2604 {
   2605     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2606     DT_SUBTABLE             *Subtable;
   2607     DT_SUBTABLE             *ParentTable;
   2608     ACPI_STATUS             Status;
   2609 
   2610 
   2611     /* Compile the main table */
   2612 
   2613     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl,
   2614         &Subtable);
   2615     if (ACPI_FAILURE (Status))
   2616     {
   2617         return (Status);
   2618     }
   2619 
   2620     ParentTable = DtPeekSubtable ();
   2621     DtInsertSubtable (ParentTable, Subtable);
   2622 
   2623     /* Compile each subtable */
   2624 
   2625     while (*PFieldList)
   2626     {
   2627         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0,
   2628             &Subtable);
   2629         if (ACPI_FAILURE (Status))
   2630         {
   2631             return (Status);
   2632         }
   2633 
   2634         ParentTable = DtPeekSubtable ();
   2635         DtInsertSubtable (ParentTable, Subtable);
   2636     }
   2637 
   2638     return (AE_OK);
   2639 }
   2640 
   2641 
   2642 /******************************************************************************
   2643  *
   2644  * FUNCTION:    DtCompileTcpa
   2645  *
   2646  * PARAMETERS:  PFieldList          - Current field list pointer
   2647  *
   2648  * RETURN:      Status
   2649  *
   2650  * DESCRIPTION: Compile TCPA.
   2651  *
   2652  *****************************************************************************/
   2653 
   2654 ACPI_STATUS
   2655 DtCompileTcpa (
   2656     void                    **List)
   2657 {
   2658     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2659     DT_SUBTABLE             *Subtable;
   2660     ACPI_TABLE_TCPA_HDR     *TcpaHeader;
   2661     DT_SUBTABLE             *ParentTable;
   2662     ACPI_STATUS             Status;
   2663 
   2664 
   2665     /* Compile the main table */
   2666 
   2667     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
   2668         &Subtable);
   2669     if (ACPI_FAILURE (Status))
   2670     {
   2671         return (Status);
   2672     }
   2673 
   2674     ParentTable = DtPeekSubtable ();
   2675     DtInsertSubtable (ParentTable, Subtable);
   2676 
   2677     /*
   2678      * Examine the PlatformClass field to determine the table type.
   2679      * Either a client or server table. Only one.
   2680      */
   2681     TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
   2682 
   2683     switch (TcpaHeader->PlatformClass)
   2684     {
   2685     case ACPI_TCPA_CLIENT_TABLE:
   2686 
   2687         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
   2688             &Subtable);
   2689         break;
   2690 
   2691     case ACPI_TCPA_SERVER_TABLE:
   2692 
   2693         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
   2694             &Subtable);
   2695         break;
   2696 
   2697     default:
   2698 
   2699         AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
   2700             TcpaHeader->PlatformClass);
   2701         Status = AE_ERROR;
   2702         break;
   2703     }
   2704 
   2705     ParentTable = DtPeekSubtable ();
   2706     DtInsertSubtable (ParentTable, Subtable);
   2707     return (Status);
   2708 }
   2709 
   2710 
   2711 /******************************************************************************
   2712  *
   2713  * FUNCTION:    DtCompileTpm2Rev3
   2714  *
   2715  * PARAMETERS:  PFieldList          - Current field list pointer
   2716  *
   2717  * RETURN:      Status
   2718  *
   2719  * DESCRIPTION: Compile TPM2 revision 3
   2720  *
   2721  *****************************************************************************/
   2722 static ACPI_STATUS
   2723 DtCompileTpm2Rev3 (
   2724     void                    **List)
   2725 {
   2726     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2727     DT_SUBTABLE             *Subtable;
   2728     ACPI_TABLE_TPM23        *Tpm23Header;
   2729     DT_SUBTABLE             *ParentTable;
   2730     ACPI_STATUS             Status = AE_OK;
   2731 
   2732 
   2733     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23,
   2734         &Subtable);
   2735 
   2736     ParentTable = DtPeekSubtable ();
   2737     DtInsertSubtable (ParentTable, Subtable);
   2738     Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer);
   2739 
   2740     /* Subtable type depends on the StartMethod */
   2741 
   2742     switch (Tpm23Header->StartMethod)
   2743     {
   2744     case ACPI_TPM23_ACPI_START_METHOD:
   2745 
   2746         /* Subtable specific to to ARM_SMC */
   2747 
   2748         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a,
   2749             &Subtable);
   2750         if (ACPI_FAILURE (Status))
   2751         {
   2752             return (Status);
   2753         }
   2754 
   2755         ParentTable = DtPeekSubtable ();
   2756         DtInsertSubtable (ParentTable, Subtable);
   2757         break;
   2758 
   2759     default:
   2760         break;
   2761     }
   2762 
   2763     return (Status);
   2764 }
   2765 
   2766 
   2767 /******************************************************************************
   2768  *
   2769  * FUNCTION:    DtCompileTpm2
   2770  *
   2771  * PARAMETERS:  PFieldList          - Current field list pointer
   2772  *
   2773  * RETURN:      Status
   2774  *
   2775  * DESCRIPTION: Compile TPM2.
   2776  *
   2777  *****************************************************************************/
   2778 
   2779 ACPI_STATUS
   2780 DtCompileTpm2 (
   2781     void                    **List)
   2782 {
   2783     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2784     DT_SUBTABLE             *Subtable;
   2785     ACPI_TABLE_TPM2         *Tpm2Header;
   2786     DT_SUBTABLE             *ParentTable;
   2787     ACPI_STATUS             Status = AE_OK;
   2788     ACPI_TABLE_HEADER       *Header;
   2789 
   2790 
   2791     ParentTable = DtPeekSubtable ();
   2792 
   2793     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   2794 
   2795     if (Header->Revision == 3)
   2796     {
   2797         return (DtCompileTpm2Rev3 (List));
   2798     }
   2799 
   2800     /* Compile the main table */
   2801 
   2802     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
   2803         &Subtable);
   2804     if (ACPI_FAILURE (Status))
   2805     {
   2806         return (Status);
   2807     }
   2808 
   2809     ParentTable = DtPeekSubtable ();
   2810     DtInsertSubtable (ParentTable, Subtable);
   2811 
   2812     Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
   2813 
   2814     /* Method parameters */
   2815     /* Optional: Log area minimum length */
   2816     /* Optional: Log area start address */
   2817     /* TBD: Optional fields above not fully implemented (not optional at this time) */
   2818 
   2819     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
   2820         &Subtable);
   2821     if (ACPI_FAILURE (Status))
   2822     {
   2823         return (Status);
   2824     }
   2825 
   2826     ParentTable = DtPeekSubtable ();
   2827     DtInsertSubtable (ParentTable, Subtable);
   2828 
   2829 
   2830     /* Subtable type depends on the StartMethod */
   2831 
   2832     switch (Tpm2Header->StartMethod)
   2833     {
   2834     case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
   2835 
   2836         /* Subtable specific to to ARM_SMC */
   2837 
   2838         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
   2839             &Subtable);
   2840         if (ACPI_FAILURE (Status))
   2841         {
   2842             return (Status);
   2843         }
   2844 
   2845         ParentTable = DtPeekSubtable ();
   2846         DtInsertSubtable (ParentTable, Subtable);
   2847         break;
   2848 
   2849     case ACPI_TPM2_START_METHOD:
   2850     case ACPI_TPM2_MEMORY_MAPPED:
   2851     case ACPI_TPM2_COMMAND_BUFFER:
   2852     case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
   2853         break;
   2854 
   2855     case ACPI_TPM2_RESERVED1:
   2856     case ACPI_TPM2_RESERVED3:
   2857     case ACPI_TPM2_RESERVED4:
   2858     case ACPI_TPM2_RESERVED5:
   2859     case ACPI_TPM2_RESERVED9:
   2860     case ACPI_TPM2_RESERVED10:
   2861 
   2862         AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
   2863             Tpm2Header->StartMethod);
   2864         Status = AE_ERROR;
   2865         break;
   2866 
   2867     case ACPI_TPM2_NOT_ALLOWED:
   2868     default:
   2869 
   2870         AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
   2871             Tpm2Header->StartMethod);
   2872         Status = AE_ERROR;
   2873         break;
   2874     }
   2875 
   2876     return (Status);
   2877 }
   2878 
   2879 
   2880 /******************************************************************************
   2881  *
   2882  * FUNCTION:    DtGetGenericTableInfo
   2883  *
   2884  * PARAMETERS:  Name                - Generic type name
   2885  *
   2886  * RETURN:      Info entry
   2887  *
   2888  * DESCRIPTION: Obtain table info for a generic name entry
   2889  *
   2890  *****************************************************************************/
   2891 
   2892 ACPI_DMTABLE_INFO *
   2893 DtGetGenericTableInfo (
   2894     char                    *Name)
   2895 {
   2896     ACPI_DMTABLE_INFO       *Info;
   2897     UINT32                  i;
   2898 
   2899 
   2900     if (!Name)
   2901     {
   2902         return (NULL);
   2903     }
   2904 
   2905     /* Search info table for name match */
   2906 
   2907     for (i = 0; ; i++)
   2908     {
   2909         Info = AcpiDmTableInfoGeneric[i];
   2910         if (Info->Opcode == ACPI_DMT_EXIT)
   2911         {
   2912             Info = NULL;
   2913             break;
   2914         }
   2915 
   2916         /* Use caseless compare for generic keywords */
   2917 
   2918         if (!AcpiUtStricmp (Name, Info->Name))
   2919         {
   2920             break;
   2921         }
   2922     }
   2923 
   2924     return (Info);
   2925 }
   2926 
   2927 
   2928 /******************************************************************************
   2929  *
   2930  * FUNCTION:    DtCompileUefi
   2931  *
   2932  * PARAMETERS:  List                - Current field list pointer
   2933  *
   2934  * RETURN:      Status
   2935  *
   2936  * DESCRIPTION: Compile UEFI.
   2937  *
   2938  *****************************************************************************/
   2939 
   2940 ACPI_STATUS
   2941 DtCompileUefi (
   2942     void                    **List)
   2943 {
   2944     ACPI_STATUS             Status;
   2945     DT_SUBTABLE             *Subtable;
   2946     DT_SUBTABLE             *ParentTable;
   2947     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2948     UINT16                  *DataOffset;
   2949 
   2950 
   2951     /* Compile the predefined portion of the UEFI table */
   2952 
   2953     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
   2954         &Subtable);
   2955     if (ACPI_FAILURE (Status))
   2956     {
   2957         return (Status);
   2958     }
   2959 
   2960     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
   2961     *DataOffset = sizeof (ACPI_TABLE_UEFI);
   2962 
   2963     ParentTable = DtPeekSubtable ();
   2964     DtInsertSubtable (ParentTable, Subtable);
   2965 
   2966     /*
   2967      * Compile the "generic" portion of the UEFI table. This
   2968      * part of the table is not predefined and any of the generic
   2969      * operators may be used.
   2970      */
   2971     DtCompileGeneric ((void **) PFieldList, NULL, NULL);
   2972     return (AE_OK);
   2973 }
   2974 
   2975 
   2976 /******************************************************************************
   2977  *
   2978  * FUNCTION:    DtCompileViot
   2979  *
   2980  * PARAMETERS:  List                - Current field list pointer
   2981  *
   2982  * RETURN:      Status
   2983  *
   2984  * DESCRIPTION: Compile VIOT.
   2985  *
   2986  *****************************************************************************/
   2987 
   2988 ACPI_STATUS
   2989 DtCompileViot (
   2990     void                    **List)
   2991 {
   2992     ACPI_STATUS             Status;
   2993     DT_SUBTABLE             *Subtable;
   2994     DT_SUBTABLE             *ParentTable;
   2995     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2996     DT_FIELD                *SubtableStart;
   2997     ACPI_TABLE_VIOT         *Viot;
   2998     ACPI_VIOT_HEADER        *ViotHeader;
   2999     ACPI_DMTABLE_INFO       *InfoTable;
   3000     UINT16                  NodeCount;
   3001 
   3002     ParentTable = DtPeekSubtable ();
   3003 
   3004     Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable);
   3005     if (ACPI_FAILURE (Status))
   3006     {
   3007         return (Status);
   3008     }
   3009     DtInsertSubtable (ParentTable, Subtable);
   3010 
   3011     /*
   3012      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   3013      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
   3014      */
   3015     Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer,
   3016         sizeof (ACPI_TABLE_HEADER));
   3017 
   3018     Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT);
   3019 
   3020     NodeCount = 0;
   3021     while (*PFieldList) {
   3022         SubtableStart = *PFieldList;
   3023         Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader,
   3024             &Subtable);
   3025         if (ACPI_FAILURE (Status))
   3026         {
   3027             return (Status);
   3028         }
   3029 
   3030         ParentTable = DtPeekSubtable ();
   3031         DtInsertSubtable (ParentTable, Subtable);
   3032         DtPushSubtable (Subtable);
   3033 
   3034         ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer);
   3035 
   3036         switch (ViotHeader->Type)
   3037         {
   3038         case ACPI_VIOT_NODE_PCI_RANGE:
   3039 
   3040             InfoTable = AcpiDmTableInfoViot1;
   3041             break;
   3042 
   3043         case ACPI_VIOT_NODE_MMIO:
   3044 
   3045             InfoTable = AcpiDmTableInfoViot2;
   3046             break;
   3047 
   3048         case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI:
   3049 
   3050             InfoTable = AcpiDmTableInfoViot3;
   3051             break;
   3052 
   3053         case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO:
   3054 
   3055             InfoTable = AcpiDmTableInfoViot4;
   3056             break;
   3057 
   3058         default:
   3059 
   3060             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT");
   3061             return (AE_ERROR);
   3062         }
   3063 
   3064         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   3065         if (ACPI_FAILURE (Status))
   3066         {
   3067             return (Status);
   3068         }
   3069 
   3070         ParentTable = DtPeekSubtable ();
   3071         DtInsertSubtable (ParentTable, Subtable);
   3072         DtPopSubtable ();
   3073         NodeCount++;
   3074     }
   3075 
   3076     Viot->NodeCount = NodeCount;
   3077     return (AE_OK);
   3078 }
   3079 
   3080 
   3081 /******************************************************************************
   3082  *
   3083  * FUNCTION:    DtCompileWdat
   3084  *
   3085  * PARAMETERS:  List                - Current field list pointer
   3086  *
   3087  * RETURN:      Status
   3088  *
   3089  * DESCRIPTION: Compile WDAT.
   3090  *
   3091  *****************************************************************************/
   3092 
   3093 ACPI_STATUS
   3094 DtCompileWdat (
   3095     void                    **List)
   3096 {
   3097     ACPI_STATUS             Status;
   3098 
   3099 
   3100     Status = DtCompileTwoSubtables (List,
   3101         AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
   3102     return (Status);
   3103 }
   3104 
   3105 
   3106 /******************************************************************************
   3107  *
   3108  * FUNCTION:    DtCompileWpbt
   3109  *
   3110  * PARAMETERS:  List                - Current field list pointer
   3111  *
   3112  * RETURN:      Status
   3113  *
   3114  * DESCRIPTION: Compile WPBT.
   3115  *
   3116  *****************************************************************************/
   3117 
   3118 ACPI_STATUS
   3119 DtCompileWpbt (
   3120     void                    **List)
   3121 {
   3122     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   3123     DT_SUBTABLE             *Subtable;
   3124     DT_SUBTABLE             *ParentTable;
   3125     ACPI_TABLE_WPBT         *Table;
   3126     ACPI_STATUS             Status;
   3127 
   3128 
   3129     /* Compile the main table */
   3130 
   3131     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable);
   3132     if (ACPI_FAILURE (Status))
   3133     {
   3134         return (Status);
   3135     }
   3136 
   3137     ParentTable = DtPeekSubtable ();
   3138     DtInsertSubtable (ParentTable, Subtable);
   3139     Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
   3140 
   3141     /*
   3142      * Exit now if there are no arguments specified. This is indicated by:
   3143      * The "Command-line Arguments" field has not been specified (if specified,
   3144      * it will be the last field in the field list -- after the main table).
   3145      * Set the Argument Length in the main table to zero.
   3146      */
   3147     if (!*PFieldList)
   3148     {
   3149         Table->ArgumentsLength = 0;
   3150         return (AE_OK);
   3151     }
   3152 
   3153     /* Compile the argument list subtable */
   3154 
   3155     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable);
   3156     if (ACPI_FAILURE (Status))
   3157     {
   3158         return (Status);
   3159     }
   3160 
   3161     /* Extract the length of the Arguments buffer, insert into main table */
   3162 
   3163     Table->ArgumentsLength = (UINT16) Subtable->TotalLength;
   3164     DtInsertSubtable (ParentTable, Subtable);
   3165     return (AE_OK);
   3166 }
   3167 
   3168 
   3169 /******************************************************************************
   3170  *
   3171  * FUNCTION:    DtCompileXsdt
   3172  *
   3173  * PARAMETERS:  List                - Current field list pointer
   3174  *
   3175  * RETURN:      Status
   3176  *
   3177  * DESCRIPTION: Compile XSDT.
   3178  *
   3179  *****************************************************************************/
   3180 
   3181 ACPI_STATUS
   3182 DtCompileXsdt (
   3183     void                    **List)
   3184 {
   3185     DT_SUBTABLE             *Subtable;
   3186     DT_SUBTABLE             *ParentTable;
   3187     DT_FIELD                *FieldList = *(DT_FIELD **) List;
   3188     UINT64                  Address;
   3189 
   3190 
   3191     ParentTable = DtPeekSubtable ();
   3192 
   3193     while (FieldList)
   3194     {
   3195         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
   3196 
   3197         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
   3198         DtInsertSubtable (ParentTable, Subtable);
   3199         FieldList = FieldList->Next;
   3200     }
   3201 
   3202     return (AE_OK);
   3203 }
   3204 
   3205 
   3206 /******************************************************************************
   3207  *
   3208  * FUNCTION:    DtCompileGeneric
   3209  *
   3210  * PARAMETERS:  List                - Current field list pointer
   3211  *              Name                - Field name to end generic compiling
   3212  *              Length              - Compiled table length to return
   3213  *
   3214  * RETURN:      Status
   3215  *
   3216  * DESCRIPTION: Compile generic unknown table.
   3217  *
   3218  *****************************************************************************/
   3219 
   3220 ACPI_STATUS
   3221 DtCompileGeneric (
   3222     void                    **List,
   3223     char                    *Name,
   3224     UINT32                  *Length)
   3225 {
   3226     ACPI_STATUS             Status;
   3227     DT_SUBTABLE             *Subtable;
   3228     DT_SUBTABLE             *ParentTable;
   3229     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   3230     ACPI_DMTABLE_INFO       *Info;
   3231 
   3232 
   3233     ParentTable = DtPeekSubtable ();
   3234 
   3235     /*
   3236      * Compile the "generic" portion of the table. This
   3237      * part of the table is not predefined and any of the generic
   3238      * operators may be used.
   3239      */
   3240 
   3241     /* Find any and all labels in the entire generic portion */
   3242 
   3243     DtDetectAllLabels (*PFieldList);
   3244 
   3245     /* Now we can actually compile the parse tree */
   3246 
   3247     if (Length && *Length)
   3248     {
   3249         *Length = 0;
   3250     }
   3251     while (*PFieldList)
   3252     {
   3253         if (Name && !strcmp ((*PFieldList)->Name, Name))
   3254         {
   3255             break;
   3256         }
   3257 
   3258         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
   3259         if (!Info)
   3260         {
   3261             sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
   3262                 (*PFieldList)->Name);
   3263             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
   3264                 (*PFieldList), AslGbl_MsgBuffer);
   3265 
   3266             *PFieldList = (*PFieldList)->Next;
   3267             continue;
   3268         }
   3269 
   3270         Status = DtCompileTable (PFieldList, Info,
   3271             &Subtable);
   3272         if (ACPI_SUCCESS (Status))
   3273         {
   3274             DtInsertSubtable (ParentTable, Subtable);
   3275             if (Length)
   3276             {
   3277                 *Length += Subtable->Length;
   3278             }
   3279         }
   3280         else
   3281         {
   3282             *PFieldList = (*PFieldList)->Next;
   3283 
   3284             if (Status == AE_NOT_FOUND)
   3285             {
   3286                 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
   3287                     (*PFieldList)->Name);
   3288                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
   3289                     (*PFieldList), AslGbl_MsgBuffer);
   3290             }
   3291         }
   3292     }
   3293 
   3294     return (AE_OK);
   3295 }
   3296