Home | History | Annotate | Line # | Download | only in compiler
dttable2.c revision 1.1.1.13
      1 /******************************************************************************
      2  *
      3  * Module Name: dttable2.c - handling for specific ACPI tables
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2021, 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         default:
    267 
    268             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT");
    269             return (AE_ERROR);
    270         }
    271 
    272         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    273         if (ACPI_FAILURE (Status))
    274         {
    275             return (Status);
    276         }
    277 
    278         ParentTable = DtPeekSubtable ();
    279         DtInsertSubtable (ParentTable, Subtable);
    280         DtPopSubtable ();
    281     }
    282 
    283     return (AE_OK);
    284 }
    285 
    286 
    287 /******************************************************************************
    288  *
    289  * FUNCTION:    DtCompileMcfg
    290  *
    291  * PARAMETERS:  List                - Current field list pointer
    292  *
    293  * RETURN:      Status
    294  *
    295  * DESCRIPTION: Compile MCFG.
    296  *
    297  *****************************************************************************/
    298 
    299 ACPI_STATUS
    300 DtCompileMcfg (
    301     void                    **List)
    302 {
    303     ACPI_STATUS             Status;
    304 
    305 
    306     Status = DtCompileTwoSubtables (List,
    307         AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0);
    308     return (Status);
    309 }
    310 
    311 
    312 /******************************************************************************
    313  *
    314  * FUNCTION:    DtCompileMpst
    315  *
    316  * PARAMETERS:  List                - Current field list pointer
    317  *
    318  * RETURN:      Status
    319  *
    320  * DESCRIPTION: Compile MPST.
    321  *
    322  *****************************************************************************/
    323 
    324 ACPI_STATUS
    325 DtCompileMpst (
    326     void                    **List)
    327 {
    328     ACPI_STATUS             Status;
    329     DT_SUBTABLE             *Subtable;
    330     DT_SUBTABLE             *ParentTable;
    331     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    332     ACPI_MPST_CHANNEL       *MpstChannelInfo;
    333     ACPI_MPST_POWER_NODE    *MpstPowerNode;
    334     ACPI_MPST_DATA_HDR      *MpstDataHeader;
    335     UINT16                  SubtableCount;
    336     UINT32                  PowerStateCount;
    337     UINT32                  ComponentCount;
    338 
    339 
    340     /* Main table */
    341 
    342     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable);
    343     if (ACPI_FAILURE (Status))
    344     {
    345         return (Status);
    346     }
    347 
    348     ParentTable = DtPeekSubtable ();
    349     DtInsertSubtable (ParentTable, Subtable);
    350     DtPushSubtable (Subtable);
    351 
    352     MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer);
    353     SubtableCount = MpstChannelInfo->PowerNodeCount;
    354 
    355     while (*PFieldList && SubtableCount)
    356     {
    357         /* Subtable: Memory Power Node(s) */
    358 
    359         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0,
    360             &Subtable);
    361         if (ACPI_FAILURE (Status))
    362         {
    363             return (Status);
    364         }
    365 
    366         ParentTable = DtPeekSubtable ();
    367         DtInsertSubtable (ParentTable, Subtable);
    368         DtPushSubtable (Subtable);
    369 
    370         MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer);
    371         PowerStateCount = MpstPowerNode->NumPowerStates;
    372         ComponentCount = MpstPowerNode->NumPhysicalComponents;
    373 
    374         ParentTable = DtPeekSubtable ();
    375 
    376         /* Sub-subtables - Memory Power State Structure(s) */
    377 
    378         while (*PFieldList && PowerStateCount)
    379         {
    380             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A,
    381                 &Subtable);
    382             if (ACPI_FAILURE (Status))
    383             {
    384                 return (Status);
    385             }
    386 
    387             DtInsertSubtable (ParentTable, Subtable);
    388             PowerStateCount--;
    389         }
    390 
    391         /* Sub-subtables - Physical Component ID Structure(s) */
    392 
    393         while (*PFieldList && ComponentCount)
    394         {
    395             Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B,
    396                 &Subtable);
    397             if (ACPI_FAILURE (Status))
    398             {
    399                 return (Status);
    400             }
    401 
    402             DtInsertSubtable (ParentTable, Subtable);
    403             ComponentCount--;
    404         }
    405 
    406         SubtableCount--;
    407         DtPopSubtable ();
    408     }
    409 
    410     /* Subtable: Count of Memory Power State Characteristic structures */
    411 
    412     DtPopSubtable ();
    413 
    414     Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable);
    415     if (ACPI_FAILURE (Status))
    416     {
    417         return (Status);
    418     }
    419 
    420     ParentTable = DtPeekSubtable ();
    421     DtInsertSubtable (ParentTable, Subtable);
    422     DtPushSubtable (Subtable);
    423 
    424     MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer);
    425     SubtableCount = MpstDataHeader->CharacteristicsCount;
    426 
    427     ParentTable = DtPeekSubtable ();
    428 
    429     /* Subtable: Memory Power State Characteristics structure(s) */
    430 
    431     while (*PFieldList && SubtableCount)
    432     {
    433         Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2,
    434             &Subtable);
    435         if (ACPI_FAILURE (Status))
    436         {
    437             return (Status);
    438         }
    439 
    440         DtInsertSubtable (ParentTable, Subtable);
    441         SubtableCount--;
    442     }
    443 
    444     DtPopSubtable ();
    445     return (AE_OK);
    446 }
    447 
    448 
    449 /******************************************************************************
    450  *
    451  * FUNCTION:    DtCompileMsct
    452  *
    453  * PARAMETERS:  List                - Current field list pointer
    454  *
    455  * RETURN:      Status
    456  *
    457  * DESCRIPTION: Compile MSCT.
    458  *
    459  *****************************************************************************/
    460 
    461 ACPI_STATUS
    462 DtCompileMsct (
    463     void                    **List)
    464 {
    465     ACPI_STATUS             Status;
    466 
    467 
    468     Status = DtCompileTwoSubtables (List,
    469         AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0);
    470     return (Status);
    471 }
    472 
    473 
    474 /******************************************************************************
    475  *
    476  * FUNCTION:    DtCompileNfit
    477  *
    478  * PARAMETERS:  List                - Current field list pointer
    479  *
    480  * RETURN:      Status
    481  *
    482  * DESCRIPTION: Compile NFIT.
    483  *
    484  *****************************************************************************/
    485 
    486 ACPI_STATUS
    487 DtCompileNfit (
    488     void                    **List)
    489 {
    490     ACPI_STATUS             Status;
    491     DT_SUBTABLE             *Subtable;
    492     DT_SUBTABLE             *ParentTable;
    493     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    494     DT_FIELD                *SubtableStart;
    495     ACPI_NFIT_HEADER        *NfitHeader;
    496     ACPI_DMTABLE_INFO       *InfoTable;
    497     UINT32                  Count;
    498     ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
    499     ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
    500 
    501 
    502     /* Main table */
    503 
    504     Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit,
    505         &Subtable);
    506     if (ACPI_FAILURE (Status))
    507     {
    508         return (Status);
    509     }
    510 
    511     ParentTable = DtPeekSubtable ();
    512     DtInsertSubtable (ParentTable, Subtable);
    513     DtPushSubtable (Subtable);
    514 
    515     /* Subtables */
    516 
    517     while (*PFieldList)
    518     {
    519         SubtableStart = *PFieldList;
    520         Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr,
    521             &Subtable);
    522         if (ACPI_FAILURE (Status))
    523         {
    524             return (Status);
    525         }
    526 
    527         ParentTable = DtPeekSubtable ();
    528         DtInsertSubtable (ParentTable, Subtable);
    529         DtPushSubtable (Subtable);
    530 
    531         NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer);
    532 
    533         switch (NfitHeader->Type)
    534         {
    535         case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
    536 
    537             InfoTable = AcpiDmTableInfoNfit0;
    538             break;
    539 
    540         case ACPI_NFIT_TYPE_MEMORY_MAP:
    541 
    542             InfoTable = AcpiDmTableInfoNfit1;
    543             break;
    544 
    545         case ACPI_NFIT_TYPE_INTERLEAVE:
    546 
    547             Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer);
    548             InfoTable = AcpiDmTableInfoNfit2;
    549             break;
    550 
    551         case ACPI_NFIT_TYPE_SMBIOS:
    552 
    553             InfoTable = AcpiDmTableInfoNfit3;
    554             break;
    555 
    556         case ACPI_NFIT_TYPE_CONTROL_REGION:
    557 
    558             InfoTable = AcpiDmTableInfoNfit4;
    559             break;
    560 
    561         case ACPI_NFIT_TYPE_DATA_REGION:
    562 
    563             InfoTable = AcpiDmTableInfoNfit5;
    564             break;
    565 
    566         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
    567 
    568             Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer);
    569             InfoTable = AcpiDmTableInfoNfit6;
    570             break;
    571 
    572         case ACPI_NFIT_TYPE_CAPABILITIES:
    573 
    574             InfoTable = AcpiDmTableInfoNfit7;
    575             break;
    576 
    577         default:
    578 
    579             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT");
    580             return (AE_ERROR);
    581         }
    582 
    583         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    584         if (ACPI_FAILURE (Status))
    585         {
    586             return (Status);
    587         }
    588 
    589         ParentTable = DtPeekSubtable ();
    590         DtInsertSubtable (ParentTable, Subtable);
    591         DtPopSubtable ();
    592 
    593         switch (NfitHeader->Type)
    594         {
    595         case ACPI_NFIT_TYPE_INTERLEAVE:
    596 
    597             Count = 0;
    598             DtPushSubtable (Subtable);
    599             while (*PFieldList)
    600             {
    601                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a,
    602                     &Subtable);
    603                 if (ACPI_FAILURE (Status))
    604                 {
    605                     return (Status);
    606                 }
    607 
    608                 if (!Subtable)
    609                 {
    610                     DtPopSubtable ();
    611                     break;
    612                 }
    613 
    614                 ParentTable = DtPeekSubtable ();
    615                 DtInsertSubtable (ParentTable, Subtable);
    616                 Count++;
    617             }
    618 
    619             Interleave->LineCount = Count;
    620             break;
    621 
    622         case ACPI_NFIT_TYPE_SMBIOS:
    623 
    624             if (*PFieldList)
    625             {
    626                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a,
    627                     &Subtable);
    628                 if (ACPI_FAILURE (Status))
    629                 {
    630                     return (Status);
    631                 }
    632 
    633                 if (Subtable)
    634                 {
    635                     DtInsertSubtable (ParentTable, Subtable);
    636                 }
    637             }
    638             break;
    639 
    640         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
    641 
    642             Count = 0;
    643             DtPushSubtable (Subtable);
    644             while (*PFieldList)
    645             {
    646                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a,
    647                     &Subtable);
    648                 if (ACPI_FAILURE (Status))
    649                 {
    650                     return (Status);
    651                 }
    652 
    653                 if (!Subtable)
    654                 {
    655                     DtPopSubtable ();
    656                     break;
    657                 }
    658 
    659                 ParentTable = DtPeekSubtable ();
    660                 DtInsertSubtable (ParentTable, Subtable);
    661                 Count++;
    662             }
    663 
    664             Hint->HintCount = (UINT16) Count;
    665             break;
    666 
    667         default:
    668             break;
    669         }
    670     }
    671 
    672     return (AE_OK);
    673 }
    674 
    675 
    676 /******************************************************************************
    677  *
    678  * FUNCTION:    DtCompilePcct
    679  *
    680  * PARAMETERS:  List                - Current field list pointer
    681  *
    682  * RETURN:      Status
    683  *
    684  * DESCRIPTION: Compile PCCT.
    685  *
    686  *****************************************************************************/
    687 
    688 ACPI_STATUS
    689 DtCompilePcct (
    690     void                    **List)
    691 {
    692     ACPI_STATUS             Status;
    693     DT_SUBTABLE             *Subtable;
    694     DT_SUBTABLE             *ParentTable;
    695     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    696     DT_FIELD                *SubtableStart;
    697     ACPI_SUBTABLE_HEADER    *PcctHeader;
    698     ACPI_DMTABLE_INFO       *InfoTable;
    699 
    700 
    701     /* Main table */
    702 
    703     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct,
    704         &Subtable);
    705     if (ACPI_FAILURE (Status))
    706     {
    707         return (Status);
    708     }
    709 
    710     ParentTable = DtPeekSubtable ();
    711     DtInsertSubtable (ParentTable, Subtable);
    712 
    713     /* Subtables */
    714 
    715     while (*PFieldList)
    716     {
    717         SubtableStart = *PFieldList;
    718         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr,
    719             &Subtable);
    720         if (ACPI_FAILURE (Status))
    721         {
    722             return (Status);
    723         }
    724 
    725         ParentTable = DtPeekSubtable ();
    726         DtInsertSubtable (ParentTable, Subtable);
    727         DtPushSubtable (Subtable);
    728 
    729         PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
    730 
    731         switch (PcctHeader->Type)
    732         {
    733         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
    734 
    735             InfoTable = AcpiDmTableInfoPcct0;
    736             break;
    737 
    738         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
    739 
    740             InfoTable = AcpiDmTableInfoPcct1;
    741             break;
    742 
    743         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
    744 
    745             InfoTable = AcpiDmTableInfoPcct2;
    746             break;
    747 
    748         case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
    749 
    750             InfoTable = AcpiDmTableInfoPcct3;
    751             break;
    752 
    753         case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
    754 
    755             InfoTable = AcpiDmTableInfoPcct4;
    756             break;
    757 
    758         case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE:
    759 
    760             InfoTable = AcpiDmTableInfoPcct5;
    761             break;
    762 
    763         default:
    764 
    765             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT");
    766             return (AE_ERROR);
    767         }
    768 
    769         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
    770         if (ACPI_FAILURE (Status))
    771         {
    772             return (Status);
    773         }
    774 
    775         ParentTable = DtPeekSubtable ();
    776         DtInsertSubtable (ParentTable, Subtable);
    777         DtPopSubtable ();
    778     }
    779 
    780     return (AE_OK);
    781 }
    782 
    783 
    784 /******************************************************************************
    785  *
    786  * FUNCTION:    DtCompilePdtt
    787  *
    788  * PARAMETERS:  List                - Current field list pointer
    789  *
    790  * RETURN:      Status
    791  *
    792  * DESCRIPTION: Compile PDTT.
    793  *
    794  *****************************************************************************/
    795 
    796 ACPI_STATUS
    797 DtCompilePdtt (
    798     void                    **List)
    799 {
    800     ACPI_STATUS             Status;
    801     DT_SUBTABLE             *Subtable;
    802     DT_SUBTABLE             *ParentTable;
    803     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    804     ACPI_TABLE_PDTT         *PdttHeader;
    805     UINT32                  Count = 0;
    806 
    807 
    808     /* Main table */
    809 
    810     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable);
    811     if (ACPI_FAILURE (Status))
    812     {
    813         return (Status);
    814     }
    815 
    816     ParentTable = DtPeekSubtable ();
    817     DtInsertSubtable (ParentTable, Subtable);
    818 
    819     PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer);
    820     PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT);
    821 
    822     /* There is only one type of subtable at this time, no need to decode */
    823 
    824     while (*PFieldList)
    825     {
    826         /* List of subchannel IDs, each 2 bytes */
    827 
    828         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0,
    829             &Subtable);
    830         if (ACPI_FAILURE (Status))
    831         {
    832             return (Status);
    833         }
    834 
    835         DtInsertSubtable (ParentTable, Subtable);
    836         Count++;
    837     }
    838 
    839     PdttHeader->TriggerCount = (UINT8) Count;
    840     return (AE_OK);
    841 }
    842 
    843 
    844 /******************************************************************************
    845  *
    846  * FUNCTION:    DtCompilePhat
    847  *
    848  * PARAMETERS:  List                - Current field list pointer
    849  *
    850  * RETURN:      Status
    851  *
    852  * DESCRIPTION: Compile Phat.
    853  *
    854  *****************************************************************************/
    855 
    856 ACPI_STATUS
    857 DtCompilePhat (
    858     void                    **List)
    859 {
    860     ACPI_STATUS             Status = AE_OK;
    861     DT_SUBTABLE             *Subtable;
    862     DT_SUBTABLE             *ParentTable;
    863     DT_FIELD                **PFieldList = (DT_FIELD **) List;
    864     ACPI_PHAT_HEADER        *PhatHeader;
    865     ACPI_DMTABLE_INFO       *Info;
    866     ACPI_PHAT_VERSION_DATA  *VersionData;
    867     UINT32                  RecordCount;
    868 
    869 
    870     /* The table consist of subtables */
    871 
    872     while (*PFieldList)
    873     {
    874         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable);
    875         if (ACPI_FAILURE (Status))
    876         {
    877             return (Status);
    878         }
    879 
    880         ParentTable = DtPeekSubtable ();
    881         DtInsertSubtable (ParentTable, Subtable);
    882         DtPushSubtable (Subtable);
    883 
    884         PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer);
    885 
    886         switch (PhatHeader->Type)
    887         {
    888         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
    889 
    890             Info = AcpiDmTableInfoPhat0;
    891             PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA);
    892             break;
    893 
    894         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
    895 
    896             Info = AcpiDmTableInfoPhat1;
    897             PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA);
    898             break;
    899 
    900         default:
    901 
    902             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
    903             return (AE_ERROR);
    904 
    905             break;
    906         }
    907 
    908         Status = DtCompileTable (PFieldList, Info, &Subtable);
    909         if (ACPI_FAILURE (Status))
    910         {
    911             return (Status);
    912         }
    913 
    914         ParentTable = DtPeekSubtable ();
    915         DtInsertSubtable (ParentTable, Subtable);
    916 
    917         switch (PhatHeader->Type)
    918         {
    919         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
    920 
    921             VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA,
    922                 (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER)));
    923             RecordCount = VersionData->ElementCount;
    924 
    925             while (RecordCount)
    926             {
    927                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a,
    928                     &Subtable);
    929                 if (ACPI_FAILURE (Status))
    930                 {
    931                     return (Status);
    932                 }
    933                 ParentTable = DtPeekSubtable ();
    934                 DtInsertSubtable (ParentTable, Subtable);
    935 
    936                 RecordCount--;
    937                 PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT);
    938             }
    939             break;
    940 
    941         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
    942 
    943             /* Compile device path */
    944 
    945             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable);
    946             if (ACPI_FAILURE (Status))
    947             {
    948                 return (Status);
    949             }
    950             ParentTable = DtPeekSubtable ();
    951             DtInsertSubtable (ParentTable, Subtable);
    952 
    953             PhatHeader->Length += (UINT16) Subtable->Length;
    954 
    955             /* Compile vendor specific data */
    956 
    957             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable);
    958             if (ACPI_FAILURE (Status))
    959             {
    960                 return (Status);
    961             }
    962             ParentTable = DtPeekSubtable ();
    963             DtInsertSubtable (ParentTable, Subtable);
    964 
    965             PhatHeader->Length += (UINT16) Subtable->Length;
    966 
    967             break;
    968 
    969         default:
    970 
    971             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT");
    972             return (AE_ERROR);
    973         }
    974     }
    975 
    976     return (Status);
    977 }
    978 
    979 
    980 /******************************************************************************
    981  *
    982  * FUNCTION:    DtCompilePmtt
    983  *
    984  * PARAMETERS:  List                - Current field list pointer
    985  *
    986  * RETURN:      Status
    987  *
    988  * DESCRIPTION: Compile PMTT.
    989  *
    990  *****************************************************************************/
    991 
    992 ACPI_STATUS
    993 DtCompilePmtt (
    994     void                    **List)
    995 {
    996     ACPI_STATUS             Status;
    997     DT_SUBTABLE             *Subtable;
    998     DT_SUBTABLE             *ParentTable;
    999     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1000     DT_FIELD                *SubtableStart;
   1001     UINT16                  Type;
   1002 
   1003 
   1004     /* Main table */
   1005 
   1006     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable);
   1007     if (ACPI_FAILURE (Status))
   1008     {
   1009         return (Status);
   1010     }
   1011 
   1012     ParentTable = DtPeekSubtable ();
   1013     DtInsertSubtable (ParentTable, Subtable);
   1014     DtPushSubtable (Subtable);
   1015 
   1016     /* Subtables */
   1017 
   1018     while (*PFieldList)
   1019     {
   1020         SubtableStart = *PFieldList;
   1021         DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0);
   1022 
   1023         switch (Type)
   1024         {
   1025         case ACPI_PMTT_TYPE_SOCKET:
   1026 
   1027             /* Subtable: Socket Structure */
   1028 
   1029             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n");
   1030 
   1031             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0,
   1032                 &Subtable);
   1033             if (ACPI_FAILURE (Status))
   1034             {
   1035                 return (Status);
   1036             }
   1037 
   1038             break;
   1039 
   1040         case ACPI_PMTT_TYPE_CONTROLLER:
   1041 
   1042             /* Subtable: Memory Controller Structure */
   1043 
   1044             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n");
   1045 
   1046             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1,
   1047                 &Subtable);
   1048             if (ACPI_FAILURE (Status))
   1049             {
   1050                 return (Status);
   1051             }
   1052 
   1053             break;
   1054 
   1055         case ACPI_PMTT_TYPE_DIMM:
   1056 
   1057             /* Subtable: Physical Component (DIMM) Structure */
   1058 
   1059             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n");
   1060             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2,
   1061                 &Subtable);
   1062             if (ACPI_FAILURE (Status))
   1063             {
   1064                 return (Status);
   1065             }
   1066 
   1067             break;
   1068 
   1069         case ACPI_PMTT_TYPE_VENDOR:
   1070 
   1071             /* Subtable: Vendor-specific Structure */
   1072 
   1073             DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n");
   1074             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor,
   1075                 &Subtable);
   1076             if (ACPI_FAILURE (Status))
   1077             {
   1078                 return (Status);
   1079             }
   1080 
   1081             break;
   1082 
   1083         default:
   1084 
   1085             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT");
   1086             return (AE_ERROR);
   1087         }
   1088 
   1089         DtInsertSubtable (ParentTable, Subtable);
   1090     }
   1091 
   1092     return (Status);
   1093 }
   1094 
   1095 
   1096 /******************************************************************************
   1097  *
   1098  * FUNCTION:    DtCompilePptt
   1099  *
   1100  * PARAMETERS:  List                - Current field list pointer
   1101  *
   1102  * RETURN:      Status
   1103  *
   1104  * DESCRIPTION: Compile PPTT.
   1105  *
   1106  *****************************************************************************/
   1107 
   1108 ACPI_STATUS
   1109 DtCompilePptt (
   1110     void                    **List)
   1111 {
   1112     ACPI_STATUS             Status;
   1113     ACPI_SUBTABLE_HEADER    *PpttHeader;
   1114     ACPI_PPTT_PROCESSOR     *PpttProcessor = NULL;
   1115     DT_SUBTABLE             *Subtable;
   1116     DT_SUBTABLE             *ParentTable;
   1117     ACPI_DMTABLE_INFO       *InfoTable;
   1118     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1119     DT_FIELD                *SubtableStart;
   1120     ACPI_TABLE_HEADER       *PpttAcpiHeader;
   1121 
   1122 
   1123     ParentTable = DtPeekSubtable ();
   1124     while (*PFieldList)
   1125     {
   1126         SubtableStart = *PFieldList;
   1127 
   1128         /* Compile PPTT subtable header */
   1129 
   1130         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr,
   1131             &Subtable);
   1132         if (ACPI_FAILURE (Status))
   1133         {
   1134             return (Status);
   1135         }
   1136         DtInsertSubtable (ParentTable, Subtable);
   1137         PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
   1138         PpttHeader->Length = (UINT8)(Subtable->Length);
   1139 
   1140         switch (PpttHeader->Type)
   1141         {
   1142         case ACPI_PPTT_TYPE_PROCESSOR:
   1143 
   1144             InfoTable = AcpiDmTableInfoPptt0;
   1145             break;
   1146 
   1147         case ACPI_PPTT_TYPE_CACHE:
   1148 
   1149             InfoTable = AcpiDmTableInfoPptt1;
   1150             break;
   1151 
   1152         case ACPI_PPTT_TYPE_ID:
   1153 
   1154             InfoTable = AcpiDmTableInfoPptt2;
   1155             break;
   1156 
   1157         default:
   1158 
   1159             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT");
   1160             return (AE_ERROR);
   1161         }
   1162 
   1163         /* Compile PPTT subtable body */
   1164 
   1165         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1166         if (ACPI_FAILURE (Status))
   1167         {
   1168             return (Status);
   1169         }
   1170         DtInsertSubtable (ParentTable, Subtable);
   1171         PpttHeader->Length += (UINT8)(Subtable->Length);
   1172 
   1173         /* Compile PPTT subtable additionals */
   1174 
   1175         switch (PpttHeader->Type)
   1176         {
   1177         case ACPI_PPTT_TYPE_PROCESSOR:
   1178 
   1179             PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR,
   1180                 Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER));
   1181             if (PpttProcessor)
   1182             {
   1183                 /* Compile initiator proximity domain list */
   1184 
   1185                 PpttProcessor->NumberOfPrivResources = 0;
   1186                 while (*PFieldList)
   1187                 {
   1188                     Status = DtCompileTable (PFieldList,
   1189                         AcpiDmTableInfoPptt0a, &Subtable);
   1190                     if (ACPI_FAILURE (Status))
   1191                     {
   1192                         return (Status);
   1193                     }
   1194                     if (!Subtable)
   1195                     {
   1196                         break;
   1197                     }
   1198 
   1199                     DtInsertSubtable (ParentTable, Subtable);
   1200                     PpttHeader->Length += (UINT8)(Subtable->Length);
   1201                     PpttProcessor->NumberOfPrivResources++;
   1202                 }
   1203             }
   1204             break;
   1205 
   1206         case ACPI_PPTT_TYPE_CACHE:
   1207 
   1208             PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
   1209                 AslGbl_RootTable->Buffer);
   1210             if (PpttAcpiHeader->Revision < 3)
   1211             {
   1212                 break;
   1213             }
   1214             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a,
   1215                 &Subtable);
   1216             DtInsertSubtable (ParentTable, Subtable);
   1217             PpttHeader->Length += (UINT8)(Subtable->Length);
   1218             break;
   1219 
   1220         default:
   1221 
   1222             break;
   1223         }
   1224     }
   1225 
   1226     return (AE_OK);
   1227 }
   1228 
   1229 
   1230 /******************************************************************************
   1231  *
   1232  * FUNCTION:    DtCompilePrmt
   1233  *
   1234  * PARAMETERS:  List                - Current field list pointer
   1235  *
   1236  * RETURN:      Status
   1237  *
   1238  * DESCRIPTION: Compile PRMT.
   1239  *
   1240  *****************************************************************************/
   1241 
   1242 ACPI_STATUS
   1243 DtCompilePrmt (
   1244     void                    **List)
   1245 {
   1246     ACPI_STATUS             Status;
   1247     ACPI_TABLE_PRMT_HEADER  *PrmtHeader;
   1248     ACPI_PRMT_MODULE_INFO   *PrmtModuleInfo;
   1249     DT_SUBTABLE             *Subtable;
   1250     DT_SUBTABLE             *ParentTable;
   1251     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1252     UINT32                  i, j;
   1253 
   1254     ParentTable = DtPeekSubtable ();
   1255 
   1256     /* Compile PRMT subtable header */
   1257 
   1258     Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr,
   1259         &Subtable);
   1260     if (ACPI_FAILURE (Status))
   1261     {
   1262         return (Status);
   1263     }
   1264     DtInsertSubtable (ParentTable, Subtable);
   1265     PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer);
   1266 
   1267     for (i = 0; i < PrmtHeader->ModuleInfoCount; i++)
   1268     {
   1269         Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule,
   1270             &Subtable);
   1271         if (ACPI_FAILURE (Status))
   1272         {
   1273             return (Status);
   1274         }
   1275         DtInsertSubtable (ParentTable, Subtable);
   1276         PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer);
   1277 
   1278         for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++)
   1279         {
   1280             Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler,
   1281                 &Subtable);
   1282             if (ACPI_FAILURE (Status))
   1283             {
   1284                 return (Status);
   1285             }
   1286             DtInsertSubtable (ParentTable, Subtable);
   1287         }
   1288     }
   1289 
   1290     return (AE_OK);
   1291 }
   1292 
   1293 
   1294 /******************************************************************************
   1295  *
   1296  * FUNCTION:    DtCompileRgrt
   1297  *
   1298  * PARAMETERS:  List                - Current field list pointer
   1299  *
   1300  * RETURN:      Status
   1301  *
   1302  * DESCRIPTION: Compile RGRT.
   1303  *
   1304  *****************************************************************************/
   1305 
   1306 ACPI_STATUS
   1307 DtCompileRgrt (
   1308     void                    **List)
   1309 {
   1310     ACPI_STATUS             Status;
   1311     DT_SUBTABLE             *Subtable;
   1312     DT_SUBTABLE             *ParentTable;
   1313     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1314 
   1315 
   1316     /* Compile the main table */
   1317 
   1318     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt,
   1319         &Subtable);
   1320     if (ACPI_FAILURE (Status))
   1321     {
   1322         return (Status);
   1323     }
   1324 
   1325     ParentTable = DtPeekSubtable ();
   1326     DtInsertSubtable (ParentTable, Subtable);
   1327 
   1328     /* Compile the "Subtable" -- actually just the binary (PNG) image */
   1329 
   1330     Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0,
   1331         &Subtable);
   1332     if (ACPI_FAILURE (Status))
   1333     {
   1334         return (Status);
   1335     }
   1336 
   1337     DtInsertSubtable (ParentTable, Subtable);
   1338     return (AE_OK);
   1339 }
   1340 
   1341 
   1342 /******************************************************************************
   1343  *
   1344  * FUNCTION:    DtCompileRsdt
   1345  *
   1346  * PARAMETERS:  List                - Current field list pointer
   1347  *
   1348  * RETURN:      Status
   1349  *
   1350  * DESCRIPTION: Compile RSDT.
   1351  *
   1352  *****************************************************************************/
   1353 
   1354 ACPI_STATUS
   1355 DtCompileRsdt (
   1356     void                    **List)
   1357 {
   1358     DT_SUBTABLE             *Subtable;
   1359     DT_SUBTABLE             *ParentTable;
   1360     DT_FIELD                *FieldList = *(DT_FIELD **) List;
   1361     UINT32                  Address;
   1362 
   1363 
   1364     ParentTable = DtPeekSubtable ();
   1365 
   1366     while (FieldList)
   1367     {
   1368         DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO);
   1369 
   1370         DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable);
   1371         DtInsertSubtable (ParentTable, Subtable);
   1372         FieldList = FieldList->Next;
   1373     }
   1374 
   1375     return (AE_OK);
   1376 }
   1377 
   1378 
   1379 /******************************************************************************
   1380  *
   1381  * FUNCTION:    DtCompileS3pt
   1382  *
   1383  * PARAMETERS:  PFieldList          - Current field list pointer
   1384  *
   1385  * RETURN:      Status
   1386  *
   1387  * DESCRIPTION: Compile S3PT (Pointed to by FPDT)
   1388  *
   1389  *****************************************************************************/
   1390 
   1391 ACPI_STATUS
   1392 DtCompileS3pt (
   1393     DT_FIELD                **PFieldList)
   1394 {
   1395     ACPI_STATUS             Status;
   1396     ACPI_FPDT_HEADER        *S3ptHeader;
   1397     DT_SUBTABLE             *Subtable;
   1398     DT_SUBTABLE             *ParentTable;
   1399     ACPI_DMTABLE_INFO       *InfoTable;
   1400     DT_FIELD                *SubtableStart;
   1401 
   1402 
   1403     Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt,
   1404         &AslGbl_RootTable);
   1405     if (ACPI_FAILURE (Status))
   1406     {
   1407         return (Status);
   1408     }
   1409 
   1410     DtPushSubtable (AslGbl_RootTable);
   1411 
   1412     while (*PFieldList)
   1413     {
   1414         SubtableStart = *PFieldList;
   1415         Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr,
   1416             &Subtable);
   1417         if (ACPI_FAILURE (Status))
   1418         {
   1419             return (Status);
   1420         }
   1421 
   1422         ParentTable = DtPeekSubtable ();
   1423         DtInsertSubtable (ParentTable, Subtable);
   1424         DtPushSubtable (Subtable);
   1425 
   1426         S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer);
   1427 
   1428         switch (S3ptHeader->Type)
   1429         {
   1430         case ACPI_S3PT_TYPE_RESUME:
   1431 
   1432             InfoTable = AcpiDmTableInfoS3pt0;
   1433             break;
   1434 
   1435         case ACPI_S3PT_TYPE_SUSPEND:
   1436 
   1437             InfoTable = AcpiDmTableInfoS3pt1;
   1438             break;
   1439 
   1440         default:
   1441 
   1442             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT");
   1443             return (AE_ERROR);
   1444         }
   1445 
   1446         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1447         if (ACPI_FAILURE (Status))
   1448         {
   1449             return (Status);
   1450         }
   1451 
   1452         ParentTable = DtPeekSubtable ();
   1453         DtInsertSubtable (ParentTable, Subtable);
   1454         DtPopSubtable ();
   1455     }
   1456 
   1457     return (AE_OK);
   1458 }
   1459 
   1460 
   1461 /******************************************************************************
   1462  *
   1463  * FUNCTION:    DtCompileSdev
   1464  *
   1465  * PARAMETERS:  List                - Current field list pointer
   1466  *
   1467  * RETURN:      Status
   1468  *
   1469  * DESCRIPTION: Compile SDEV.
   1470  *
   1471  *****************************************************************************/
   1472 
   1473 ACPI_STATUS
   1474 DtCompileSdev (
   1475     void                    **List)
   1476 {
   1477     ACPI_STATUS                 Status;
   1478     ACPI_SDEV_HEADER            *SdevHeader;
   1479     ACPI_SDEV_HEADER            *SecureComponentHeader;
   1480     DT_SUBTABLE                 *Subtable;
   1481     DT_SUBTABLE                 *ParentTable;
   1482     ACPI_DMTABLE_INFO           *InfoTable;
   1483     ACPI_DMTABLE_INFO           *SecureComponentInfoTable = NULL;
   1484     DT_FIELD                    **PFieldList = (DT_FIELD **) List;
   1485     DT_FIELD                    *SubtableStart;
   1486     ACPI_SDEV_PCIE              *Pcie = NULL;
   1487     ACPI_SDEV_NAMESPACE         *Namesp = NULL;
   1488     UINT32                      EntryCount;
   1489     ACPI_SDEV_SECURE_COMPONENT  *SecureComponent = NULL;
   1490     UINT16                      ComponentLength = 0;
   1491 
   1492 
   1493     /* Subtables */
   1494 
   1495     while (*PFieldList)
   1496     {
   1497         /* Compile common SDEV subtable header */
   1498 
   1499         SubtableStart = *PFieldList;
   1500         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr,
   1501             &Subtable);
   1502         if (ACPI_FAILURE (Status))
   1503         {
   1504             return (Status);
   1505         }
   1506 
   1507         ParentTable = DtPeekSubtable ();
   1508         DtInsertSubtable (ParentTable, Subtable);
   1509         DtPushSubtable (Subtable);
   1510 
   1511         SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
   1512         SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER));
   1513 
   1514         switch (SdevHeader->Type)
   1515         {
   1516         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
   1517 
   1518             InfoTable = AcpiDmTableInfoSdev0;
   1519             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer);
   1520             SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
   1521                 ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE)));
   1522             break;
   1523 
   1524         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
   1525 
   1526             InfoTable = AcpiDmTableInfoSdev1;
   1527             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer);
   1528             break;
   1529 
   1530         default:
   1531 
   1532             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
   1533             return (AE_ERROR);
   1534         }
   1535 
   1536         /* Compile SDEV subtable body */
   1537 
   1538         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1539         if (ACPI_FAILURE (Status))
   1540         {
   1541             return (Status);
   1542         }
   1543 
   1544         ParentTable = DtPeekSubtable ();
   1545         DtInsertSubtable (ParentTable, Subtable);
   1546 
   1547         /* Optional data fields are appended to the main subtable body */
   1548 
   1549         switch (SdevHeader->Type)
   1550         {
   1551         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
   1552 
   1553             /*
   1554              * Device Id Offset will be be calculated differently depending on
   1555              * the presence of secure access components.
   1556              */
   1557             Namesp->DeviceIdOffset = 0;
   1558             ComponentLength = 0;
   1559 
   1560             /* If the secure access component exists, get the structures */
   1561 
   1562             if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
   1563             {
   1564                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b,
   1565                     &Subtable);
   1566                 if (ACPI_FAILURE (Status))
   1567                 {
   1568                     return (Status);
   1569                 }
   1570                 ParentTable = DtPeekSubtable ();
   1571                 DtInsertSubtable (ParentTable, Subtable);
   1572 
   1573                 Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
   1574 
   1575                 /* Compile a secure access component header */
   1576 
   1577                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr,
   1578                     &Subtable);
   1579                 if (ACPI_FAILURE (Status))
   1580                 {
   1581                     return (Status);
   1582                 }
   1583                 ParentTable = DtPeekSubtable ();
   1584                 DtInsertSubtable (ParentTable, Subtable);
   1585 
   1586                 /* Compile the secure access component */
   1587 
   1588                 SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer);
   1589                 switch (SecureComponentHeader->Type)
   1590                 {
   1591                 case ACPI_SDEV_TYPE_ID_COMPONENT:
   1592 
   1593                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
   1594                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT);
   1595                     ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT);
   1596                     break;
   1597 
   1598                 case ACPI_SDEV_TYPE_MEM_COMPONENT:
   1599 
   1600                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
   1601                     Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT);
   1602                     ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT);
   1603                     break;
   1604 
   1605                 default:
   1606 
   1607                     /* Any other secure component types are undefined */
   1608 
   1609                     return (AE_ERROR);
   1610                 }
   1611 
   1612                 Status = DtCompileTable (PFieldList, SecureComponentInfoTable,
   1613                     &Subtable);
   1614                 if (ACPI_FAILURE (Status))
   1615                 {
   1616                     return (Status);
   1617                 }
   1618                 ParentTable = DtPeekSubtable ();
   1619                 DtInsertSubtable (ParentTable, Subtable);
   1620 
   1621                 SecureComponent->SecureComponentOffset =
   1622                     sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT);
   1623                 SecureComponent->SecureComponentLength = ComponentLength;
   1624 
   1625 
   1626                 /*
   1627                  * Add the secure component to the subtable to be added for the
   1628                  * the namespace subtable's length
   1629                  */
   1630                 ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT);
   1631             }
   1632 
   1633             /* Append DeviceId namespace string */
   1634 
   1635             Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a,
   1636                 &Subtable);
   1637             if (ACPI_FAILURE (Status))
   1638             {
   1639                 return (Status);
   1640             }
   1641 
   1642             if (!Subtable)
   1643             {
   1644                 break;
   1645             }
   1646 
   1647             ParentTable = DtPeekSubtable ();
   1648             DtInsertSubtable (ParentTable, Subtable);
   1649 
   1650             Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE);
   1651 
   1652             Namesp->DeviceIdLength = (UINT16) Subtable->Length;
   1653 
   1654             /* Append Vendor data */
   1655 
   1656             Namesp->VendorDataLength = 0;
   1657             Namesp->VendorDataOffset = 0;
   1658 
   1659             if (*PFieldList)
   1660             {
   1661                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
   1662                     &Subtable);
   1663                 if (ACPI_FAILURE (Status))
   1664                 {
   1665                     return (Status);
   1666                 }
   1667 
   1668                 if (Subtable)
   1669                 {
   1670                     ParentTable = DtPeekSubtable ();
   1671                     DtInsertSubtable (ParentTable, Subtable);
   1672 
   1673                     Namesp->VendorDataOffset =
   1674                         Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
   1675                     Namesp->VendorDataLength =
   1676                         (UINT16) Subtable->Length;
   1677 
   1678                     /* Final size of entire namespace structure */
   1679 
   1680                     SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) +
   1681                         Subtable->Length + Namesp->DeviceIdLength) + ComponentLength;
   1682                 }
   1683             }
   1684 
   1685             break;
   1686 
   1687         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
   1688 
   1689             /* Append the PCIe path info first */
   1690 
   1691             EntryCount = 0;
   1692             while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device"))
   1693             {
   1694                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a,
   1695                     &Subtable);
   1696                 if (ACPI_FAILURE (Status))
   1697                 {
   1698                     return (Status);
   1699                 }
   1700 
   1701                 if (!Subtable)
   1702                 {
   1703                     DtPopSubtable ();
   1704                     break;
   1705                 }
   1706 
   1707                 ParentTable = DtPeekSubtable ();
   1708                 DtInsertSubtable (ParentTable, Subtable);
   1709                 EntryCount++;
   1710             }
   1711 
   1712             /* Path offset will point immediately after the main subtable */
   1713 
   1714             Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE);
   1715             Pcie->PathLength = (UINT16)
   1716                 (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH));
   1717 
   1718             /* Append the Vendor Data last */
   1719 
   1720             Pcie->VendorDataLength = 0;
   1721             Pcie->VendorDataOffset = 0;
   1722 
   1723             if (*PFieldList)
   1724             {
   1725                 Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b,
   1726                     &Subtable);
   1727                 if (ACPI_FAILURE (Status))
   1728                 {
   1729                     return (Status);
   1730                 }
   1731 
   1732                 if (Subtable)
   1733                 {
   1734                     ParentTable = DtPeekSubtable ();
   1735                     DtInsertSubtable (ParentTable, Subtable);
   1736 
   1737                     Pcie->VendorDataOffset =
   1738                         Pcie->PathOffset + Pcie->PathLength;
   1739                     Pcie->VendorDataLength = (UINT16)
   1740                         Subtable->Length;
   1741                 }
   1742             }
   1743 
   1744             SdevHeader->Length =
   1745                 sizeof (ACPI_SDEV_PCIE) +
   1746                 Pcie->PathLength + Pcie->VendorDataLength;
   1747             break;
   1748 
   1749         default:
   1750 
   1751             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV");
   1752             return (AE_ERROR);
   1753         }
   1754 
   1755         DtPopSubtable ();
   1756     }
   1757 
   1758     return (AE_OK);
   1759 }
   1760 
   1761 
   1762 /******************************************************************************
   1763  *
   1764  * FUNCTION:    DtCompileSlic
   1765  *
   1766  * PARAMETERS:  List                - Current field list pointer
   1767  *
   1768  * RETURN:      Status
   1769  *
   1770  * DESCRIPTION: Compile SLIC.
   1771  *
   1772  *****************************************************************************/
   1773 
   1774 ACPI_STATUS
   1775 DtCompileSlic (
   1776     void                    **List)
   1777 {
   1778     ACPI_STATUS             Status;
   1779     DT_SUBTABLE             *Subtable;
   1780     DT_SUBTABLE             *ParentTable;
   1781     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1782 
   1783 
   1784     while (*PFieldList)
   1785     {
   1786         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic,
   1787             &Subtable);
   1788         if (ACPI_FAILURE (Status))
   1789         {
   1790             return (Status);
   1791         }
   1792 
   1793         ParentTable = DtPeekSubtable ();
   1794         DtInsertSubtable (ParentTable, Subtable);
   1795         DtPushSubtable (Subtable);
   1796         DtPopSubtable ();
   1797     }
   1798 
   1799     return (AE_OK);
   1800 }
   1801 
   1802 
   1803 /******************************************************************************
   1804  *
   1805  * FUNCTION:    DtCompileSlit
   1806  *
   1807  * PARAMETERS:  List                - Current field list pointer
   1808  *
   1809  * RETURN:      Status
   1810  *
   1811  * DESCRIPTION: Compile SLIT.
   1812  *
   1813  *****************************************************************************/
   1814 
   1815 ACPI_STATUS
   1816 DtCompileSlit (
   1817     void                    **List)
   1818 {
   1819     ACPI_STATUS             Status;
   1820     DT_SUBTABLE             *Subtable;
   1821     DT_SUBTABLE             *ParentTable;
   1822     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1823     DT_FIELD                *FieldList;
   1824     DT_FIELD                *EndOfFieldList = NULL;
   1825     UINT32                  Localities;
   1826     UINT32                  LocalityListLength;
   1827     UINT8                   *LocalityBuffer;
   1828 
   1829 
   1830     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit,
   1831         &Subtable);
   1832     if (ACPI_FAILURE (Status))
   1833     {
   1834         return (Status);
   1835     }
   1836 
   1837     ParentTable = DtPeekSubtable ();
   1838     DtInsertSubtable (ParentTable, Subtable);
   1839 
   1840     Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
   1841     LocalityBuffer = UtLocalCalloc (Localities);
   1842     LocalityListLength = 0;
   1843 
   1844     /* Compile each locality buffer */
   1845 
   1846     FieldList = *PFieldList;
   1847     while (FieldList)
   1848     {
   1849         DtCompileBuffer (LocalityBuffer,
   1850             FieldList->Value, FieldList, Localities);
   1851 
   1852         LocalityListLength++;
   1853         DtCreateSubtable (LocalityBuffer, Localities, &Subtable);
   1854         DtInsertSubtable (ParentTable, Subtable);
   1855         EndOfFieldList = FieldList;
   1856         FieldList = FieldList->Next;
   1857     }
   1858 
   1859     if (LocalityListLength != Localities)
   1860     {
   1861         sprintf(AslGbl_MsgBuffer,
   1862             "Found %u entries, must match LocalityCount: %u",
   1863             LocalityListLength, Localities);
   1864         DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer);
   1865         ACPI_FREE (LocalityBuffer);
   1866         return (AE_LIMIT);
   1867     }
   1868 
   1869     ACPI_FREE (LocalityBuffer);
   1870     return (AE_OK);
   1871 }
   1872 
   1873 
   1874 /******************************************************************************
   1875  *
   1876  * FUNCTION:    DtCompileSrat
   1877  *
   1878  * PARAMETERS:  List                - Current field list pointer
   1879  *
   1880  * RETURN:      Status
   1881  *
   1882  * DESCRIPTION: Compile SRAT.
   1883  *
   1884  *****************************************************************************/
   1885 
   1886 ACPI_STATUS
   1887 DtCompileSrat (
   1888     void                    **List)
   1889 {
   1890     ACPI_STATUS             Status;
   1891     DT_SUBTABLE             *Subtable;
   1892     DT_SUBTABLE             *ParentTable;
   1893     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   1894     DT_FIELD                *SubtableStart;
   1895     ACPI_SUBTABLE_HEADER    *SratHeader;
   1896     ACPI_DMTABLE_INFO       *InfoTable;
   1897 
   1898 
   1899     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat,
   1900         &Subtable);
   1901     if (ACPI_FAILURE (Status))
   1902     {
   1903         return (Status);
   1904     }
   1905 
   1906     ParentTable = DtPeekSubtable ();
   1907     DtInsertSubtable (ParentTable, Subtable);
   1908 
   1909     while (*PFieldList)
   1910     {
   1911         SubtableStart = *PFieldList;
   1912         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr,
   1913             &Subtable);
   1914         if (ACPI_FAILURE (Status))
   1915         {
   1916             return (Status);
   1917         }
   1918 
   1919         ParentTable = DtPeekSubtable ();
   1920         DtInsertSubtable (ParentTable, Subtable);
   1921         DtPushSubtable (Subtable);
   1922 
   1923         SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer);
   1924 
   1925         switch (SratHeader->Type)
   1926         {
   1927         case ACPI_SRAT_TYPE_CPU_AFFINITY:
   1928 
   1929             InfoTable = AcpiDmTableInfoSrat0;
   1930             break;
   1931 
   1932         case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
   1933 
   1934             InfoTable = AcpiDmTableInfoSrat1;
   1935             break;
   1936 
   1937         case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
   1938 
   1939             InfoTable = AcpiDmTableInfoSrat2;
   1940             break;
   1941 
   1942         case ACPI_SRAT_TYPE_GICC_AFFINITY:
   1943 
   1944             InfoTable = AcpiDmTableInfoSrat3;
   1945             break;
   1946 
   1947         case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
   1948 
   1949             InfoTable = AcpiDmTableInfoSrat4;
   1950             break;
   1951 
   1952         case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
   1953 
   1954             InfoTable = AcpiDmTableInfoSrat5;
   1955             break;
   1956 
   1957         case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY:
   1958 
   1959             InfoTable = AcpiDmTableInfoSrat6;
   1960             break;
   1961 
   1962         default:
   1963 
   1964             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
   1965             return (AE_ERROR);
   1966         }
   1967 
   1968         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   1969         if (ACPI_FAILURE (Status))
   1970         {
   1971             return (Status);
   1972         }
   1973 
   1974         ParentTable = DtPeekSubtable ();
   1975         DtInsertSubtable (ParentTable, Subtable);
   1976         DtPopSubtable ();
   1977     }
   1978 
   1979     return (AE_OK);
   1980 }
   1981 
   1982 
   1983 /******************************************************************************
   1984  *
   1985  * FUNCTION:    DtCompileStao
   1986  *
   1987  * PARAMETERS:  PFieldList          - Current field list pointer
   1988  *
   1989  * RETURN:      Status
   1990  *
   1991  * DESCRIPTION: Compile STAO.
   1992  *
   1993  *****************************************************************************/
   1994 
   1995 ACPI_STATUS
   1996 DtCompileStao (
   1997     void                    **List)
   1998 {
   1999     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2000     DT_SUBTABLE             *Subtable;
   2001     DT_SUBTABLE             *ParentTable;
   2002     ACPI_STATUS             Status;
   2003 
   2004 
   2005     /* Compile the main table */
   2006 
   2007     Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao,
   2008         &Subtable);
   2009     if (ACPI_FAILURE (Status))
   2010     {
   2011         return (Status);
   2012     }
   2013 
   2014     ParentTable = DtPeekSubtable ();
   2015     DtInsertSubtable (ParentTable, Subtable);
   2016 
   2017     /* Compile each ASCII namestring as a subtable */
   2018 
   2019     while (*PFieldList)
   2020     {
   2021         Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr,
   2022             &Subtable);
   2023         if (ACPI_FAILURE (Status))
   2024         {
   2025             return (Status);
   2026         }
   2027 
   2028         ParentTable = DtPeekSubtable ();
   2029         DtInsertSubtable (ParentTable, Subtable);
   2030     }
   2031 
   2032     return (AE_OK);
   2033 }
   2034 
   2035 
   2036 
   2037 /******************************************************************************
   2038  *
   2039  * FUNCTION:    DtCompileSvkl
   2040  *
   2041  * PARAMETERS:  PFieldList          - Current field list pointer
   2042  *
   2043  * RETURN:      Status
   2044  *
   2045  * DESCRIPTION: Compile SVKL.
   2046  *
   2047  * NOTES: SVKL is essentially a flat table, with a small main table and
   2048  *          a variable number of a single type of subtable.
   2049  *
   2050  *****************************************************************************/
   2051 
   2052 ACPI_STATUS
   2053 DtCompileSvkl (
   2054     void                    **List)
   2055 {
   2056     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2057     DT_SUBTABLE             *Subtable;
   2058     DT_SUBTABLE             *ParentTable;
   2059     ACPI_STATUS             Status;
   2060 
   2061 
   2062     /* Compile the main table */
   2063 
   2064     Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl,
   2065         &Subtable);
   2066     if (ACPI_FAILURE (Status))
   2067     {
   2068         return (Status);
   2069     }
   2070 
   2071     ParentTable = DtPeekSubtable ();
   2072     DtInsertSubtable (ParentTable, Subtable);
   2073 
   2074     /* Compile each subtable */
   2075 
   2076     while (*PFieldList)
   2077     {
   2078         Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0,
   2079             &Subtable);
   2080         if (ACPI_FAILURE (Status))
   2081         {
   2082             return (Status);
   2083         }
   2084 
   2085         ParentTable = DtPeekSubtable ();
   2086         DtInsertSubtable (ParentTable, Subtable);
   2087     }
   2088 
   2089     return (AE_OK);
   2090 }
   2091 
   2092 
   2093 /******************************************************************************
   2094  *
   2095  * FUNCTION:    DtCompileTcpa
   2096  *
   2097  * PARAMETERS:  PFieldList          - Current field list pointer
   2098  *
   2099  * RETURN:      Status
   2100  *
   2101  * DESCRIPTION: Compile TCPA.
   2102  *
   2103  *****************************************************************************/
   2104 
   2105 ACPI_STATUS
   2106 DtCompileTcpa (
   2107     void                    **List)
   2108 {
   2109     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2110     DT_SUBTABLE             *Subtable;
   2111     ACPI_TABLE_TCPA_HDR     *TcpaHeader;
   2112     DT_SUBTABLE             *ParentTable;
   2113     ACPI_STATUS             Status;
   2114 
   2115 
   2116     /* Compile the main table */
   2117 
   2118     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr,
   2119         &Subtable);
   2120     if (ACPI_FAILURE (Status))
   2121     {
   2122         return (Status);
   2123     }
   2124 
   2125     ParentTable = DtPeekSubtable ();
   2126     DtInsertSubtable (ParentTable, Subtable);
   2127 
   2128     /*
   2129      * Examine the PlatformClass field to determine the table type.
   2130      * Either a client or server table. Only one.
   2131      */
   2132     TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer);
   2133 
   2134     switch (TcpaHeader->PlatformClass)
   2135     {
   2136     case ACPI_TCPA_CLIENT_TABLE:
   2137 
   2138         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient,
   2139             &Subtable);
   2140         break;
   2141 
   2142     case ACPI_TCPA_SERVER_TABLE:
   2143 
   2144         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer,
   2145             &Subtable);
   2146         break;
   2147 
   2148     default:
   2149 
   2150         AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n",
   2151             TcpaHeader->PlatformClass);
   2152         Status = AE_ERROR;
   2153         break;
   2154     }
   2155 
   2156     ParentTable = DtPeekSubtable ();
   2157     DtInsertSubtable (ParentTable, Subtable);
   2158     return (Status);
   2159 }
   2160 
   2161 
   2162 /******************************************************************************
   2163  *
   2164  * FUNCTION:    DtCompileTpm2Rev3
   2165  *
   2166  * PARAMETERS:  PFieldList          - Current field list pointer
   2167  *
   2168  * RETURN:      Status
   2169  *
   2170  * DESCRIPTION: Compile TPM2 revision 3
   2171  *
   2172  *****************************************************************************/
   2173 static ACPI_STATUS
   2174 DtCompileTpm2Rev3 (
   2175     void                    **List)
   2176 {
   2177     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2178     DT_SUBTABLE             *Subtable;
   2179     ACPI_TABLE_TPM23        *Tpm23Header;
   2180     DT_SUBTABLE             *ParentTable;
   2181     ACPI_STATUS             Status = AE_OK;
   2182 
   2183 
   2184     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23,
   2185         &Subtable);
   2186 
   2187     ParentTable = DtPeekSubtable ();
   2188     DtInsertSubtable (ParentTable, Subtable);
   2189     Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer);
   2190 
   2191     /* Subtable type depends on the StartMethod */
   2192 
   2193     switch (Tpm23Header->StartMethod)
   2194     {
   2195     case ACPI_TPM23_ACPI_START_METHOD:
   2196 
   2197         /* Subtable specific to to ARM_SMC */
   2198 
   2199         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a,
   2200             &Subtable);
   2201         if (ACPI_FAILURE (Status))
   2202         {
   2203             return (Status);
   2204         }
   2205 
   2206         ParentTable = DtPeekSubtable ();
   2207         DtInsertSubtable (ParentTable, Subtable);
   2208         break;
   2209 
   2210     default:
   2211         break;
   2212     }
   2213 
   2214     return (Status);
   2215 }
   2216 
   2217 
   2218 /******************************************************************************
   2219  *
   2220  * FUNCTION:    DtCompileTpm2
   2221  *
   2222  * PARAMETERS:  PFieldList          - Current field list pointer
   2223  *
   2224  * RETURN:      Status
   2225  *
   2226  * DESCRIPTION: Compile TPM2.
   2227  *
   2228  *****************************************************************************/
   2229 
   2230 ACPI_STATUS
   2231 DtCompileTpm2 (
   2232     void                    **List)
   2233 {
   2234     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2235     DT_SUBTABLE             *Subtable;
   2236     ACPI_TABLE_TPM2         *Tpm2Header;
   2237     DT_SUBTABLE             *ParentTable;
   2238     ACPI_STATUS             Status = AE_OK;
   2239     ACPI_TABLE_HEADER       *Header;
   2240 
   2241 
   2242     ParentTable = DtPeekSubtable ();
   2243 
   2244     Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
   2245 
   2246     if (Header->Revision == 3)
   2247     {
   2248         return (DtCompileTpm2Rev3 (List));
   2249     }
   2250 
   2251     /* Compile the main table */
   2252 
   2253     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2,
   2254         &Subtable);
   2255     if (ACPI_FAILURE (Status))
   2256     {
   2257         return (Status);
   2258     }
   2259 
   2260     ParentTable = DtPeekSubtable ();
   2261     DtInsertSubtable (ParentTable, Subtable);
   2262 
   2263     Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer);
   2264 
   2265     /* Method parameters */
   2266     /* Optional: Log area minimum length */
   2267     /* Optional: Log area start address */
   2268     /* TBD: Optional fields above not fully implemented (not optional at this time) */
   2269 
   2270     Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a,
   2271         &Subtable);
   2272     if (ACPI_FAILURE (Status))
   2273     {
   2274         return (Status);
   2275     }
   2276 
   2277     ParentTable = DtPeekSubtable ();
   2278     DtInsertSubtable (ParentTable, Subtable);
   2279 
   2280 
   2281     /* Subtable type depends on the StartMethod */
   2282 
   2283     switch (Tpm2Header->StartMethod)
   2284     {
   2285     case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC:
   2286 
   2287         /* Subtable specific to to ARM_SMC */
   2288 
   2289         Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211,
   2290             &Subtable);
   2291         if (ACPI_FAILURE (Status))
   2292         {
   2293             return (Status);
   2294         }
   2295 
   2296         ParentTable = DtPeekSubtable ();
   2297         DtInsertSubtable (ParentTable, Subtable);
   2298         break;
   2299 
   2300     case ACPI_TPM2_START_METHOD:
   2301     case ACPI_TPM2_MEMORY_MAPPED:
   2302     case ACPI_TPM2_COMMAND_BUFFER:
   2303     case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD:
   2304         break;
   2305 
   2306     case ACPI_TPM2_RESERVED1:
   2307     case ACPI_TPM2_RESERVED3:
   2308     case ACPI_TPM2_RESERVED4:
   2309     case ACPI_TPM2_RESERVED5:
   2310     case ACPI_TPM2_RESERVED9:
   2311     case ACPI_TPM2_RESERVED10:
   2312 
   2313         AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n",
   2314             Tpm2Header->StartMethod);
   2315         Status = AE_ERROR;
   2316         break;
   2317 
   2318     case ACPI_TPM2_NOT_ALLOWED:
   2319     default:
   2320 
   2321         AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n",
   2322             Tpm2Header->StartMethod);
   2323         Status = AE_ERROR;
   2324         break;
   2325     }
   2326 
   2327     return (Status);
   2328 }
   2329 
   2330 
   2331 /******************************************************************************
   2332  *
   2333  * FUNCTION:    DtGetGenericTableInfo
   2334  *
   2335  * PARAMETERS:  Name                - Generic type name
   2336  *
   2337  * RETURN:      Info entry
   2338  *
   2339  * DESCRIPTION: Obtain table info for a generic name entry
   2340  *
   2341  *****************************************************************************/
   2342 
   2343 ACPI_DMTABLE_INFO *
   2344 DtGetGenericTableInfo (
   2345     char                    *Name)
   2346 {
   2347     ACPI_DMTABLE_INFO       *Info;
   2348     UINT32                  i;
   2349 
   2350 
   2351     if (!Name)
   2352     {
   2353         return (NULL);
   2354     }
   2355 
   2356     /* Search info table for name match */
   2357 
   2358     for (i = 0; ; i++)
   2359     {
   2360         Info = AcpiDmTableInfoGeneric[i];
   2361         if (Info->Opcode == ACPI_DMT_EXIT)
   2362         {
   2363             Info = NULL;
   2364             break;
   2365         }
   2366 
   2367         /* Use caseless compare for generic keywords */
   2368 
   2369         if (!AcpiUtStricmp (Name, Info->Name))
   2370         {
   2371             break;
   2372         }
   2373     }
   2374 
   2375     return (Info);
   2376 }
   2377 
   2378 
   2379 /******************************************************************************
   2380  *
   2381  * FUNCTION:    DtCompileUefi
   2382  *
   2383  * PARAMETERS:  List                - Current field list pointer
   2384  *
   2385  * RETURN:      Status
   2386  *
   2387  * DESCRIPTION: Compile UEFI.
   2388  *
   2389  *****************************************************************************/
   2390 
   2391 ACPI_STATUS
   2392 DtCompileUefi (
   2393     void                    **List)
   2394 {
   2395     ACPI_STATUS             Status;
   2396     DT_SUBTABLE             *Subtable;
   2397     DT_SUBTABLE             *ParentTable;
   2398     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2399     UINT16                  *DataOffset;
   2400 
   2401 
   2402     /* Compile the predefined portion of the UEFI table */
   2403 
   2404     Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi,
   2405         &Subtable);
   2406     if (ACPI_FAILURE (Status))
   2407     {
   2408         return (Status);
   2409     }
   2410 
   2411     DataOffset = (UINT16 *) (Subtable->Buffer + 16);
   2412     *DataOffset = sizeof (ACPI_TABLE_UEFI);
   2413 
   2414     ParentTable = DtPeekSubtable ();
   2415     DtInsertSubtable (ParentTable, Subtable);
   2416 
   2417     /*
   2418      * Compile the "generic" portion of the UEFI table. This
   2419      * part of the table is not predefined and any of the generic
   2420      * operators may be used.
   2421      */
   2422     DtCompileGeneric ((void **) PFieldList, NULL, NULL);
   2423     return (AE_OK);
   2424 }
   2425 
   2426 
   2427 /******************************************************************************
   2428  *
   2429  * FUNCTION:    DtCompileViot
   2430  *
   2431  * PARAMETERS:  List                - Current field list pointer
   2432  *
   2433  * RETURN:      Status
   2434  *
   2435  * DESCRIPTION: Compile VIOT.
   2436  *
   2437  *****************************************************************************/
   2438 
   2439 ACPI_STATUS
   2440 DtCompileViot (
   2441     void                    **List)
   2442 {
   2443     ACPI_STATUS             Status;
   2444     DT_SUBTABLE             *Subtable;
   2445     DT_SUBTABLE             *ParentTable;
   2446     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2447     DT_FIELD                *SubtableStart;
   2448     ACPI_TABLE_VIOT         *Viot;
   2449     ACPI_VIOT_HEADER        *ViotHeader;
   2450     ACPI_DMTABLE_INFO       *InfoTable;
   2451     UINT16                  NodeCount;
   2452 
   2453     ParentTable = DtPeekSubtable ();
   2454 
   2455     Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable);
   2456     if (ACPI_FAILURE (Status))
   2457     {
   2458         return (Status);
   2459     }
   2460     DtInsertSubtable (ParentTable, Subtable);
   2461 
   2462     /*
   2463      * Using ACPI_SUB_PTR, We needn't define a separate structure. Care
   2464      * should be taken to avoid accessing ACPI_TABLE_HEADER fields.
   2465      */
   2466     Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer,
   2467         sizeof (ACPI_TABLE_HEADER));
   2468 
   2469     Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT);
   2470 
   2471     NodeCount = 0;
   2472     while (*PFieldList) {
   2473         SubtableStart = *PFieldList;
   2474         Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader,
   2475             &Subtable);
   2476         if (ACPI_FAILURE (Status))
   2477         {
   2478             return (Status);
   2479         }
   2480 
   2481         ParentTable = DtPeekSubtable ();
   2482         DtInsertSubtable (ParentTable, Subtable);
   2483         DtPushSubtable (Subtable);
   2484 
   2485         ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer);
   2486 
   2487         switch (ViotHeader->Type)
   2488         {
   2489         case ACPI_VIOT_NODE_PCI_RANGE:
   2490 
   2491             InfoTable = AcpiDmTableInfoViot1;
   2492             break;
   2493 
   2494         case ACPI_VIOT_NODE_MMIO:
   2495 
   2496             InfoTable = AcpiDmTableInfoViot2;
   2497             break;
   2498 
   2499         case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI:
   2500 
   2501             InfoTable = AcpiDmTableInfoViot3;
   2502             break;
   2503 
   2504         case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO:
   2505 
   2506             InfoTable = AcpiDmTableInfoViot4;
   2507             break;
   2508 
   2509         default:
   2510 
   2511             DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT");
   2512             return (AE_ERROR);
   2513         }
   2514 
   2515         Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
   2516         if (ACPI_FAILURE (Status))
   2517         {
   2518             return (Status);
   2519         }
   2520 
   2521         ParentTable = DtPeekSubtable ();
   2522         DtInsertSubtable (ParentTable, Subtable);
   2523         DtPopSubtable ();
   2524         NodeCount++;
   2525     }
   2526 
   2527     Viot->NodeCount = NodeCount;
   2528     return (AE_OK);
   2529 }
   2530 
   2531 
   2532 /******************************************************************************
   2533  *
   2534  * FUNCTION:    DtCompileWdat
   2535  *
   2536  * PARAMETERS:  List                - Current field list pointer
   2537  *
   2538  * RETURN:      Status
   2539  *
   2540  * DESCRIPTION: Compile WDAT.
   2541  *
   2542  *****************************************************************************/
   2543 
   2544 ACPI_STATUS
   2545 DtCompileWdat (
   2546     void                    **List)
   2547 {
   2548     ACPI_STATUS             Status;
   2549 
   2550 
   2551     Status = DtCompileTwoSubtables (List,
   2552         AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0);
   2553     return (Status);
   2554 }
   2555 
   2556 
   2557 /******************************************************************************
   2558  *
   2559  * FUNCTION:    DtCompileWpbt
   2560  *
   2561  * PARAMETERS:  List                - Current field list pointer
   2562  *
   2563  * RETURN:      Status
   2564  *
   2565  * DESCRIPTION: Compile WPBT.
   2566  *
   2567  *****************************************************************************/
   2568 
   2569 ACPI_STATUS
   2570 DtCompileWpbt (
   2571     void                    **List)
   2572 {
   2573     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2574     DT_SUBTABLE             *Subtable;
   2575     DT_SUBTABLE             *ParentTable;
   2576     ACPI_TABLE_WPBT         *Table;
   2577     ACPI_STATUS             Status;
   2578 
   2579 
   2580     /* Compile the main table */
   2581 
   2582     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable);
   2583     if (ACPI_FAILURE (Status))
   2584     {
   2585         return (Status);
   2586     }
   2587 
   2588     ParentTable = DtPeekSubtable ();
   2589     DtInsertSubtable (ParentTable, Subtable);
   2590     Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer);
   2591 
   2592     /*
   2593      * Exit now if there are no arguments specified. This is indicated by:
   2594      * The "Command-line Arguments" field has not been specified (if specified,
   2595      * it will be the last field in the field list -- after the main table).
   2596      * Set the Argument Length in the main table to zero.
   2597      */
   2598     if (!*PFieldList)
   2599     {
   2600         Table->ArgumentsLength = 0;
   2601         return (AE_OK);
   2602     }
   2603 
   2604     /* Compile the argument list subtable */
   2605 
   2606     Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable);
   2607     if (ACPI_FAILURE (Status))
   2608     {
   2609         return (Status);
   2610     }
   2611 
   2612     /* Extract the length of the Arguments buffer, insert into main table */
   2613 
   2614     Table->ArgumentsLength = (UINT16) Subtable->TotalLength;
   2615     DtInsertSubtable (ParentTable, Subtable);
   2616     return (AE_OK);
   2617 }
   2618 
   2619 
   2620 /******************************************************************************
   2621  *
   2622  * FUNCTION:    DtCompileXsdt
   2623  *
   2624  * PARAMETERS:  List                - Current field list pointer
   2625  *
   2626  * RETURN:      Status
   2627  *
   2628  * DESCRIPTION: Compile XSDT.
   2629  *
   2630  *****************************************************************************/
   2631 
   2632 ACPI_STATUS
   2633 DtCompileXsdt (
   2634     void                    **List)
   2635 {
   2636     DT_SUBTABLE             *Subtable;
   2637     DT_SUBTABLE             *ParentTable;
   2638     DT_FIELD                *FieldList = *(DT_FIELD **) List;
   2639     UINT64                  Address;
   2640 
   2641 
   2642     ParentTable = DtPeekSubtable ();
   2643 
   2644     while (FieldList)
   2645     {
   2646         DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO);
   2647 
   2648         DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable);
   2649         DtInsertSubtable (ParentTable, Subtable);
   2650         FieldList = FieldList->Next;
   2651     }
   2652 
   2653     return (AE_OK);
   2654 }
   2655 
   2656 
   2657 /******************************************************************************
   2658  *
   2659  * FUNCTION:    DtCompileGeneric
   2660  *
   2661  * PARAMETERS:  List                - Current field list pointer
   2662  *              Name                - Field name to end generic compiling
   2663  *              Length              - Compiled table length to return
   2664  *
   2665  * RETURN:      Status
   2666  *
   2667  * DESCRIPTION: Compile generic unknown table.
   2668  *
   2669  *****************************************************************************/
   2670 
   2671 ACPI_STATUS
   2672 DtCompileGeneric (
   2673     void                    **List,
   2674     char                    *Name,
   2675     UINT32                  *Length)
   2676 {
   2677     ACPI_STATUS             Status;
   2678     DT_SUBTABLE             *Subtable;
   2679     DT_SUBTABLE             *ParentTable;
   2680     DT_FIELD                **PFieldList = (DT_FIELD **) List;
   2681     ACPI_DMTABLE_INFO       *Info;
   2682 
   2683 
   2684     ParentTable = DtPeekSubtable ();
   2685 
   2686     /*
   2687      * Compile the "generic" portion of the table. This
   2688      * part of the table is not predefined and any of the generic
   2689      * operators may be used.
   2690      */
   2691 
   2692     /* Find any and all labels in the entire generic portion */
   2693 
   2694     DtDetectAllLabels (*PFieldList);
   2695 
   2696     /* Now we can actually compile the parse tree */
   2697 
   2698     if (Length && *Length)
   2699     {
   2700         *Length = 0;
   2701     }
   2702     while (*PFieldList)
   2703     {
   2704         if (Name && !strcmp ((*PFieldList)->Name, Name))
   2705         {
   2706             break;
   2707         }
   2708 
   2709         Info = DtGetGenericTableInfo ((*PFieldList)->Name);
   2710         if (!Info)
   2711         {
   2712             sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
   2713                 (*PFieldList)->Name);
   2714             DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
   2715                 (*PFieldList), AslGbl_MsgBuffer);
   2716 
   2717             *PFieldList = (*PFieldList)->Next;
   2718             continue;
   2719         }
   2720 
   2721         Status = DtCompileTable (PFieldList, Info,
   2722             &Subtable);
   2723         if (ACPI_SUCCESS (Status))
   2724         {
   2725             DtInsertSubtable (ParentTable, Subtable);
   2726             if (Length)
   2727             {
   2728                 *Length += Subtable->Length;
   2729             }
   2730         }
   2731         else
   2732         {
   2733             *PFieldList = (*PFieldList)->Next;
   2734 
   2735             if (Status == AE_NOT_FOUND)
   2736             {
   2737                 sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found",
   2738                     (*PFieldList)->Name);
   2739                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
   2740                     (*PFieldList), AslGbl_MsgBuffer);
   2741             }
   2742         }
   2743     }
   2744 
   2745     return (AE_OK);
   2746 }
   2747