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