Home | History | Annotate | Line # | Download | only in compiler
      1 /******************************************************************************
      2  *
      3  * Module Name: dttable2.c - handling for specific ACPI tables
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2025, 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:    DtCompileMrrm
    686  *
    687  * PARAMETERS:  List                - Current field list pointer
    688  *
    689  * RETURN:      Status
    690  *
    691  * DESCRIPTION: Compile MRRM.
    692  *
    693  *****************************************************************************/
    694 
    695 ACPI_STATUS
    696 DtCompileMrrm (
    697     void                    **List)
    698 {
    699     ACPI_STATUS             Status;
    700     DT_SUBTABLE             *Subtable;
    701     DT_SUBTABLE             *ParentTable;
    702     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    703 
    704     /* Main table */
    705 
    706     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMrrm,
    707         &Subtable);
    708     if (ACPI_FAILURE (Status))
    709     {
    710         return (Status);
    711     }
    712 
    713     ParentTable = DtPeekSubtable ();
    714     DtInsertSubtable (ParentTable, Subtable);
    715 
    716     /* Subtables (all are same type) */
    717 
    718     while (*PFieldList)
    719     {
    720         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMrrm0,
    721             &Subtable);
    722         if (ACPI_FAILURE (Status))
    723         {
    724             return (Status);
    725         }
    726 
    727         DtInsertSubtable (ParentTable, Subtable);
    728     }
    729 
    730     return (AE_OK);
    731 }
    732 
    733 
    734 /******************************************************************************
    735  *
    736  * FUNCTION:    DtCompileMsct
    737  *
    738  * PARAMETERS:  List                - Current field list pointer
    739  *
    740  * RETURN:      Status
    741  *
    742  * DESCRIPTION: Compile MSCT.
    743  *
    744  *****************************************************************************/
    745 
    746 ACPI_STATUS
    747 DtCompileMsct (
    748     void                    **List)
    749 {
    750     ACPI_STATUS             Status;
    751 
    752 
    753     Status = DtCompileTwoSubtables (List,
    754         AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
    755     return (Status);
    756 }
    757 
    758 
    759 /******************************************************************************
    760  *
    761  * FUNCTION:    DtCompileNfit
    762  *
    763  * PARAMETERS:  List                - Current field list pointer
    764  *
    765  * RETURN:      Status
    766  *
    767  * DESCRIPTION: Compile NFIT.
    768  *
    769  *****************************************************************************/
    770 
    771 ACPI_STATUS
    772 DtCompileNfit (
    773     void                    **List)
    774 {
    775     ACPI_STATUS             Status;
    776     DT_SUBTABLE             *Subtable;
    777     DT_SUBTABLE             *ParentTable;
    778     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    779     DT_FIELD                *SubtableStart;
    780     ACPI_NFIT_HEADER        *NfitHeader;
    781     ACPI_DMTABLE_INFO       *InfoTable;
    782     UINT32                  Count;
    783     ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
    784     ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
    785 
    786 
    787     /* Main table */
    788 
    789     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
    790         &Subtable);
    791     if (ACPI_FAILURE (Status))
    792     {
    793         return (Status);
    794     }
    795 
    796     ParentTable = DtPeekSubtable ();
    797     DtInsertSubtable (ParentTable, Subtable);
    798     DtPushSubtable (Subtable);
    799 
    800     /* Subtables */
    801 
    802     while (*PFieldList)
    803     {
    804         SubtableStart = *PFieldList;
    805         Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
    806             &Subtable);
    807         if (ACPI_FAILURE (Status))
    808         {
    809             return (Status);
    810         }
    811 
    812         ParentTable = DtPeekSubtable ();
    813         DtInsertSubtable (ParentTable, Subtable);
    814         DtPushSubtable (Subtable);
    815 
    816         NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
    817 
    818         switch (NfitHeader->Type)
    819         {
    820         case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
    821 
    822             InfoTable = AcpiDmTableInfoNfit0;
    823             break;
    824 
    825         case ACPI_NFIT_TYPE_MEMORY_MAP:
    826 
    827             InfoTable = AcpiDmTableInfoNfit1;
    828             break;
    829 
    830         case ACPI_NFIT_TYPE_INTERLEAVE:
    831 
    832             Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
    833             InfoTable = AcpiDmTableInfoNfit2;
    834             break;
    835 
    836         case ACPI_NFIT_TYPE_SMBIOS:
    837 
    838             InfoTable = AcpiDmTableInfoNfit3;
    839             break;
    840 
    841         case ACPI_NFIT_TYPE_CONTROL_REGION:
    842 
    843             InfoTable = AcpiDmTableInfoNfit4;
    844             break;
    845 
    846         case ACPI_NFIT_TYPE_DATA_REGION:
    847 
    848             InfoTable = AcpiDmTableInfoNfit5;
    849             break;
    850 
    851         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
    852 
    853             Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
    854             InfoTable = AcpiDmTableInfoNfit6;
    855             break;
    856 
    857         case ACPI_NFIT_TYPE_CAPABILITIES:
    858 
    859             InfoTable = AcpiDmTableInfoNfit7;
    860             break;
    861 
    862         default:
    863 
    864             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
    865             return (AE_ERROR);
    866         }
    867 
    868         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    869         if (ACPI_FAILURE (Status))
    870         {
    871             return (Status);
    872         }
    873 
    874         ParentTable = DtPeekSubtable ();
    875         DtInsertSubtable (ParentTable, Subtable);
    876         DtPopSubtable ();
    877 
    878         switch (NfitHeader->Type)
    879         {
    880         case ACPI_NFIT_TYPE_INTERLEAVE:
    881 
    882             Count = 0;
    883             DtPushSubtable (Subtable);
    884             while (*PFieldList)
    885             {
    886                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
    887                     &Subtable);
    888                 if (ACPI_FAILURE (Status))
    889                 {
    890                     return (Status);
    891                 }
    892 
    893                 if (!Subtable)
    894                 {
    895                     DtPopSubtable ();
    896                     break;
    897                 }
    898 
    899                 ParentTable = DtPeekSubtable ();
    900                 DtInsertSubtable (ParentTable, Subtable);
    901                 Count++;
    902             }
    903 
    904             Interleave->LineCount = Count;
    905             break;
    906 
    907         case ACPI_NFIT_TYPE_SMBIOS:
    908 
    909             if (*PFieldList)
    910             {
    911                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
    912                     &Subtable);
    913                 if (ACPI_FAILURE (Status))
    914                 {
    915                     return (Status);
    916                 }
    917 
    918                 if (Subtable)
    919                 {
    920                     DtInsertSubtable (ParentTable, Subtable);
    921                 }
    922             }
    923             break;
    924 
    925         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
    926 
    927             Count = 0;
    928             DtPushSubtable (Subtable);
    929             while (*PFieldList)
    930             {
    931                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
    932                     &Subtable);
    933                 if (ACPI_FAILURE (Status))
    934                 {
    935                     return (Status);
    936                 }
    937 
    938                 if (!Subtable)
    939                 {
    940                     DtPopSubtable ();
    941                     break;
    942                 }
    943 
    944                 ParentTable = DtPeekSubtable ();
    945                 DtInsertSubtable (ParentTable, Subtable);
    946                 Count++;
    947             }
    948 
    949             Hint->HintCount = (UINT16) Count;
    950             break;
    951 
    952         default:
    953             break;
    954         }
    955     }
    956 
    957     return (AE_OK);
    958 }
    959 
    960 
    961 /******************************************************************************
    962  *
    963  * FUNCTION:    DtCompilePcct
    964  *
    965  * PARAMETERS:  List                - Current field list pointer
    966  *
    967  * RETURN:      Status
    968  *
    969  * DESCRIPTION: Compile PCCT.
    970  *
    971  *****************************************************************************/
    972 
    973 ACPI_STATUS
    974 DtCompilePcct (
    975     void                    **List)
    976 {
    977     ACPI_STATUS             Status;
    978     DT_SUBTABLE             *Subtable;
    979     DT_SUBTABLE             *ParentTable;
    980     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    981     DT_FIELD                *SubtableStart;
    982     ACPI_SUBTABLE_HEADER    *PcctHeader;
    983     ACPI_DMTABLE_INFO       *InfoTable;
    984 
    985 
    986     /* Main table */
    987 
    988     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
    989         &Subtable);
    990     if (ACPI_FAILURE (Status))
    991     {
    992         return (Status);
    993     }
    994 
    995     ParentTable = DtPeekSubtable ();
    996     DtInsertSubtable (ParentTable, Subtable);
    997 
    998     /* Subtables */
    999 
   1000     while (*PFieldList)
   1001     {
   1002         SubtableStart = *PFieldList;
   1003         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
   1004             &Subtable);
   1005         if (ACPI_FAILURE (Status))
   1006         {
   1007             return (Status);
   1008         }
   1009 
   1010         ParentTable = DtPeekSubtable ();
   1011         DtInsertSubtable (ParentTable, Subtable);
   1012         DtPushSubtable (Subtable);
   1013 
   1014         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
   1015 
   1016         switch (PcctHeader->Type)
   1017         {
   1018         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
   1019 
   1020             InfoTable = AcpiDmTableInfoPcct0;
   1021             break;
   1022 
   1023         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
   1024 
   1025             InfoTable = AcpiDmTableInfoPcct1;
   1026             break;
   1027 
   1028         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
   1029 
   1030             InfoTable = AcpiDmTableInfoPcct2;
   1031             break;
   1032 
   1033         case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
   1034 
   1035             InfoTable = AcpiDmTableInfoPcct3;
   1036             break;
   1037 
   1038         case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
   1039 
   1040             InfoTable = AcpiDmTableInfoPcct4;
   1041             break;
   1042 
   1043         case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE:
   1044 
   1045             InfoTable = AcpiDmTableInfoPcct5;
   1046             break;
   1047 
   1048         default:
   1049 
   1050             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
   1051             return (AE_ERROR);
   1052         }
   1053 
   1054         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1055         if (ACPI_FAILURE (Status))
   1056         {
   1057             return (Status);
   1058         }
   1059 
   1060         ParentTable = DtPeekSubtable ();
   1061         DtInsertSubtable (ParentTable, Subtable);
   1062         DtPopSubtable ();
   1063     }
   1064 
   1065     return (AE_OK);
   1066 }
   1067 
   1068 
   1069 /******************************************************************************
   1070  *
   1071  * FUNCTION:    DtCompilePdtt
   1072  *
   1073  * PARAMETERS:  List                - Current field list pointer
   1074  *
   1075  * RETURN:      Status
   1076  *
   1077  * DESCRIPTION: Compile PDTT.
   1078  *
   1079  *****************************************************************************/
   1080 
   1081 ACPI_STATUS
   1082 DtCompilePdtt (
   1083     void                    **List)
   1084 {
   1085     ACPI_STATUS             Status;
   1086     DT_SUBTABLE             *Subtable;
   1087     DT_SUBTABLE             *ParentTable;
   1088     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1089     ACPI_TABLE_PDTT         *PdttHeader;
   1090     UINT32                  Count = 0;
   1091 
   1092 
   1093     /* Main table */
   1094 
   1095     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable);
   1096     if (ACPI_FAILURE (Status))
   1097     {
   1098         return (Status);
   1099     }
   1100 
   1101     ParentTable = DtPeekSubtable ();
   1102     DtInsertSubtable (ParentTable, Subtable);
   1103 
   1104     PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer);
   1105     PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT);
   1106 
   1107     /* There is only one type of subtable at this time, no need to decode */
   1108 
   1109     while (*PFieldList)
   1110     {
   1111         /* List of subchannel IDs, each 2 bytes */
   1112 
   1113         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0,
   1114             &Subtable);
   1115         if (ACPI_FAILURE (Status))
   1116         {
   1117             return (Status);
   1118         }
   1119 
   1120         DtInsertSubtable (ParentTable, Subtable);
   1121         Count++;
   1122     }
   1123 
   1124     PdttHeader->TriggerCount = (UINT8) Count;
   1125     return (AE_OK);
   1126 }
   1127 
   1128 
   1129 /******************************************************************************
   1130  *
   1131  * FUNCTION:    DtCompilePhat
   1132  *
   1133  * PARAMETERS:  List                - Current field list pointer
   1134  *
   1135  * RETURN:      Status
   1136  *
   1137  * DESCRIPTION: Compile Phat.
   1138  *
   1139  *****************************************************************************/
   1140 
   1141 ACPI_STATUS
   1142 DtCompilePhat (
   1143     void                    **List)
   1144 {
   1145     ACPI_STATUS             Status = AE_OK;
   1146     DT_SUBTABLE             *Subtable;
   1147     DT_SUBTABLE             *ParentTable;
   1148     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1149     ACPI_PHAT_HEADER        *PhatHeader;
   1150     ACPI_DMTABLE_INFO       *Info;
   1151     ACPI_PHAT_VERSION_DATA  *VersionData;
   1152     UINT32                  DeviceDataLength;
   1153     UINT32                  RecordCount;
   1154     DT_FIELD                *DataOffsetField;
   1155     DT_FIELD                *DevicePathField;
   1156     UINT32                  TableOffset = 0;
   1157     UINT32                  DataOffsetValue;
   1158     UINT32                  i;
   1159 
   1160 
   1161     /* The table consists of subtables */
   1162 
   1163     while (*PFieldList)
   1164     {
   1165         /* Compile the common subtable header */
   1166 
   1167         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable);
   1168         if (ACPI_FAILURE (Status))
   1169         {
   1170             return (Status);
   1171         }
   1172 
   1173         TableOffset += Subtable->Length;
   1174         DbgPrint (ASL_DEBUG_OUTPUT, "0 Subtable->Length: %X\n", Subtable->Length);
   1175 
   1176         ParentTable = DtPeekSubtable ();
   1177         DtInsertSubtable (ParentTable, Subtable);
   1178         DtPushSubtable (Subtable);
   1179 
   1180         PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer);
   1181 
   1182         switch (PhatHeader->Type)
   1183         {
   1184         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
   1185 
   1186             /* Compile the middle portion of the Firmware Version Data */
   1187 
   1188             Info = AcpiDmTableInfoPhat0;
   1189             PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA);
   1190             DataOffsetField = NULL;
   1191             break;
   1192 
   1193         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
   1194 
   1195             DbgPrint (ASL_DEBUG_OUTPUT, "1 Offset: %X, Name: \"%s\" Length: %X\n",
   1196                 (*PFieldList)->TableOffset, (*PFieldList)->Name, Subtable->Length);
   1197 
   1198             DataOffsetField = *PFieldList;
   1199 
   1200             /* Walk the field list to get to the "Device-specific data Offset" field */
   1201 
   1202             TableOffset = sizeof (ACPI_PHAT_HEALTH_DATA);
   1203             for (i = 0; i < 3; i++)
   1204             {
   1205                 DataOffsetField = DataOffsetField->Next;
   1206                 DbgPrint (ASL_DEBUG_OUTPUT, "2 Offset: %X, Name: \"%s\" Length: %X Value: %s:\n",
   1207                     TableOffset, DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value);
   1208             }
   1209 
   1210             /* Convert DataOffsetField->Value (a char * string) to an integer value */
   1211 
   1212             sscanf (DataOffsetField->Value, "%X", &DataOffsetValue);
   1213 
   1214             /*
   1215              * Get the next field (Device Path):
   1216              * DataOffsetField points to "Device-Specific Offset", next field is
   1217              * "Device Path".
   1218              */
   1219             DevicePathField = DataOffsetField->Next;
   1220 
   1221             /* Compute the size of the input ASCII string as a unicode string (*2 + 2) */
   1222 
   1223             DevicePathField->StringLength = (strlen ((const char *) DevicePathField->Value) * 2) + 2;
   1224             TableOffset += DevicePathField->StringLength;
   1225 
   1226             DbgPrint (ASL_DEBUG_OUTPUT, "3 Offset: %X, Length: %X devicepathLength: %X\n",
   1227                 TableOffset, Subtable->Length, DevicePathField->StringLength);
   1228 
   1229             /* Set the DataOffsetField to the current TableOffset */
   1230             /* Must set the DataOffsetField here (not later) */
   1231 
   1232             if (DataOffsetValue != 0)
   1233             {
   1234                 snprintf (DataOffsetField->Value, Subtable->Length, "%X", TableOffset);
   1235             }
   1236 
   1237             DbgPrint (ASL_DEBUG_OUTPUT, "4 Offset: %X, Length: %X\n", TableOffset, Subtable->Length);
   1238 
   1239             DbgPrint (ASL_DEBUG_OUTPUT, "5 TableOffset: %X, DataOffsetField->StringLength: "
   1240                 "%X DevicePathField Length: %X DevicePathField->Value: %s, DataOffsetField->Value: %s DataOffsetField->ByteOffset %X\n",
   1241                 TableOffset, DataOffsetField->StringLength, DevicePathField->StringLength,
   1242                 DevicePathField->Value, DataOffsetField->Value, DataOffsetField->ByteOffset);
   1243 
   1244             /* Compile the middle portion of the Health Data Record */
   1245 
   1246             Info = AcpiDmTableInfoPhat1;
   1247             PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA);
   1248             break;
   1249 
   1250         default:
   1251 
   1252             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
   1253             return (AE_ERROR);
   1254         }
   1255 
   1256         /* Compile either the Version Data or the Health Data */
   1257 
   1258         Status = DtCompileTable (PFieldList, Info, &Subtable);
   1259         if (ACPI_FAILURE (Status))
   1260         {
   1261             return (Status);
   1262         }
   1263 
   1264         DbgPrint (ASL_DEBUG_OUTPUT, "6 Offset: %X, Name: \"%s\" SubtableLength: %X\n",
   1265             TableOffset /* - StartTableOffset*/, (*PFieldList)->Name, Subtable->Length);
   1266 
   1267         ParentTable = DtPeekSubtable ();
   1268         DtInsertSubtable (ParentTable, Subtable);
   1269 
   1270         switch (PhatHeader->Type)
   1271         {
   1272         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
   1273 
   1274             VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA,
   1275                 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER)));
   1276             RecordCount = VersionData->ElementCount;
   1277 
   1278             /* Compile all of the Version Elements */
   1279 
   1280             while (RecordCount)
   1281             {
   1282                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a,
   1283                     &Subtable);
   1284                 if (ACPI_FAILURE (Status))
   1285                 {
   1286                     return (Status);
   1287                 }
   1288 
   1289                 ParentTable = DtPeekSubtable ();
   1290                 DtInsertSubtable (ParentTable, Subtable);
   1291 
   1292                 TableOffset += Subtable->Length;
   1293                 RecordCount--;
   1294                 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT);
   1295             }
   1296 
   1297             DtPopSubtable ();
   1298             break;
   1299 
   1300         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
   1301 
   1302             /* Compile the Device Path */
   1303 
   1304             DeviceDataLength = Subtable->Length;
   1305             TableOffset += Subtable->Length;
   1306 
   1307             DbgPrint (ASL_DEBUG_OUTPUT, "7 Device Path Length: %X FieldName: \"%s\" FieldLength: "
   1308                 "%s FieldValue: %s SubtableLength: %X TableOffset: %X\n", DeviceDataLength,
   1309                 (*PFieldList)->Name, DataOffsetField->Value, (*PFieldList)->Value,
   1310                 Subtable->Length, TableOffset);
   1311 
   1312             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable);
   1313             if (ACPI_FAILURE (Status))
   1314             {
   1315                 return (Status);
   1316             }
   1317             ParentTable = DtPeekSubtable ();
   1318             DtInsertSubtable (ParentTable, Subtable);
   1319 
   1320             /* *PFieldList will be null if previous field was at the end-of-ParseTree (EOF) */
   1321 
   1322             if (!*PFieldList)
   1323             {
   1324                 DbgPrint (ASL_DEBUG_OUTPUT, "8 Exit on end-of-ParseTree\n");
   1325                 return (AE_OK);
   1326             }
   1327 
   1328             DbgPrint (ASL_DEBUG_OUTPUT, "9 Device Data Length: %X FieldName: \"%s"
   1329                 " TableOffset: %X FieldLength: %X Field Value: %s SubtableLength: %X\n",
   1330                 DeviceDataLength, (*PFieldList)->Name, TableOffset,
   1331                 (*PFieldList)->StringLength, (*PFieldList)->Value, Subtable->Length);
   1332 
   1333             PhatHeader->Length += (UINT16) Subtable->Length;
   1334 
   1335             /* Convert DataOffsetField->Value (a hex char * string) to an integer value */
   1336 
   1337             sscanf (DataOffsetField->Value, "%X", &DataOffsetValue);
   1338 
   1339             DbgPrint (ASL_DEBUG_OUTPUT, "10 Device-Specific Offset: %X Table Offset: %X\n",
   1340                 DataOffsetValue, TableOffset);
   1341             if (DataOffsetValue != 0)
   1342             {
   1343                 /* Compile Device-Specific Data - only if the Data Offset is non-zero */
   1344 
   1345                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable);
   1346                 if (ACPI_FAILURE (Status))
   1347                 {
   1348                     return (Status);
   1349                 }
   1350 
   1351                 DbgPrint (ASL_DEBUG_OUTPUT, "11 Subtable: %p Table Offset: %X\n",
   1352                     Subtable, TableOffset);
   1353                 if (Subtable)
   1354                 {
   1355                     DbgPrint (ASL_DEBUG_OUTPUT, "12 Device Specific Offset: "
   1356                         "%X FieldName \"%s\" SubtableLength %X\n",
   1357                         DeviceDataLength, DataOffsetField->Name, Subtable->Length);
   1358 
   1359                     DeviceDataLength += Subtable->Length;
   1360 
   1361                     ParentTable = DtPeekSubtable ();
   1362                     DtInsertSubtable (ParentTable, Subtable);
   1363 
   1364                     PhatHeader->Length += (UINT16) Subtable->Length;
   1365                 }
   1366             }
   1367 
   1368             DtPopSubtable ();
   1369 
   1370             DbgPrint (ASL_DEBUG_OUTPUT, "13 FieldName: \"%s\" FieldLength: %X Field Value: %s\n",
   1371                 DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value);
   1372             break;
   1373 
   1374         default:
   1375 
   1376             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
   1377             return (AE_ERROR);
   1378         }
   1379     }
   1380 
   1381     return (Status);
   1382 }
   1383 
   1384 
   1385 /******************************************************************************
   1386  *
   1387  * FUNCTION:    DtCompilePmtt
   1388  *
   1389  * PARAMETERS:  List                - Current field list pointer
   1390  *
   1391  * RETURN:      Status
   1392  *
   1393  * DESCRIPTION: Compile PMTT.
   1394  *
   1395  *****************************************************************************/
   1396 
   1397 ACPI_STATUS
   1398 DtCompilePmtt (
   1399     void                    **List)
   1400 {
   1401     ACPI_STATUS             Status;
   1402     DT_SUBTABLE             *Subtable;
   1403     DT_SUBTABLE             *ParentTable;
   1404     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1405     DT_FIELD                *SubtableStart;
   1406     UINT16                  Type;
   1407 
   1408 
   1409     /* Main table */
   1410 
   1411     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable);
   1412     if (ACPI_FAILURE (Status))
   1413     {
   1414         return (Status);
   1415     }
   1416 
   1417     ParentTable = DtPeekSubtable ();
   1418     DtInsertSubtable (ParentTable, Subtable);
   1419     DtPushSubtable (Subtable);
   1420 
   1421     /* Subtables */
   1422 
   1423     while (*PFieldList)
   1424     {
   1425         SubtableStart = *PFieldList;
   1426         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
   1427 
   1428         switch (Type)
   1429         {
   1430         case ACPI_PMTT_TYPE_SOCKET:
   1431 
   1432             /* Subtable: Socket Structure */
   1433 
   1434             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n");
   1435 
   1436             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
   1437                 &Subtable);
   1438             if (ACPI_FAILURE (Status))
   1439             {
   1440                 return (Status);
   1441             }
   1442 
   1443             break;
   1444 
   1445         case ACPI_PMTT_TYPE_CONTROLLER:
   1446 
   1447             /* Subtable: Memory Controller Structure */
   1448 
   1449             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n");
   1450 
   1451             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
   1452                 &Subtable);
   1453             if (ACPI_FAILURE (Status))
   1454             {
   1455                 return (Status);
   1456             }
   1457 
   1458             break;
   1459 
   1460         case ACPI_PMTT_TYPE_DIMM:
   1461 
   1462             /* Subtable: Physical Component (DIMM) Structure */
   1463 
   1464             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n");
   1465             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
   1466                 &Subtable);
   1467             if (ACPI_FAILURE (Status))
   1468             {
   1469                 return (Status);
   1470             }
   1471 
   1472             break;
   1473 
   1474         case ACPI_PMTT_TYPE_VENDOR:
   1475 
   1476             /* Subtable: Vendor-specific Structure */
   1477 
   1478             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n");
   1479             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor,
   1480                 &Subtable);
   1481             if (ACPI_FAILURE (Status))
   1482             {
   1483                 return (Status);
   1484             }
   1485 
   1486             break;
   1487 
   1488         default:
   1489 
   1490             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
   1491             return (AE_ERROR);
   1492         }
   1493 
   1494         DtInsertSubtable (ParentTable, Subtable);
   1495     }
   1496 
   1497     return (Status);
   1498 }
   1499 
   1500 
   1501 /******************************************************************************
   1502  *
   1503  * FUNCTION:    DtCompilePptt
   1504  *
   1505  * PARAMETERS:  List                - Current field list pointer
   1506  *
   1507  * RETURN:      Status
   1508  *
   1509  * DESCRIPTION: Compile PPTT.
   1510  *
   1511  *****************************************************************************/
   1512 
   1513 ACPI_STATUS
   1514 DtCompilePptt (
   1515     void                    **List)
   1516 {
   1517     ACPI_STATUS             Status;
   1518     ACPI_SUBTABLE_HEADER    *PpttHeader;
   1519     ACPI_PPTT_PROCESSOR     *PpttProcessor = NULL;
   1520     DT_SUBTABLE             *Subtable;
   1521     DT_SUBTABLE             *ParentTable;
   1522     ACPI_DMTABLE_INFO       *InfoTable;
   1523     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1524     DT_FIELD                *SubtableStart;
   1525     ACPI_TABLE_HEADER       *PpttAcpiHeader;
   1526 
   1527 
   1528     ParentTable = DtPeekSubtable ();
   1529 
   1530     PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   1531 
   1532     while (*PFieldList)
   1533     {
   1534         SubtableStart = *PFieldList;
   1535 
   1536         /* Compile PPTT subtable header */
   1537 
   1538         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr,
   1539             &Subtable);
   1540         if (ACPI_FAILURE (Status))
   1541         {
   1542             return (Status);
   1543         }
   1544         DtInsertSubtable (ParentTable, Subtable);
   1545         PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
   1546         PpttHeader->Length = (UINT8)(Subtable->Length);
   1547 
   1548         switch (PpttHeader->Type)
   1549         {
   1550         case ACPI_PPTT_TYPE_PROCESSOR:
   1551 
   1552             InfoTable = AcpiDmTableInfoPptt0;
   1553             break;
   1554 
   1555         case ACPI_PPTT_TYPE_CACHE:
   1556 
   1557             if (PpttAcpiHeader->Revision < 3)
   1558             {
   1559                 InfoTable = AcpiDmTableInfoPptt1;
   1560             }
   1561             else
   1562             {
   1563                 InfoTable = AcpiDmTableInfoPptt1a;
   1564             }
   1565             break;
   1566 
   1567         case ACPI_PPTT_TYPE_ID:
   1568 
   1569             InfoTable = AcpiDmTableInfoPptt2;
   1570             break;
   1571 
   1572         default:
   1573 
   1574             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT");
   1575             return (AE_ERROR);
   1576         }
   1577 
   1578         /* Compile PPTT subtable body */
   1579 
   1580         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1581         if (ACPI_FAILURE (Status))
   1582         {
   1583             return (Status);
   1584         }
   1585         DtInsertSubtable (ParentTable, Subtable);
   1586         PpttHeader->Length += (UINT8)(Subtable->Length);
   1587 
   1588         /* Compile PPTT subtable additional */
   1589 
   1590         switch (PpttHeader->Type)
   1591         {
   1592         case ACPI_PPTT_TYPE_PROCESSOR:
   1593 
   1594             PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR,
   1595                 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER));
   1596             if (PpttProcessor)
   1597             {
   1598                 /* Compile initiator proximity domain list */
   1599 
   1600                 PpttProcessor->NumberOfPrivResources = 0;
   1601                 while (*PFieldList)
   1602                 {
   1603                     Status = DtCompileTable (PFieldList,
   1604                         AcpiDmTableInfoPptt0a, &Subtable);
   1605                     if (ACPI_FAILURE (Status))
   1606                     {
   1607                         return (Status);
   1608                     }
   1609                     if (!Subtable)
   1610                     {
   1611                         break;
   1612                     }
   1613 
   1614                     DtInsertSubtable (ParentTable, Subtable);
   1615                     PpttHeader->Length += (UINT8)(Subtable->Length);
   1616                     PpttProcessor->NumberOfPrivResources++;
   1617                 }
   1618             }
   1619             break;
   1620         default:
   1621 
   1622             break;
   1623         }
   1624     }
   1625 
   1626     return (AE_OK);
   1627 }
   1628 
   1629 
   1630 /******************************************************************************
   1631  *
   1632  * FUNCTION:    DtCompilePrmt
   1633  *
   1634  * PARAMETERS:  List                - Current field list pointer
   1635  *
   1636  * RETURN:      Status
   1637  *
   1638  * DESCRIPTION: Compile PRMT.
   1639  *
   1640  *****************************************************************************/
   1641 
   1642 ACPI_STATUS
   1643 DtCompilePrmt (
   1644     void                    **List)
   1645 {
   1646     ACPI_STATUS             Status;
   1647     ACPI_TABLE_PRMT_HEADER  *PrmtHeader;
   1648     ACPI_PRMT_MODULE_INFO   *PrmtModuleInfo;
   1649     DT_SUBTABLE             *Subtable;
   1650     DT_SUBTABLE             *ParentTable;
   1651     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1652     UINT32                  i, j;
   1653 
   1654     ParentTable = DtPeekSubtable ();
   1655 
   1656     /* Compile PRMT subtable header */
   1657 
   1658     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr,
   1659         &Subtable);
   1660     if (ACPI_FAILURE (Status))
   1661     {
   1662         return (Status);
   1663     }
   1664     DtInsertSubtable (ParentTable, Subtable);
   1665     PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer);
   1666 
   1667     for (i = 0; i < PrmtHeader->ModuleInfoCount; i++)
   1668     {
   1669         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule,
   1670             &Subtable);
   1671         if (ACPI_FAILURE (Status))
   1672         {
   1673             return (Status);
   1674         }
   1675         DtInsertSubtable (ParentTable, Subtable);
   1676         PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer);
   1677 
   1678         for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++)
   1679         {
   1680             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler,
   1681                 &Subtable);
   1682             if (ACPI_FAILURE (Status))
   1683             {
   1684                 return (Status);
   1685             }
   1686             DtInsertSubtable (ParentTable, Subtable);
   1687         }
   1688     }
   1689 
   1690     return (AE_OK);
   1691 }
   1692 
   1693 
   1694 /******************************************************************************
   1695  *
   1696  * FUNCTION:    DtCompileRas2
   1697  *
   1698  * PARAMETERS:  List                - Current field list pointer
   1699  *
   1700  * RETURN:      Status
   1701  *
   1702  * DESCRIPTION: Compile RAS2.
   1703  *
   1704  *****************************************************************************/
   1705 
   1706 ACPI_STATUS
   1707 DtCompileRas2 (
   1708     void                    **List)
   1709 {
   1710     ACPI_STATUS             Status;
   1711     DT_SUBTABLE             *Subtable;
   1712     DT_SUBTABLE             *ParentTable;
   1713     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1714     ACPI_TABLE_RAS2         *Ras2Header;
   1715     UINT32                  Count = 0;
   1716 
   1717 
   1718     /* Main table */
   1719 
   1720     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2, &Subtable);
   1721     if (ACPI_FAILURE (Status))
   1722     {
   1723         return (Status);
   1724     }
   1725 
   1726     ParentTable = DtPeekSubtable ();
   1727     DtInsertSubtable (ParentTable, Subtable);
   1728 
   1729     Ras2Header = ACPI_CAST_PTR (ACPI_TABLE_RAS2, ParentTable->Buffer);
   1730 
   1731     /* There is only one type of subtable at this time, no need to decode */
   1732 
   1733     while (*PFieldList)
   1734     {
   1735         /* List of RAS2 PCC descriptors, each 8 bytes */
   1736 
   1737         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRas2PccDesc,
   1738             &Subtable);
   1739         if (ACPI_FAILURE (Status))
   1740         {
   1741             return (Status);
   1742         }
   1743 
   1744         DtInsertSubtable (ParentTable, Subtable);
   1745         Count++;
   1746     }
   1747 
   1748     Ras2Header->NumPccDescs = (UINT8) Count;
   1749     return (AE_OK);
   1750 }
   1751 
   1752 
   1753 /******************************************************************************
   1754  *
   1755  * FUNCTION:    DtCompileRgrt
   1756  *
   1757  * PARAMETERS:  List                - Current field list pointer
   1758  *
   1759  * RETURN:      Status
   1760  *
   1761  * DESCRIPTION: Compile RGRT.
   1762  *
   1763  *****************************************************************************/
   1764 
   1765 ACPI_STATUS
   1766 DtCompileRgrt (
   1767     void                    **List)
   1768 {
   1769     ACPI_STATUS             Status;
   1770     DT_SUBTABLE             *Subtable;
   1771     DT_SUBTABLE             *ParentTable;
   1772     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1773 
   1774 
   1775     /* Compile the main table */
   1776 
   1777     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt,
   1778         &Subtable);
   1779     if (ACPI_FAILURE (Status))
   1780     {
   1781         return (Status);
   1782     }
   1783 
   1784     ParentTable = DtPeekSubtable ();
   1785     DtInsertSubtable (ParentTable, Subtable);
   1786 
   1787     /* Compile the "Subtable" -- actually just the binary (PNG) image */
   1788 
   1789     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0,
   1790         &Subtable);
   1791     if (ACPI_FAILURE (Status))
   1792     {
   1793         return (Status);
   1794     }
   1795 
   1796     DtInsertSubtable (ParentTable, Subtable);
   1797     return (AE_OK);
   1798 }
   1799 
   1800 
   1801 /******************************************************************************
   1802  *
   1803  * FUNCTION:    DtCompileRhct
   1804  *
   1805  * PARAMETERS:  List                - Current field list pointer
   1806  *
   1807  * RETURN:      Status
   1808  *
   1809  * DESCRIPTION: Compile RHCT.
   1810  *
   1811  *****************************************************************************/
   1812 
   1813 ACPI_STATUS
   1814 DtCompileRhct (
   1815     void                    **List)
   1816 {
   1817     ACPI_STATUS             Status;
   1818     ACPI_RHCT_NODE_HEADER   *RhctHeader;
   1819     ACPI_RHCT_HART_INFO     *RhctHartInfo;
   1820     DT_SUBTABLE             *Subtable;
   1821     DT_SUBTABLE             *ParentTable;
   1822     ACPI_DMTABLE_INFO       *InfoTable;
   1823     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1824     DT_FIELD                *SubtableStart;
   1825     ACPI_TABLE_RHCT         *Table;
   1826     BOOLEAN                 FirstNode = TRUE;
   1827 
   1828 
   1829     /* Compile the main table */
   1830 
   1831     ParentTable = DtPeekSubtable ();
   1832     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhct,
   1833         &Subtable);
   1834     if (ACPI_FAILURE (Status))
   1835     {
   1836         return (Status);
   1837     }
   1838     DtInsertSubtable (ParentTable, Subtable);
   1839     Table = ACPI_CAST_PTR (ACPI_TABLE_RHCT, ParentTable->Buffer);
   1840     Table->NodeCount = 0;
   1841     Table->NodeOffset = sizeof (ACPI_TABLE_RHCT);
   1842 
   1843     while (*PFieldList)
   1844     {
   1845         SubtableStart = *PFieldList;
   1846 
   1847         /* Compile RHCT subtable header */
   1848 
   1849         Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctNodeHdr,
   1850             &Subtable);
   1851         if (ACPI_FAILURE (Status))
   1852         {
   1853             return (Status);
   1854         }
   1855         DtInsertSubtable (ParentTable, Subtable);
   1856         RhctHeader = ACPI_CAST_PTR (ACPI_RHCT_NODE_HEADER, Subtable->Buffer);
   1857 
   1858         DtPushSubtable (Subtable);
   1859         ParentTable = DtPeekSubtable ();
   1860         Table->NodeCount++;
   1861 
   1862         switch (RhctHeader->Type)
   1863         {
   1864         case ACPI_RHCT_NODE_TYPE_ISA_STRING:
   1865 
   1866             InfoTable = AcpiDmTableInfoRhctIsa1;
   1867             break;
   1868 
   1869         case ACPI_RHCT_NODE_TYPE_HART_INFO:
   1870 
   1871             InfoTable = AcpiDmTableInfoRhctHartInfo1;
   1872             break;
   1873 
   1874         case ACPI_RHCT_NODE_TYPE_CMO:
   1875 
   1876             InfoTable = AcpiDmTableInfoRhctCmo1;
   1877             break;
   1878 
   1879         case ACPI_RHCT_NODE_TYPE_MMU:
   1880 
   1881             InfoTable = AcpiDmTableInfoRhctMmu1;
   1882             break;
   1883 
   1884         default:
   1885 
   1886             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RHCT");
   1887             return (AE_ERROR);
   1888         }
   1889 
   1890         /* Compile RHCT subtable body */
   1891 
   1892         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1893         if (ACPI_FAILURE (Status))
   1894         {
   1895             return (Status);
   1896         }
   1897         DtInsertSubtable (ParentTable, Subtable);
   1898         if (FirstNode)
   1899         {
   1900             Table->NodeOffset = ACPI_PTR_DIFF(ParentTable->Buffer, Table);
   1901             FirstNode = FALSE;
   1902         }
   1903 
   1904         /* Compile RHCT subtable additionals */
   1905 
   1906         switch (RhctHeader->Type)
   1907         {
   1908         case ACPI_RHCT_NODE_TYPE_ISA_STRING:
   1909 
   1910             /*
   1911              * Padding - Variable-length data
   1912              * Optionally allows the padding of the ISA string to be used
   1913              * for filling this field.
   1914              */
   1915             Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctIsaPad,
   1916                                      &Subtable);
   1917             if (ACPI_FAILURE (Status))
   1918             {
   1919                 return (Status);
   1920             }
   1921             if (Subtable)
   1922             {
   1923                 DtInsertSubtable (ParentTable, Subtable);
   1924             }
   1925             break;
   1926 
   1927         case ACPI_RHCT_NODE_TYPE_HART_INFO:
   1928 
   1929             RhctHartInfo = ACPI_CAST_PTR (ACPI_RHCT_HART_INFO,
   1930                 Subtable->Buffer);
   1931             RhctHartInfo->NumOffsets = 0;
   1932             while (*PFieldList)
   1933             {
   1934                 Status = DtCompileTable (PFieldList,
   1935                     AcpiDmTableInfoRhctHartInfo2, &Subtable);
   1936                 if (ACPI_FAILURE (Status))
   1937                 {
   1938                     return (Status);
   1939                 }
   1940                 if (!Subtable)
   1941                 {
   1942                     break;
   1943                 }
   1944                 DtInsertSubtable (ParentTable, Subtable);
   1945                 RhctHartInfo->NumOffsets++;
   1946             }
   1947             break;
   1948 
   1949         default:
   1950 
   1951             break;
   1952         }
   1953 
   1954         DtPopSubtable ();
   1955         ParentTable = DtPeekSubtable ();
   1956     }
   1957 
   1958     return (AE_OK);
   1959 }
   1960 
   1961 
   1962 /******************************************************************************
   1963  *
   1964  * FUNCTION:    DtCompileRsdt
   1965  *
   1966  * PARAMETERS:  List                - Current field list pointer
   1967  *
   1968  * RETURN:      Status
   1969  *
   1970  * DESCRIPTION: Compile RSDT.
   1971  *
   1972  *****************************************************************************/
   1973 
   1974 ACPI_STATUS
   1975 DtCompileRsdt (
   1976     void                    **List)
   1977 {
   1978     DT_SUBTABLE             *Subtable;
   1979     DT_SUBTABLE             *ParentTable;
   1980     DT_FIELD                *FieldList = *(DT_FIELD **) List;
   1981     UINT32                  Address;
   1982 
   1983 
   1984     ParentTable = DtPeekSubtable ();
   1985 
   1986     while (FieldList)
   1987     {
   1988         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
   1989 
   1990         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
   1991         DtInsertSubtable (ParentTable, Subtable);
   1992         FieldList = FieldList->Next;
   1993     }
   1994 
   1995     return (AE_OK);
   1996 }
   1997 
   1998 
   1999 /******************************************************************************
   2000  *
   2001  * FUNCTION:    DtCompileS3pt
   2002  *
   2003  * PARAMETERS:  PFieldList          - Current field list pointer
   2004  *
   2005  * RETURN:      Status
   2006  *
   2007  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
   2008  *
   2009  *****************************************************************************/
   2010 
   2011 ACPI_STATUS
   2012 DtCompileS3pt (
   2013     DT_FIELD                **PFieldList)
   2014 {
   2015     ACPI_STATUS             Status;
   2016     ACPI_FPDT_HEADER        *S3ptHeader;
   2017     DT_SUBTABLE             *Subtable;
   2018     DT_SUBTABLE             *ParentTable;
   2019     ACPI_DMTABLE_INFO       *InfoTable;
   2020     DT_FIELD                *SubtableStart;
   2021 
   2022 
   2023     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
   2024         &AslGbl_RootTable);
   2025     if (ACPI_FAILURE (Status))
   2026     {
   2027         return (Status);
   2028     }
   2029 
   2030     DtPushSubtable (AslGbl_RootTable);
   2031 
   2032     while (*PFieldList)
   2033     {
   2034         SubtableStart = *PFieldList;
   2035         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
   2036             &Subtable);
   2037         if (ACPI_FAILURE (Status))
   2038         {
   2039             return (Status);
   2040         }
   2041 
   2042         ParentTable = DtPeekSubtable ();
   2043         DtInsertSubtable (ParentTable, Subtable);
   2044         DtPushSubtable (Subtable);
   2045 
   2046         S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
   2047 
   2048         switch (S3ptHeader->Type)
   2049         {
   2050         case ACPI_S3PT_TYPE_RESUME:
   2051 
   2052             InfoTable = AcpiDmTableInfoS3pt0;
   2053             break;
   2054 
   2055         case ACPI_S3PT_TYPE_SUSPEND:
   2056 
   2057             InfoTable = AcpiDmTableInfoS3pt1;
   2058             break;
   2059 
   2060         default:
   2061 
   2062             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
   2063             return (AE_ERROR);
   2064         }
   2065 
   2066         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   2067         if (ACPI_FAILURE (Status))
   2068         {
   2069             return (Status);
   2070         }
   2071 
   2072         ParentTable = DtPeekSubtable ();
   2073         DtInsertSubtable (ParentTable, Subtable);
   2074         DtPopSubtable ();
   2075     }
   2076 
   2077     return (AE_OK);
   2078 }
   2079 
   2080 
   2081 /******************************************************************************
   2082  *
   2083  * FUNCTION:    DtCompileSdev
   2084  *
   2085  * PARAMETERS:  List                - Current field list pointer
   2086  *
   2087  * RETURN:      Status
   2088  *
   2089  * DESCRIPTION: Compile SDEV.
   2090  *
   2091  *****************************************************************************/
   2092 
   2093 ACPI_STATUS
   2094 DtCompileSdev (
   2095     void                    **List)
   2096 {
   2097     ACPI_STATUS                 Status;
   2098     ACPI_SDEV_HEADER            *SdevHeader;
   2099     ACPI_SDEV_HEADER            *SecureComponentHeader;
   2100     DT_SUBTABLE                 *Subtable;
   2101     DT_SUBTABLE                 *ParentTable;
   2102     ACPI_DMTABLE_INFO           *InfoTable;
   2103     ACPI_DMTABLE_INFO           *SecureComponentInfoTable = NULL;
   2104     DT_FIELD                    **PFieldList = (DT_FIELD **) List;
   2105     DT_FIELD                    *SubtableStart;
   2106     ACPI_SDEV_PCIE              *Pcie = NULL;
   2107     ACPI_SDEV_NAMESPACE         *Namesp = NULL;
   2108     UINT32                      EntryCount;
   2109     ACPI_SDEV_SECURE_COMPONENT  *SecureComponent = NULL;
   2110     UINT16                      ComponentLength = 0;
   2111 
   2112 
   2113     /* Subtables */
   2114 
   2115     while (*PFieldList)
   2116     {
   2117         /* Compile common SDEV subtable header */
   2118 
   2119         SubtableStart = *PFieldList;
   2120         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
   2121             &Subtable);
   2122         if (ACPI_FAILURE (Status))
   2123         {
   2124             return (Status);
   2125         }
   2126 
   2127         ParentTable = DtPeekSubtable ();
   2128         DtInsertSubtable (ParentTable, Subtable);
   2129         DtPushSubtable (Subtable);
   2130 
   2131         SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
   2132         SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
   2133 
   2134         switch (SdevHeader->Type)
   2135         {
   2136         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
   2137 
   2138             InfoTable = AcpiDmTableInfoSdev0;
   2139             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
   2140             SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
   2141                 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE)));
   2142             break;
   2143 
   2144         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
   2145 
   2146             InfoTable = AcpiDmTableInfoSdev1;
   2147             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
   2148             break;
   2149 
   2150         default:
   2151 
   2152             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
   2153             return (AE_ERROR);
   2154         }
   2155 
   2156         /* Compile SDEV subtable body */
   2157 
   2158         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   2159         if (ACPI_FAILURE (Status))
   2160         {
   2161             return (Status);
   2162         }
   2163 
   2164         ParentTable = DtPeekSubtable ();
   2165         DtInsertSubtable (ParentTable, Subtable);
   2166 
   2167         /* Optional data fields are appended to the main subtable body */
   2168 
   2169         switch (SdevHeader->Type)
   2170         {
   2171         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
   2172 
   2173             /*
   2174              * Device Id Offset will be be calculated differently depending on
   2175              * the presence of secure access components.
   2176              */
   2177             Namesp->DeviceIdOffset = 0;
   2178             ComponentLength = 0;
   2179 
   2180             /* If the secure access component exists, get the structures */
   2181 
   2182             if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
   2183             {
   2184                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b,
   2185                     &Subtable);
   2186                 if (ACPI_FAILURE (Status))
   2187                 {
   2188                     return (Status);
   2189                 }
   2190                 ParentTable = DtPeekSubtable ();
   2191                 DtInsertSubtable (ParentTable, Subtable);
   2192 
   2193                 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
   2194 
   2195                 /* Compile a secure access component header */
   2196 
   2197                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr,
   2198                     &Subtable);
   2199                 if (ACPI_FAILURE (Status))
   2200                 {
   2201                     return (Status);
   2202                 }
   2203                 ParentTable = DtPeekSubtable ();
   2204                 DtInsertSubtable (ParentTable, Subtable);
   2205 
   2206                 /* Compile the secure access component */
   2207 
   2208                 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
   2209                 switch (SecureComponentHeader->Type)
   2210                 {
   2211                 case ACPI_SDEV_TYPE_ID_COMPONENT:
   2212 
   2213                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
   2214                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT);
   2215                     ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT);
   2216                     break;
   2217 
   2218                 case ACPI_SDEV_TYPE_MEM_COMPONENT:
   2219 
   2220                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
   2221                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT);
   2222                     ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT);
   2223                     break;
   2224 
   2225                 default:
   2226 
   2227                     /* Any other secure component types are undefined */
   2228 
   2229                     return (AE_ERROR);
   2230                 }
   2231 
   2232                 Status = DtCompileTable (PFieldList, SecureComponentInfoTable,
   2233                     &Subtable);
   2234                 if (ACPI_FAILURE (Status))
   2235                 {
   2236                     return (Status);
   2237                 }
   2238                 ParentTable = DtPeekSubtable ();
   2239                 DtInsertSubtable (ParentTable, Subtable);
   2240 
   2241                 SecureComponent->SecureComponentOffset =
   2242                     sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT);
   2243                 SecureComponent->SecureComponentLength = ComponentLength;
   2244 
   2245 
   2246                 /*
   2247                  * Add the secure component to the subtable to be added for the
   2248                  * the namespace subtable's length
   2249                  */
   2250                 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT);
   2251             }
   2252 
   2253             /* Append DeviceId namespace string */
   2254 
   2255             Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
   2256                 &Subtable);
   2257             if (ACPI_FAILURE (Status))
   2258             {
   2259                 return (Status);
   2260             }
   2261 
   2262             if (!Subtable)
   2263             {
   2264                 break;
   2265             }
   2266 
   2267             ParentTable = DtPeekSubtable ();
   2268             DtInsertSubtable (ParentTable, Subtable);
   2269 
   2270             Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE);
   2271 
   2272             Namesp->DeviceIdLength = (UINT16) Subtable->Length;
   2273 
   2274             /* Append Vendor data */
   2275 
   2276             Namesp->VendorDataLength = 0;
   2277             Namesp->VendorDataOffset = 0;
   2278 
   2279             if (*PFieldList)
   2280             {
   2281                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
   2282                     &Subtable);
   2283                 if (ACPI_FAILURE (Status))
   2284                 {
   2285                     return (Status);
   2286                 }
   2287 
   2288                 if (Subtable)
   2289                 {
   2290                     ParentTable = DtPeekSubtable ();
   2291                     DtInsertSubtable (ParentTable, Subtable);
   2292 
   2293                     Namesp->VendorDataOffset =
   2294                         Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
   2295                     Namesp->VendorDataLength =
   2296                         (UINT16) Subtable->Length;
   2297 
   2298                     /* Final size of entire namespace structure */
   2299 
   2300                     SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) +
   2301                         Subtable->Length + Namesp->DeviceIdLength) + ComponentLength;
   2302                 }
   2303             }
   2304 
   2305             break;
   2306 
   2307         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
   2308 
   2309             /* Append the PCIe path info first */
   2310 
   2311             EntryCount = 0;
   2312             while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
   2313             {
   2314                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
   2315                     &Subtable);
   2316                 if (ACPI_FAILURE (Status))
   2317                 {
   2318                     return (Status);
   2319                 }
   2320 
   2321                 if (!Subtable)
   2322                 {
   2323                     DtPopSubtable ();
   2324                     break;
   2325                 }
   2326 
   2327                 ParentTable = DtPeekSubtable ();
   2328                 DtInsertSubtable (ParentTable, Subtable);
   2329                 EntryCount++;
   2330             }
   2331 
   2332             /* Path offset will point immediately after the main subtable */
   2333 
   2334             Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
   2335             Pcie->PathLength = (UINT16)
   2336                 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
   2337 
   2338             /* Append the Vendor Data last */
   2339 
   2340             Pcie->VendorDataLength = 0;
   2341             Pcie->VendorDataOffset = 0;
   2342 
   2343             if (*PFieldList)
   2344             {
   2345                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
   2346                     &Subtable);
   2347                 if (ACPI_FAILURE (Status))
   2348                 {
   2349                     return (Status);
   2350                 }
   2351 
   2352                 if (Subtable)
   2353                 {
   2354                     ParentTable = DtPeekSubtable ();
   2355                     DtInsertSubtable (ParentTable, Subtable);
   2356 
   2357                     Pcie->VendorDataOffset =
   2358                         Pcie->PathOffset + Pcie->PathLength;
   2359                     Pcie->VendorDataLength = (UINT16)
   2360                         Subtable->Length;
   2361                 }
   2362             }
   2363 
   2364             SdevHeader->Length =
   2365                 sizeof (ACPI_SDEV_PCIE) +
   2366                 Pcie->PathLength + Pcie->VendorDataLength;
   2367             break;
   2368 
   2369         default:
   2370 
   2371             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
   2372             return (AE_ERROR);
   2373         }
   2374 
   2375         DtPopSubtable ();
   2376     }
   2377 
   2378     return (AE_OK);
   2379 }
   2380 
   2381 
   2382 /******************************************************************************
   2383  *
   2384  * FUNCTION:    DtCompileSlic
   2385  *
   2386  * PARAMETERS:  List                - Current field list pointer
   2387  *
   2388  * RETURN:      Status
   2389  *
   2390  * DESCRIPTION: Compile SLIC.
   2391  *
   2392  *****************************************************************************/
   2393 
   2394 ACPI_STATUS
   2395 DtCompileSlic (
   2396     void                    **List)
   2397 {
   2398     ACPI_STATUS             Status;
   2399     DT_SUBTABLE             *Subtable;
   2400     DT_SUBTABLE             *ParentTable;
   2401     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2402 
   2403 
   2404     while (*PFieldList)
   2405     {
   2406         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
   2407             &Subtable);
   2408         if (ACPI_FAILURE (Status))
   2409         {
   2410             return (Status);
   2411         }
   2412 
   2413         ParentTable = DtPeekSubtable ();
   2414         DtInsertSubtable (ParentTable, Subtable);
   2415         DtPushSubtable (Subtable);
   2416         DtPopSubtable ();
   2417     }
   2418 
   2419     return (AE_OK);
   2420 }
   2421 
   2422 
   2423 /******************************************************************************
   2424  *
   2425  * FUNCTION:    DtCompileSlit
   2426  *
   2427  * PARAMETERS:  List                - Current field list pointer
   2428  *
   2429  * RETURN:      Status
   2430  *
   2431  * DESCRIPTION: Compile SLIT.
   2432  *
   2433  *****************************************************************************/
   2434 
   2435 ACPI_STATUS
   2436 DtCompileSlit (
   2437     void                    **List)
   2438 {
   2439     ACPI_STATUS             Status;
   2440     DT_SUBTABLE             *Subtable;
   2441     DT_SUBTABLE             *ParentTable;
   2442     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2443     DT_FIELD                *FieldList;
   2444     DT_FIELD                *EndOfFieldList = NULL;
   2445     UINT32                  Localities;
   2446     UINT32                  LocalityListLength;
   2447     UINT8                   *LocalityBuffer;
   2448 
   2449 
   2450     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
   2451         &Subtable);
   2452     if (ACPI_FAILURE (Status))
   2453     {
   2454         return (Status);
   2455     }
   2456 
   2457     ParentTable = DtPeekSubtable ();
   2458     DtInsertSubtable (ParentTable, Subtable);
   2459 
   2460     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
   2461     LocalityBuffer = UtLocalCalloc (Localities);
   2462     LocalityListLength = 0;
   2463 
   2464     /* Compile each locality buffer */
   2465 
   2466     FieldList = *PFieldList;
   2467     while (FieldList)
   2468     {
   2469         DtCompileBuffer (LocalityBuffer,
   2470             FieldList->Value, FieldList, Localities);
   2471 
   2472         LocalityListLength++;
   2473         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
   2474         DtInsertSubtable (ParentTable, Subtable);
   2475         EndOfFieldList = FieldList;
   2476         FieldList = FieldList->Next;
   2477     }
   2478 
   2479     if (LocalityListLength != Localities)
   2480     {
   2481         sprintf(AslGbl_MsgBuffer,
   2482             "Found %u entries, must match LocalityCount: %u",
   2483             LocalityListLength, Localities);
   2484         DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer);
   2485         ACPI_FREE (LocalityBuffer);
   2486         return (AE_LIMIT);
   2487     }
   2488 
   2489     ACPI_FREE (LocalityBuffer);
   2490     return (AE_OK);
   2491 }
   2492 
   2493 
   2494 /******************************************************************************
   2495  *
   2496  * FUNCTION:    DtCompileSrat
   2497  *
   2498  * PARAMETERS:  List                - Current field list pointer
   2499  *
   2500  * RETURN:      Status
   2501  *
   2502  * DESCRIPTION: Compile SRAT.
   2503  *
   2504  *****************************************************************************/
   2505 
   2506 ACPI_STATUS
   2507 DtCompileSrat (
   2508     void                    **List)
   2509 {
   2510     ACPI_STATUS             Status;
   2511     DT_SUBTABLE             *Subtable;
   2512     DT_SUBTABLE             *ParentTable;
   2513     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2514     DT_FIELD                *SubtableStart;
   2515     ACPI_SUBTABLE_HEADER    *SratHeader;
   2516     ACPI_DMTABLE_INFO       *InfoTable;
   2517 
   2518 
   2519     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
   2520         &Subtable);
   2521     if (ACPI_FAILURE (Status))
   2522     {
   2523         return (Status);
   2524     }
   2525 
   2526     ParentTable = DtPeekSubtable ();
   2527     DtInsertSubtable (ParentTable, Subtable);
   2528 
   2529     while (*PFieldList)
   2530     {
   2531         SubtableStart = *PFieldList;
   2532         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
   2533             &Subtable);
   2534         if (ACPI_FAILURE (Status))
   2535         {
   2536             return (Status);
   2537         }
   2538 
   2539         ParentTable = DtPeekSubtable ();
   2540         DtInsertSubtable (ParentTable, Subtable);
   2541         DtPushSubtable (Subtable);
   2542 
   2543         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
   2544 
   2545         switch (SratHeader->Type)
   2546         {
   2547         case ACPI_SRAT_TYPE_CPU_AFFINITY:
   2548 
   2549             InfoTable = AcpiDmTableInfoSrat0;
   2550             break;
   2551 
   2552         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
   2553 
   2554             InfoTable = AcpiDmTableInfoSrat1;
   2555             break;
   2556 
   2557         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
   2558 
   2559             InfoTable = AcpiDmTableInfoSrat2;
   2560             break;
   2561 
   2562         case ACPI_SRAT_TYPE_GICC_AFFINITY:
   2563 
   2564             InfoTable = AcpiDmTableInfoSrat3;
   2565             break;
   2566 
   2567         case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
   2568 
   2569             InfoTable = AcpiDmTableInfoSrat4;
   2570             break;
   2571 
   2572         case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
   2573 
   2574             InfoTable = AcpiDmTableInfoSrat5;
   2575             break;
   2576 
   2577         case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY:
   2578 
   2579             InfoTable = AcpiDmTableInfoSrat6;
   2580             break;
   2581 
   2582         case ACPI_SRAT_TYPE_RINTC_AFFINITY:
   2583 
   2584             InfoTable = AcpiDmTableInfoSrat7;
   2585             break;
   2586 
   2587         default:
   2588 
   2589             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
   2590             return (AE_ERROR);
   2591         }
   2592 
   2593         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   2594         if (ACPI_FAILURE (Status))
   2595         {
   2596             return (Status);
   2597         }
   2598 
   2599         ParentTable = DtPeekSubtable ();
   2600         DtInsertSubtable (ParentTable, Subtable);
   2601         DtPopSubtable ();
   2602     }
   2603 
   2604     return (AE_OK);
   2605 }
   2606 
   2607 
   2608 /******************************************************************************
   2609  *
   2610  * FUNCTION:    DtCompileStao
   2611  *
   2612  * PARAMETERS:  PFieldList          - Current field list pointer
   2613  *
   2614  * RETURN:      Status
   2615  *
   2616  * DESCRIPTION: Compile STAO.
   2617  *
   2618  *****************************************************************************/
   2619 
   2620 ACPI_STATUS
   2621 DtCompileStao (
   2622     void                    **List)
   2623 {
   2624     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2625     DT_SUBTABLE             *Subtable;
   2626     DT_SUBTABLE             *ParentTable;
   2627     ACPI_STATUS             Status;
   2628 
   2629 
   2630     /* Compile the main table */
   2631 
   2632     Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
   2633         &Subtable);
   2634     if (ACPI_FAILURE (Status))
   2635     {
   2636         return (Status);
   2637     }
   2638 
   2639     ParentTable = DtPeekSubtable ();
   2640     DtInsertSubtable (ParentTable, Subtable);
   2641 
   2642     /* Compile each ASCII namestring as a subtable */
   2643 
   2644     while (*PFieldList)
   2645     {
   2646         Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
   2647             &Subtable);
   2648         if (ACPI_FAILURE (Status))
   2649         {
   2650             return (Status);
   2651         }
   2652 
   2653         ParentTable = DtPeekSubtable ();
   2654         DtInsertSubtable (ParentTable, Subtable);
   2655     }
   2656 
   2657     return (AE_OK);
   2658 }
   2659 
   2660 
   2661 /******************************************************************************
   2662  *
   2663  * FUNCTION:    DtCompileSvkl
   2664  *
   2665  * PARAMETERS:  PFieldList          - Current field list pointer
   2666  *
   2667  * RETURN:      Status
   2668  *
   2669  * DESCRIPTION: Compile SVKL.
   2670  *
   2671  * NOTES: SVKL is essentially a flat table, with a small main table and
   2672  *          a variable number of a single type of subtable.
   2673  *
   2674  *****************************************************************************/
   2675 
   2676 ACPI_STATUS
   2677 DtCompileSvkl (
   2678     void                    **List)
   2679 {
   2680     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2681     DT_SUBTABLE             *Subtable;
   2682     DT_SUBTABLE             *ParentTable;
   2683     ACPI_STATUS             Status;
   2684 
   2685 
   2686     /* Compile the main table */
   2687 
   2688     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl,
   2689         &Subtable);
   2690     if (ACPI_FAILURE (Status))
   2691     {
   2692         return (Status);
   2693     }
   2694 
   2695     ParentTable = DtPeekSubtable ();
   2696     DtInsertSubtable (ParentTable, Subtable);
   2697 
   2698     /* Compile each subtable */
   2699 
   2700     while (*PFieldList)
   2701     {
   2702         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0,
   2703             &Subtable);
   2704         if (ACPI_FAILURE (Status))
   2705         {
   2706             return (Status);
   2707         }
   2708 
   2709         ParentTable = DtPeekSubtable ();
   2710         DtInsertSubtable (ParentTable, Subtable);
   2711     }
   2712 
   2713     return (AE_OK);
   2714 }
   2715 
   2716 
   2717 /******************************************************************************
   2718  *
   2719  * FUNCTION:    DtCompileSwft
   2720  *
   2721  * PARAMETERS:  PFieldList          - Current field list pointer
   2722  *
   2723  * RETURN:      Status
   2724  *
   2725  * DESCRIPTION: Compile SWFT.
   2726  *
   2727  *****************************************************************************/
   2728 
   2729 ACPI_STATUS
   2730 DtCompileSwft (
   2731     void                    **List)
   2732 {
   2733     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2734     DT_SUBTABLE             *HdrSub;
   2735     DT_SUBTABLE             *DataSub;
   2736     DT_SUBTABLE             *ParentTable;
   2737     ACPI_STATUS             Status;
   2738 
   2739     /* Main SWFT header */
   2740     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSwft, &HdrSub);
   2741     if (ACPI_FAILURE (Status))
   2742     {
   2743         return (Status);
   2744     }
   2745 
   2746     ParentTable = DtPeekSubtable ();
   2747     DtInsertSubtable (ParentTable, HdrSub);
   2748 
   2749     while (*PFieldList)
   2750     {
   2751         /* File header */
   2752         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSwftFileHdr,
   2753                                  &HdrSub);
   2754         if (ACPI_FAILURE (Status))
   2755         {
   2756             return (Status);
   2757         }
   2758 
   2759         DtInsertSubtable (ParentTable, HdrSub);
   2760 
   2761         /* File data */
   2762         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSwftFileData,
   2763                                  &DataSub);
   2764         if (ACPI_FAILURE (Status))
   2765         {
   2766             return (Status);
   2767         }
   2768 
   2769         DtInsertSubtable (ParentTable, DataSub);
   2770     }
   2771 
   2772     return (AE_OK);
   2773 }
   2774 
   2775 /******************************************************************************
   2776  *
   2777  * FUNCTION:    DtCompileTcpa
   2778  *
   2779  * PARAMETERS:  PFieldList          - Current field list pointer
   2780  *
   2781  * RETURN:      Status
   2782  *
   2783  * DESCRIPTION: Compile TCPA.
   2784  *
   2785  *****************************************************************************/
   2786 
   2787 ACPI_STATUS
   2788 DtCompileTcpa (
   2789     void                    **List)
   2790 {
   2791     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2792     DT_SUBTABLE             *Subtable;
   2793     ACPI_TABLE_TCPA_HDR     *TcpaHeader;
   2794     DT_SUBTABLE             *ParentTable;
   2795     ACPI_STATUS             Status;
   2796 
   2797 
   2798     /* Compile the main table */
   2799 
   2800     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
   2801         &Subtable);
   2802     if (ACPI_FAILURE (Status))
   2803     {
   2804         return (Status);
   2805     }
   2806 
   2807     ParentTable = DtPeekSubtable ();
   2808     DtInsertSubtable (ParentTable, Subtable);
   2809 
   2810     /*
   2811      * Examine the PlatformClass field to determine the table type.
   2812      * Either a client or server table. Only one.
   2813      */
   2814     TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
   2815 
   2816     switch (TcpaHeader->PlatformClass)
   2817     {
   2818     case ACPI_TCPA_CLIENT_TABLE:
   2819 
   2820         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
   2821             &Subtable);
   2822         break;
   2823 
   2824     case ACPI_TCPA_SERVER_TABLE:
   2825 
   2826         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
   2827             &Subtable);
   2828         break;
   2829 
   2830     default:
   2831 
   2832         AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
   2833             TcpaHeader->PlatformClass);
   2834         Status = AE_ERROR;
   2835         break;
   2836     }
   2837 
   2838     ParentTable = DtPeekSubtable ();
   2839     DtInsertSubtable (ParentTable, Subtable);
   2840     return (Status);
   2841 }
   2842 
   2843 
   2844 /******************************************************************************
   2845  *
   2846  * FUNCTION:    DtCompileTpm2Rev3
   2847  *
   2848  * PARAMETERS:  PFieldList          - Current field list pointer
   2849  *
   2850  * RETURN:      Status
   2851  *
   2852  * DESCRIPTION: Compile TPM2 revision 3
   2853  *
   2854  *****************************************************************************/
   2855 static ACPI_STATUS
   2856 DtCompileTpm2Rev3 (
   2857     void                    **List)
   2858 {
   2859     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2860     DT_SUBTABLE             *Subtable;
   2861     ACPI_TABLE_TPM23        *Tpm23Header;
   2862     DT_SUBTABLE             *ParentTable;
   2863     ACPI_STATUS             Status = AE_OK;
   2864 
   2865 
   2866     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23,
   2867         &Subtable);
   2868 
   2869     ParentTable = DtPeekSubtable ();
   2870     DtInsertSubtable (ParentTable, Subtable);
   2871     Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer);
   2872 
   2873     /* Subtable type depends on the StartMethod */
   2874 
   2875     switch (Tpm23Header->StartMethod)
   2876     {
   2877     case ACPI_TPM23_ACPI_START_METHOD:
   2878 
   2879         /* Subtable specific to to ARM_SMC */
   2880 
   2881         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a,
   2882             &Subtable);
   2883         if (ACPI_FAILURE (Status))
   2884         {
   2885             return (Status);
   2886         }
   2887 
   2888         ParentTable = DtPeekSubtable ();
   2889         DtInsertSubtable (ParentTable, Subtable);
   2890         break;
   2891 
   2892     default:
   2893         break;
   2894     }
   2895 
   2896     return (Status);
   2897 }
   2898 
   2899 
   2900 /******************************************************************************
   2901  *
   2902  * FUNCTION:    DtCompileTpm2
   2903  *
   2904  * PARAMETERS:  PFieldList          - Current field list pointer
   2905  *
   2906  * RETURN:      Status
   2907  *
   2908  * DESCRIPTION: Compile TPM2.
   2909  *
   2910  *****************************************************************************/
   2911 
   2912 ACPI_STATUS
   2913 DtCompileTpm2 (
   2914     void                    **List)
   2915 {
   2916     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2917     DT_SUBTABLE             *Subtable;
   2918     ACPI_TABLE_TPM2         *Tpm2Header;
   2919     DT_SUBTABLE             *ParentTable;
   2920     ACPI_STATUS             Status = AE_OK;
   2921     ACPI_TABLE_HEADER       *Header;
   2922 
   2923 
   2924     ParentTable = DtPeekSubtable ();
   2925 
   2926     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   2927 
   2928     if (Header->Revision == 3)
   2929     {
   2930         return (DtCompileTpm2Rev3 (List));
   2931     }
   2932 
   2933     /* Compile the main table */
   2934 
   2935     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
   2936         &Subtable);
   2937     if (ACPI_FAILURE (Status))
   2938     {
   2939         return (Status);
   2940     }
   2941 
   2942     ParentTable = DtPeekSubtable ();
   2943     DtInsertSubtable (ParentTable, Subtable);
   2944 
   2945     Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
   2946 
   2947     /* Method parameters */
   2948     /* Optional: Log area minimum length */
   2949     /* Optional: Log area start address */
   2950     /* TBD: Optional fields above not fully implemented (not optional at this time) */
   2951 
   2952     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
   2953         &Subtable);
   2954     if (ACPI_FAILURE (Status))
   2955     {
   2956         return (Status);
   2957     }
   2958 
   2959     ParentTable = DtPeekSubtable ();
   2960     DtInsertSubtable (ParentTable, Subtable);
   2961 
   2962 
   2963     /* Subtable type depends on the StartMethod */
   2964 
   2965     switch (Tpm2Header->StartMethod)
   2966     {
   2967     case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
   2968 
   2969         /* Subtable specific to to ARM_SMC */
   2970 
   2971         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
   2972             &Subtable);
   2973         if (ACPI_FAILURE (Status))
   2974         {
   2975             return (Status);
   2976         }
   2977 
   2978         ParentTable = DtPeekSubtable ();
   2979         DtInsertSubtable (ParentTable, Subtable);
   2980         break;
   2981 
   2982     case ACPI_TPM2_START_METHOD:
   2983     case ACPI_TPM2_MEMORY_MAPPED:
   2984     case ACPI_TPM2_COMMAND_BUFFER:
   2985     case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
   2986         break;
   2987 
   2988     case ACPI_TPM2_RESERVED1:
   2989     case ACPI_TPM2_RESERVED3:
   2990     case ACPI_TPM2_RESERVED4:
   2991     case ACPI_TPM2_RESERVED5:
   2992     case ACPI_TPM2_RESERVED9:
   2993     case ACPI_TPM2_RESERVED10:
   2994 
   2995         AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
   2996             Tpm2Header->StartMethod);
   2997         Status = AE_ERROR;
   2998         break;
   2999 
   3000     case ACPI_TPM2_NOT_ALLOWED:
   3001     default:
   3002 
   3003         AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
   3004             Tpm2Header->StartMethod);
   3005         Status = AE_ERROR;
   3006         break;
   3007     }
   3008 
   3009     return (Status);
   3010 }
   3011 
   3012 
   3013 /******************************************************************************
   3014  *
   3015  * FUNCTION:    DtGetGenericTableInfo
   3016  *
   3017  * PARAMETERS:  Name                - Generic type name
   3018  *
   3019  * RETURN:      Info entry
   3020  *
   3021  * DESCRIPTION: Obtain table info for a generic name entry
   3022  *
   3023  *****************************************************************************/
   3024 
   3025 ACPI_DMTABLE_INFO *
   3026 DtGetGenericTableInfo (
   3027     char                    *Name)
   3028 {
   3029     ACPI_DMTABLE_INFO       *Info;
   3030     UINT32                  i;
   3031 
   3032 
   3033     if (!Name)
   3034     {
   3035         return (NULL);
   3036     }
   3037 
   3038     /* Search info table for name match */
   3039 
   3040     for (i = 0; ; i++)
   3041     {
   3042         Info = AcpiDmTableInfoGeneric[i];
   3043         if (Info->Opcode == ACPI_DMT_EXIT)
   3044         {
   3045             Info = NULL;
   3046             break;
   3047         }
   3048 
   3049         /* Use caseless compare for generic keywords */
   3050 
   3051         if (!AcpiUtStricmp (Name, Info->Name))
   3052         {
   3053             break;
   3054         }
   3055     }
   3056 
   3057     return (Info);
   3058 }
   3059 
   3060 
   3061 /******************************************************************************
   3062  *
   3063  * FUNCTION:    DtCompileUefi
   3064  *
   3065  * PARAMETERS:  List                - Current field list pointer
   3066  *
   3067  * RETURN:      Status
   3068  *
   3069  * DESCRIPTION: Compile UEFI.
   3070  *
   3071  *****************************************************************************/
   3072 
   3073 ACPI_STATUS
   3074 DtCompileUefi (
   3075     void                    **List)
   3076 {
   3077     ACPI_STATUS             Status;
   3078     DT_SUBTABLE             *Subtable;
   3079     DT_SUBTABLE             *ParentTable;
   3080     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   3081     UINT16                  *DataOffset;
   3082 
   3083 
   3084     /* Compile the predefined portion of the UEFI table */
   3085 
   3086     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
   3087         &Subtable);
   3088     if (ACPI_FAILURE (Status))
   3089     {
   3090         return (Status);
   3091     }
   3092 
   3093     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
   3094     *DataOffset = sizeof (ACPI_TABLE_UEFI);
   3095 
   3096     ParentTable = DtPeekSubtable ();
   3097     DtInsertSubtable (ParentTable, Subtable);
   3098 
   3099     /*
   3100      * Compile the "generic" portion of the UEFI table. This
   3101      * part of the table is not predefined and any of the generic
   3102      * operators may be used.
   3103      */
   3104     DtCompileGeneric ((void **) PFieldList, NULL, NULL);
   3105     return (AE_OK);
   3106 }
   3107 
   3108 
   3109 /******************************************************************************
   3110  *
   3111  * FUNCTION:    DtCompileViot
   3112  *
   3113  * PARAMETERS:  List                - Current field list pointer
   3114  *
   3115  * RETURN:      Status
   3116  *
   3117  * DESCRIPTION: Compile VIOT.
   3118  *
   3119  *****************************************************************************/
   3120 
   3121 ACPI_STATUS
   3122 DtCompileViot (
   3123     void                    **List)
   3124 {
   3125     ACPI_STATUS             Status;
   3126     DT_SUBTABLE             *Subtable;
   3127     DT_SUBTABLE             *ParentTable;
   3128     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   3129     DT_FIELD                *SubtableStart;
   3130     ACPI_TABLE_VIOT         *Viot;
   3131     ACPI_VIOT_HEADER        *ViotHeader;
   3132     ACPI_DMTABLE_INFO       *InfoTable;
   3133     UINT16                  NodeCount;
   3134 
   3135     ParentTable = DtPeekSubtable ();
   3136 
   3137     Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable);
   3138     if (ACPI_FAILURE (Status))
   3139     {
   3140         return (Status);
   3141     }
   3142     DtInsertSubtable (ParentTable, Subtable);
   3143 
   3144     /*
   3145      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   3146      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
   3147      */
   3148     Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer,
   3149         sizeof (ACPI_TABLE_HEADER));
   3150 
   3151     Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT);
   3152 
   3153     NodeCount = 0;
   3154     while (*PFieldList) {
   3155         SubtableStart = *PFieldList;
   3156         Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader,
   3157             &Subtable);
   3158         if (ACPI_FAILURE (Status))
   3159         {
   3160             return (Status);
   3161         }
   3162 
   3163         ParentTable = DtPeekSubtable ();
   3164         DtInsertSubtable (ParentTable, Subtable);
   3165         DtPushSubtable (Subtable);
   3166 
   3167         ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer);
   3168 
   3169         switch (ViotHeader->Type)
   3170         {
   3171         case ACPI_VIOT_NODE_PCI_RANGE:
   3172 
   3173             InfoTable = AcpiDmTableInfoViot1;
   3174             break;
   3175 
   3176         case ACPI_VIOT_NODE_MMIO:
   3177 
   3178             InfoTable = AcpiDmTableInfoViot2;
   3179             break;
   3180 
   3181         case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI:
   3182 
   3183             InfoTable = AcpiDmTableInfoViot3;
   3184             break;
   3185 
   3186         case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO:
   3187 
   3188             InfoTable = AcpiDmTableInfoViot4;
   3189             break;
   3190 
   3191         default:
   3192 
   3193             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT");
   3194             return (AE_ERROR);
   3195         }
   3196 
   3197         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   3198         if (ACPI_FAILURE (Status))
   3199         {
   3200             return (Status);
   3201         }
   3202 
   3203         ParentTable = DtPeekSubtable ();
   3204         DtInsertSubtable (ParentTable, Subtable);
   3205         DtPopSubtable ();
   3206         NodeCount++;
   3207     }
   3208 
   3209     Viot->NodeCount = NodeCount;
   3210     return (AE_OK);
   3211 }
   3212 
   3213 
   3214 /******************************************************************************
   3215  *
   3216  * FUNCTION:    DtCompileWdat
   3217  *
   3218  * PARAMETERS:  List                - Current field list pointer
   3219  *
   3220  * RETURN:      Status
   3221  *
   3222  * DESCRIPTION: Compile WDAT.
   3223  *
   3224  *****************************************************************************/
   3225 
   3226 ACPI_STATUS
   3227 DtCompileWdat (
   3228     void                    **List)
   3229 {
   3230     ACPI_STATUS             Status;
   3231 
   3232 
   3233     Status = DtCompileTwoSubtables (List,
   3234         AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
   3235     return (Status);
   3236 }
   3237 
   3238 
   3239 /******************************************************************************
   3240  *
   3241  * FUNCTION:    DtCompileWpbt
   3242  *
   3243  * PARAMETERS:  List                - Current field list pointer
   3244  *
   3245  * RETURN:      Status
   3246  *
   3247  * DESCRIPTION: Compile WPBT.
   3248  *
   3249  *****************************************************************************/
   3250 
   3251 ACPI_STATUS
   3252 DtCompileWpbt (
   3253     void                    **List)
   3254 {
   3255     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   3256     DT_SUBTABLE             *Subtable;
   3257     DT_SUBTABLE             *ParentTable;
   3258     ACPI_TABLE_WPBT         *Table;
   3259     ACPI_STATUS             Status;
   3260 
   3261 
   3262     /* Compile the main table */
   3263 
   3264     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable);
   3265     if (ACPI_FAILURE (Status))
   3266     {
   3267         return (Status);
   3268     }
   3269 
   3270     ParentTable = DtPeekSubtable ();
   3271     DtInsertSubtable (ParentTable, Subtable);
   3272     Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
   3273 
   3274     /*
   3275      * Exit now if there are no arguments specified. This is indicated by:
   3276      * The "Command-line Arguments" field has not been specified (if specified,
   3277      * it will be the last field in the field list -- after the main table).
   3278      * Set the Argument Length in the main table to zero.
   3279      */
   3280     if (!*PFieldList)
   3281     {
   3282         Table->ArgumentsLength = 0;
   3283         return (AE_OK);
   3284     }
   3285 
   3286     /* Compile the argument list subtable */
   3287 
   3288     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable);
   3289     if (ACPI_FAILURE (Status))
   3290     {
   3291         return (Status);
   3292     }
   3293 
   3294     /* Extract the length of the Arguments buffer, insert into main table */
   3295 
   3296     Table->ArgumentsLength = (UINT16) Subtable->TotalLength;
   3297     DtInsertSubtable (ParentTable, Subtable);
   3298     return (AE_OK);
   3299 }
   3300 
   3301 
   3302 /******************************************************************************
   3303  *
   3304  * FUNCTION:    DtCompileXsdt
   3305  *
   3306  * PARAMETERS:  List                - Current field list pointer
   3307  *
   3308  * RETURN:      Status
   3309  *
   3310  * DESCRIPTION: Compile XSDT.
   3311  *
   3312  *****************************************************************************/
   3313 
   3314 ACPI_STATUS
   3315 DtCompileXsdt (
   3316     void                    **List)
   3317 {
   3318     DT_SUBTABLE             *Subtable;
   3319     DT_SUBTABLE             *ParentTable;
   3320     DT_FIELD                *FieldList = *(DT_FIELD **) List;
   3321     UINT64                  Address;
   3322 
   3323 
   3324     ParentTable = DtPeekSubtable ();
   3325 
   3326     while (FieldList)
   3327     {
   3328         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
   3329 
   3330         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
   3331         DtInsertSubtable (ParentTable, Subtable);
   3332         FieldList = FieldList->Next;
   3333     }
   3334 
   3335     return (AE_OK);
   3336 }
   3337 
   3338 
   3339 /******************************************************************************
   3340  *
   3341  * FUNCTION:    DtCompileGeneric
   3342  *
   3343  * PARAMETERS:  List                - Current field list pointer
   3344  *              Name                - Field name to end generic compiling
   3345  *              Length              - Compiled table length to return
   3346  *
   3347  * RETURN:      Status
   3348  *
   3349  * DESCRIPTION: Compile generic unknown table.
   3350  *
   3351  *****************************************************************************/
   3352 
   3353 ACPI_STATUS
   3354 DtCompileGeneric (
   3355     void                    **List,
   3356     char                    *Name,
   3357     UINT32                  *Length)
   3358 {
   3359     ACPI_STATUS             Status;
   3360     DT_SUBTABLE             *Subtable;
   3361     DT_SUBTABLE             *ParentTable;
   3362     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   3363     ACPI_DMTABLE_INFO       *Info;
   3364 
   3365 
   3366     ParentTable = DtPeekSubtable ();
   3367 
   3368     /*
   3369      * Compile the "generic" portion of the table. This
   3370      * part of the table is not predefined and any of the generic
   3371      * operators may be used.
   3372      */
   3373 
   3374     /* Find any and all labels in the entire generic portion */
   3375 
   3376     DtDetectAllLabels (*PFieldList);
   3377 
   3378     /* Now we can actually compile the parse tree */
   3379 
   3380     if (Length && *Length)
   3381     {
   3382         *Length = 0;
   3383     }
   3384     while (*PFieldList)
   3385     {
   3386         if (Name && !strcmp ((*PFieldList)->Name, Name))
   3387         {
   3388             break;
   3389         }
   3390 
   3391         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
   3392         if (!Info)
   3393         {
   3394             sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
   3395                 (*PFieldList)->Name);
   3396             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
   3397                 (*PFieldList), AslGbl_MsgBuffer);
   3398 
   3399             *PFieldList = (*PFieldList)->Next;
   3400             continue;
   3401         }
   3402 
   3403         Status = DtCompileTable (PFieldList, Info,
   3404             &Subtable);
   3405         if (ACPI_SUCCESS (Status))
   3406         {
   3407             DtInsertSubtable (ParentTable, Subtable);
   3408             if (Length)
   3409             {
   3410                 *Length += Subtable->Length;
   3411             }
   3412         }
   3413         else
   3414         {
   3415             *PFieldList = (*PFieldList)->Next;
   3416 
   3417             if (Status == AE_NOT_FOUND)
   3418             {
   3419                 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
   3420                     (*PFieldList)->Name);
   3421                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
   3422                     (*PFieldList), AslGbl_MsgBuffer);
   3423             }
   3424         }
   3425     }
   3426 
   3427     return (AE_OK);
   3428 }
   3429