diff options
| author | Jung-uk Kim <jkim@FreeBSD.org> | 2015-11-25 21:04:42 +0000 | 
|---|---|---|
| committer | Jung-uk Kim <jkim@FreeBSD.org> | 2015-11-25 21:04:42 +0000 | 
| commit | b9098066cd6284319bca922f13e59517f774a103 (patch) | |
| tree | f01fd6c9053cb01ed84c00cb42ee789adafceaf5 /source/compiler/dttable2.c | |
| parent | 1e24cf365bc9c8df179b145c90d52852724e54ee (diff) | |
Notes
Diffstat (limited to 'source/compiler/dttable2.c')
| -rw-r--r-- | source/compiler/dttable2.c | 1686 | 
1 files changed, 1686 insertions, 0 deletions
| diff --git a/source/compiler/dttable2.c b/source/compiler/dttable2.c new file mode 100644 index 000000000000..ec2a36f00d67 --- /dev/null +++ b/source/compiler/dttable2.c @@ -0,0 +1,1686 @@ +/****************************************************************************** + * + * Module Name: dttable2.c - handling for specific ACPI tables + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2015, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions, and the following disclaimer, + *    without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + *    substantially similar to the "NO WARRANTY" disclaimer below + *    ("Disclaimer") and any redistribution must be conditioned upon + *    including a substantially similar Disclaimer requirement for further + *    binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + *    of any contributors may be used to endorse or promote products derived + *    from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +/* Compile all complex data tables, signatures starting with L-Z */ + +#include "aslcompiler.h" +#include "dtcompiler.h" + +#define _COMPONENT          DT_COMPILER +        ACPI_MODULE_NAME    ("dttable2") + + +/****************************************************************************** + * + * FUNCTION:    DtCompileLpit + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile LPIT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileLpit ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_FIELD                *SubtableStart; +    ACPI_DMTABLE_INFO       *InfoTable; +    ACPI_LPIT_HEADER        *LpitHeader; + + +    /* Note: Main table consists only of the standard ACPI table header */ + +    while (*PFieldList) +    { +        SubtableStart = *PFieldList; + +        /* LPIT Subtable header */ + +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoLpitHdr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        LpitHeader = ACPI_CAST_PTR (ACPI_LPIT_HEADER, Subtable->Buffer); + +        switch (LpitHeader->Type) +        { +        case ACPI_LPIT_TYPE_NATIVE_CSTATE: + +            InfoTable = AcpiDmTableInfoLpit0; +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "LPIT"); +            return (AE_ERROR); +        } + +        /* LPIT Subtable */ + +        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPopSubtable (); +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileMadt + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile MADT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileMadt ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_FIELD                *SubtableStart; +    ACPI_SUBTABLE_HEADER    *MadtHeader; +    ACPI_DMTABLE_INFO       *InfoTable; + + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadt, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); + +    while (*PFieldList) +    { +        SubtableStart = *PFieldList; +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        MadtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); + +        switch (MadtHeader->Type) +        { +        case ACPI_MADT_TYPE_LOCAL_APIC: + +            InfoTable = AcpiDmTableInfoMadt0; +            break; + +        case ACPI_MADT_TYPE_IO_APIC: + +            InfoTable = AcpiDmTableInfoMadt1; +            break; + +        case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: + +            InfoTable = AcpiDmTableInfoMadt2; +            break; + +        case ACPI_MADT_TYPE_NMI_SOURCE: + +            InfoTable = AcpiDmTableInfoMadt3; +            break; + +        case ACPI_MADT_TYPE_LOCAL_APIC_NMI: + +            InfoTable = AcpiDmTableInfoMadt4; +            break; + +        case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE: + +            InfoTable = AcpiDmTableInfoMadt5; +            break; + +        case ACPI_MADT_TYPE_IO_SAPIC: + +            InfoTable = AcpiDmTableInfoMadt6; +            break; + +        case ACPI_MADT_TYPE_LOCAL_SAPIC: + +            InfoTable = AcpiDmTableInfoMadt7; +            break; + +        case ACPI_MADT_TYPE_INTERRUPT_SOURCE: + +            InfoTable = AcpiDmTableInfoMadt8; +            break; + +        case ACPI_MADT_TYPE_LOCAL_X2APIC: + +            InfoTable = AcpiDmTableInfoMadt9; +            break; + +        case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI: + +            InfoTable = AcpiDmTableInfoMadt10; +            break; + +        case ACPI_MADT_TYPE_GENERIC_INTERRUPT: + +            InfoTable = AcpiDmTableInfoMadt11; +            break; + +        case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR: + +            InfoTable = AcpiDmTableInfoMadt12; +            break; + +        case ACPI_MADT_TYPE_GENERIC_MSI_FRAME: + +            InfoTable = AcpiDmTableInfoMadt13; +            break; + +        case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR: + +            InfoTable = AcpiDmTableInfoMadt14; +            break; + +        case ACPI_MADT_TYPE_GENERIC_TRANSLATOR: + +            InfoTable = AcpiDmTableInfoMadt15; +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT"); +            return (AE_ERROR); +        } + +        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPopSubtable (); +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileMcfg + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile MCFG. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileMcfg ( +    void                    **List) +{ +    ACPI_STATUS             Status; + + +    Status = DtCompileTwoSubtables (List, +        AcpiDmTableInfoMcfg, AcpiDmTableInfoMcfg0); +    return (Status); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileMpst + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile MPST. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileMpst ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    ACPI_MPST_CHANNEL       *MpstChannelInfo; +    ACPI_MPST_POWER_NODE    *MpstPowerNode; +    ACPI_MPST_DATA_HDR      *MpstDataHeader; +    UINT16                  SubtableCount; +    UINT32                  PowerStateCount; +    UINT32                  ComponentCount; + + +    /* Main table */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst, &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); +    DtPushSubtable (Subtable); + +    MpstChannelInfo = ACPI_CAST_PTR (ACPI_MPST_CHANNEL, Subtable->Buffer); +    SubtableCount = MpstChannelInfo->PowerNodeCount; + +    while (*PFieldList && SubtableCount) +    { +        /* Subtable: Memory Power Node(s) */ + +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        MpstPowerNode = ACPI_CAST_PTR (ACPI_MPST_POWER_NODE, Subtable->Buffer); +        PowerStateCount = MpstPowerNode->NumPowerStates; +        ComponentCount = MpstPowerNode->NumPhysicalComponents; + +        ParentTable = DtPeekSubtable (); + +        /* Sub-subtables - Memory Power State Structure(s) */ + +        while (*PFieldList && PowerStateCount) +        { +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0A, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            DtInsertSubtable (ParentTable, Subtable); +            PowerStateCount--; +        } + +        /* Sub-subtables - Physical Component ID Structure(s) */ + +        while (*PFieldList && ComponentCount) +        { +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst0B, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            DtInsertSubtable (ParentTable, Subtable); +            ComponentCount--; +        } + +        SubtableCount--; +        DtPopSubtable (); +    } + +    /* Subtable: Count of Memory Power State Characteristic structures */ + +    DtPopSubtable (); + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst1, &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); +    DtPushSubtable (Subtable); + +    MpstDataHeader = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable->Buffer); +    SubtableCount = MpstDataHeader->CharacteristicsCount; + +    ParentTable = DtPeekSubtable (); + +    /* Subtable: Memory Power State Characteristics structure(s) */ + +    while (*PFieldList && SubtableCount) +    { +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpst2, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        DtInsertSubtable (ParentTable, Subtable); +        SubtableCount--; +    } + +    DtPopSubtable (); +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileMsct + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile MSCT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileMsct ( +    void                    **List) +{ +    ACPI_STATUS             Status; + + +    Status = DtCompileTwoSubtables (List, +        AcpiDmTableInfoMsct, AcpiDmTableInfoMsct0); +    return (Status); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileMtmr + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile MTMR. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileMtmr ( +    void                    **List) +{ +    ACPI_STATUS             Status; + + +    Status = DtCompileTwoSubtables (List, +        AcpiDmTableInfoMtmr, AcpiDmTableInfoMtmr0); +    return (Status); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileNfit + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile NFIT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileNfit ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_FIELD                *SubtableStart; +    ACPI_NFIT_HEADER        *NfitHeader; +    ACPI_DMTABLE_INFO       *InfoTable; +    UINT32                  Count; +    ACPI_NFIT_INTERLEAVE    *Interleave = NULL; +    ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL; + + +    /* Main table */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); +    DtPushSubtable (Subtable); + +    /* Subtables */ + +    while (*PFieldList) +    { +        SubtableStart = *PFieldList; +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        NfitHeader = ACPI_CAST_PTR (ACPI_NFIT_HEADER, Subtable->Buffer); + +        switch (NfitHeader->Type) +        { +        case ACPI_NFIT_TYPE_SYSTEM_ADDRESS: + +            InfoTable = AcpiDmTableInfoNfit0; +            break; + +        case ACPI_NFIT_TYPE_MEMORY_MAP: + +            InfoTable = AcpiDmTableInfoNfit1; +            break; + +        case ACPI_NFIT_TYPE_INTERLEAVE: + +            Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable->Buffer); +            InfoTable = AcpiDmTableInfoNfit2; +            break; + +        case ACPI_NFIT_TYPE_SMBIOS: + +            InfoTable = AcpiDmTableInfoNfit3; +            break; + +        case ACPI_NFIT_TYPE_CONTROL_REGION: + +            InfoTable = AcpiDmTableInfoNfit4; +            break; + +        case ACPI_NFIT_TYPE_DATA_REGION: + +            InfoTable = AcpiDmTableInfoNfit5; +            break; + +        case ACPI_NFIT_TYPE_FLUSH_ADDRESS: + +            Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable->Buffer); +            InfoTable = AcpiDmTableInfoNfit6; +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT"); +            return (AE_ERROR); +        } + +        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPopSubtable (); + +        switch (NfitHeader->Type) +        { +        case ACPI_NFIT_TYPE_INTERLEAVE: + +            Count = 0; +            DtPushSubtable (Subtable); +            while (*PFieldList) +            { +                Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit2a, +                    &Subtable, FALSE); +                if (ACPI_FAILURE (Status)) +                { +                    return (Status); +                } + +                if (!Subtable) +                { +                    DtPopSubtable (); +                    break; +                } + +                ParentTable = DtPeekSubtable (); +                DtInsertSubtable (ParentTable, Subtable); +                Count++; +            } + +            Interleave->LineCount = Count; +            DtPopSubtable (); +            break; + +        case ACPI_NFIT_TYPE_SMBIOS: + +            if (*PFieldList) +            { +                Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a, +                    &Subtable, TRUE); +                if (ACPI_FAILURE (Status)) +                { +                    return (Status); +                } + +                if (Subtable) +                { +                    DtInsertSubtable (ParentTable, Subtable); +                } +            } +            break; + +        case ACPI_NFIT_TYPE_FLUSH_ADDRESS: + +            Count = 0; +            DtPushSubtable (Subtable); +            while (*PFieldList) +            { +                Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit6a, +                    &Subtable, FALSE); +                if (ACPI_FAILURE (Status)) +                { +                    return (Status); +                } + +                if (!Subtable) +                { +                    DtPopSubtable (); +                    break; +                } + +                ParentTable = DtPeekSubtable (); +                DtInsertSubtable (ParentTable, Subtable); +                Count++; +            } + +            Hint->HintCount = (UINT16) Count; +            DtPopSubtable (); +            break; + +        default: +            break; +        } +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompilePcct + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile PCCT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompilePcct ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_FIELD                *SubtableStart; +    ACPI_SUBTABLE_HEADER    *PcctHeader; +    ACPI_DMTABLE_INFO       *InfoTable; + + +    /* Main table */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcct, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); + +    /* Subtables */ + +    while (*PFieldList) +    { +        SubtableStart = *PFieldList; +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        PcctHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); + +        switch (PcctHeader->Type) +        { +        case ACPI_PCCT_TYPE_GENERIC_SUBSPACE: + +            InfoTable = AcpiDmTableInfoPcct0; +            break; + +        case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE: + +            InfoTable = AcpiDmTableInfoPcct1; +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT"); +            return (AE_ERROR); +        } + +        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPopSubtable (); +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompilePmtt + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile PMTT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompilePmtt ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_FIELD                *SubtableStart; +    ACPI_PMTT_HEADER        *PmttHeader; +    ACPI_PMTT_CONTROLLER    *PmttController; +    UINT16                  DomainCount; +    UINT8                   PrevType = ACPI_PMTT_TYPE_SOCKET; + + +    /* Main table */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); +    DtPushSubtable (Subtable); + +    while (*PFieldList) +    { +        SubtableStart = *PFieldList; +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttHdr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        PmttHeader = ACPI_CAST_PTR (ACPI_PMTT_HEADER, Subtable->Buffer); +        while (PrevType >= PmttHeader->Type) +        { +            DtPopSubtable (); + +            if (PrevType == ACPI_PMTT_TYPE_SOCKET) +            { +                break; +            } + +            PrevType--; +        } + +        PrevType = PmttHeader->Type; + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        switch (PmttHeader->Type) +        { +        case ACPI_PMTT_TYPE_SOCKET: + +            /* Subtable: Socket Structure */ + +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            ParentTable = DtPeekSubtable (); +            DtInsertSubtable (ParentTable, Subtable); +            break; + +        case ACPI_PMTT_TYPE_CONTROLLER: + +            /* Subtable: Memory Controller Structure */ + +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            ParentTable = DtPeekSubtable (); +            DtInsertSubtable (ParentTable, Subtable); + +            PmttController = ACPI_CAST_PTR (ACPI_PMTT_CONTROLLER, +                (Subtable->Buffer - sizeof (ACPI_PMTT_HEADER))); +            DomainCount = PmttController->DomainCount; + +            while (DomainCount) +            { +                Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1a, +                    &Subtable, TRUE); +                if (ACPI_FAILURE (Status)) +                { +                    return (Status); +                } + +                DtInsertSubtable (ParentTable, Subtable); +                DomainCount--; +            } +            break; + +        case ACPI_PMTT_TYPE_DIMM: + +            /* Subtable: Physical Component Structure */ + +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            ParentTable = DtPeekSubtable (); +            DtInsertSubtable (ParentTable, Subtable); +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT"); +            return (AE_ERROR); +        } +    } + +    return (Status); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileRsdt + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile RSDT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileRsdt ( +    void                    **List) +{ +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                *FieldList = *(DT_FIELD **) List; +    UINT32                  Address; + + +    ParentTable = DtPeekSubtable (); + +    while (FieldList) +    { +        DtCompileInteger ((UINT8 *) &Address, FieldList, 4, DT_NON_ZERO); + +        DtCreateSubtable ((UINT8 *) &Address, 4, &Subtable); +        DtInsertSubtable (ParentTable, Subtable); +        FieldList = FieldList->Next; +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileS3pt + * + * PARAMETERS:  PFieldList          - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile S3PT (Pointed to by FPDT) + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileS3pt ( +    DT_FIELD                **PFieldList) +{ +    ACPI_STATUS             Status; +    ACPI_S3PT_HEADER        *S3ptHeader; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    ACPI_DMTABLE_INFO       *InfoTable; +    DT_FIELD                *SubtableStart; + + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt, +        &Gbl_RootTable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    DtPushSubtable (Gbl_RootTable); + +    while (*PFieldList) +    { +        SubtableStart = *PFieldList; +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        S3ptHeader = ACPI_CAST_PTR (ACPI_S3PT_HEADER, Subtable->Buffer); + +        switch (S3ptHeader->Type) +        { +        case ACPI_S3PT_TYPE_RESUME: + +            InfoTable = AcpiDmTableInfoS3pt0; +            break; + +        case ACPI_S3PT_TYPE_SUSPEND: + +            InfoTable = AcpiDmTableInfoS3pt1; +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "S3PT"); +            return (AE_ERROR); +        } + +        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPopSubtable (); +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileSlic + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile SLIC. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileSlic ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; + + +    while (*PFieldList) +    { +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlic, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); +        DtPopSubtable (); +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileSlit + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile SLIT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileSlit ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_FIELD                *FieldList; +    UINT32                  Localities; +    UINT8                   *LocalityBuffer; + + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); + +    Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); +    LocalityBuffer = UtLocalCalloc (Localities); + +    /* Compile each locality buffer */ + +    FieldList = *PFieldList; +    while (FieldList) +    { +        DtCompileBuffer (LocalityBuffer, +            FieldList->Value, FieldList, Localities); + +        DtCreateSubtable (LocalityBuffer, Localities, &Subtable); +        DtInsertSubtable (ParentTable, Subtable); +        FieldList = FieldList->Next; +    } + +    ACPI_FREE (LocalityBuffer); +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileSrat + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile SRAT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileSrat ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_FIELD                *SubtableStart; +    ACPI_SUBTABLE_HEADER    *SratHeader; +    ACPI_DMTABLE_INFO       *InfoTable; + + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoSrat, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); + +    while (*PFieldList) +    { +        SubtableStart = *PFieldList; +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        SratHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); + +        switch (SratHeader->Type) +        { +        case ACPI_SRAT_TYPE_CPU_AFFINITY: + +            InfoTable = AcpiDmTableInfoSrat0; +            break; + +        case ACPI_SRAT_TYPE_MEMORY_AFFINITY: + +            InfoTable = AcpiDmTableInfoSrat1; +            break; + +        case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: + +            InfoTable = AcpiDmTableInfoSrat2; +            break; + +        case ACPI_SRAT_TYPE_GICC_AFFINITY: + +            InfoTable = AcpiDmTableInfoSrat3; +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); +            return (AE_ERROR); +        } + +        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPopSubtable (); +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileStao + * + * PARAMETERS:  PFieldList          - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile STAO. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileStao ( +    void                    **List) +{ +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    ACPI_STATUS             Status; + + +    /* Compile the main table */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoStao, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); + +    /* Compile each ASCII namestring as a subtable */ + +    while (*PFieldList) +    { +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoStaoStr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileTcpa + * + * PARAMETERS:  PFieldList          - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile TCPA. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileTcpa ( +    void                    **List) +{ +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_SUBTABLE             *Subtable; +    ACPI_TABLE_TCPA_HDR     *TcpaHeader; +    DT_SUBTABLE             *ParentTable; +    ACPI_STATUS             Status; + + +    /* Compile the main table */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaHdr, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); + +    /* +     * Examine the PlatformClass field to determine the table type. +     * Either a client or server table. Only one. +     */ +    TcpaHeader = ACPI_CAST_PTR (ACPI_TABLE_TCPA_HDR, ParentTable->Buffer); + +    switch (TcpaHeader->PlatformClass) +    { +    case ACPI_TCPA_CLIENT_TABLE: + +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaClient, +            &Subtable, TRUE); +        break; + +    case ACPI_TCPA_SERVER_TABLE: + +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer, +            &Subtable, TRUE); +        break; + +    default: + +        AcpiOsPrintf ("\n**** Unknown TCPA Platform Class 0x%X\n", +            TcpaHeader->PlatformClass); +        Status = AE_ERROR; +        break; +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); +    return (Status); +} + + +/****************************************************************************** + * + * FUNCTION:    DtGetGenericTableInfo + * + * PARAMETERS:  Name                - Generic type name + * + * RETURN:      Info entry + * + * DESCRIPTION: Obtain table info for a generic name entry + * + *****************************************************************************/ + +ACPI_DMTABLE_INFO * +DtGetGenericTableInfo ( +    char                    *Name) +{ +    ACPI_DMTABLE_INFO       *Info; +    UINT32                  i; + + +    if (!Name) +    { +        return (NULL); +    } + +    /* Search info table for name match */ + +    for (i = 0; ; i++) +    { +        Info = AcpiDmTableInfoGeneric[i]; +        if (Info->Opcode == ACPI_DMT_EXIT) +        { +            Info = NULL; +            break; +        } + +        /* Use caseless compare for generic keywords */ + +        if (!AcpiUtStricmp (Name, Info->Name)) +        { +            break; +        } +    } + +    return (Info); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileUefi + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile UEFI. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileUefi ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    UINT16                  *DataOffset; + + +    /* Compile the predefined portion of the UEFI table */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoUefi, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    DataOffset = (UINT16 *) (Subtable->Buffer + 16); +    *DataOffset = sizeof (ACPI_TABLE_UEFI); + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); + +    /* +     * Compile the "generic" portion of the UEFI table. This +     * part of the table is not predefined and any of the generic +     * operators may be used. +     */ +    DtCompileGeneric ((void **) PFieldList, NULL, NULL); +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileVrtc + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile VRTC. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileVrtc ( +    void                    **List) +{ +    ACPI_STATUS             Status; + + +    Status = DtCompileTwoSubtables (List, +        AcpiDmTableInfoVrtc, AcpiDmTableInfoVrtc0); +    return (Status); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileWdat + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile WDAT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileWdat ( +    void                    **List) +{ +    ACPI_STATUS             Status; + + +    Status = DtCompileTwoSubtables (List, +        AcpiDmTableInfoWdat, AcpiDmTableInfoWdat0); +    return (Status); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileWpbt + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile WPBT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileWpbt ( +    void                    **List) +{ +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    ACPI_TABLE_WPBT         *Table; +    ACPI_STATUS             Status; +    UINT16                  Length; + + +    /* Compile the main table */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); + +    /* Compile the argument list subtable */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    /* Extract the length of the Arguments buffer, insert into main table */ + +    Length = (UINT16) Subtable->TotalLength; +    Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer); +    Table->ArgumentsLength = Length; + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileXsdt + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile XSDT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileXsdt ( +    void                    **List) +{ +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                *FieldList = *(DT_FIELD **) List; +    UINT64                  Address; + + +    ParentTable = DtPeekSubtable (); + +    while (FieldList) +    { +        DtCompileInteger ((UINT8 *) &Address, FieldList, 8, DT_NON_ZERO); + +        DtCreateSubtable ((UINT8 *) &Address, 8, &Subtable); +        DtInsertSubtable (ParentTable, Subtable); +        FieldList = FieldList->Next; +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileGeneric + * + * PARAMETERS:  List                - Current field list pointer + *              Name                - Field name to end generic compiling + *              Length              - Compiled table length to return + * + * RETURN:      Status + * + * DESCRIPTION: Compile generic unknown table. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileGeneric ( +    void                    **List, +    char                    *Name, +    UINT32                  *Length) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    ACPI_DMTABLE_INFO       *Info; + + +    ParentTable = DtPeekSubtable (); + +    /* +     * Compile the "generic" portion of the table. This +     * part of the table is not predefined and any of the generic +     * operators may be used. +     */ + +    /* Find any and all labels in the entire generic portion */ + +    DtDetectAllLabels (*PFieldList); + +    /* Now we can actually compile the parse tree */ + +    if (Length && *Length) +    { +        *Length = 0; +    } +    while (*PFieldList) +    { +        if (Name && !strcmp ((*PFieldList)->Name, Name)) +        { +            break; +        } + +        Info = DtGetGenericTableInfo ((*PFieldList)->Name); +        if (!Info) +        { +            sprintf (MsgBuffer, "Generic data type \"%s\" not found", +                (*PFieldList)->Name); +            DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, +                (*PFieldList), MsgBuffer); + +            *PFieldList = (*PFieldList)->Next; +            continue; +        } + +        Status = DtCompileTable (PFieldList, Info, +            &Subtable, TRUE); +        if (ACPI_SUCCESS (Status)) +        { +            DtInsertSubtable (ParentTable, Subtable); +            if (Length) +            { +                *Length += Subtable->Length; +            } +        } +        else +        { +            *PFieldList = (*PFieldList)->Next; + +            if (Status == AE_NOT_FOUND) +            { +                sprintf (MsgBuffer, "Generic data type \"%s\" not found", +                    (*PFieldList)->Name); +                DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, +                    (*PFieldList), MsgBuffer); +            } +        } +    } + +    return (AE_OK); +} | 
