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