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