diff options
Diffstat (limited to 'source/compiler/dttable1.c')
| -rw-r--r-- | source/compiler/dttable1.c | 1671 | 
1 files changed, 1671 insertions, 0 deletions
| diff --git a/source/compiler/dttable1.c b/source/compiler/dttable1.c new file mode 100644 index 000000000000..1c3b0f251104 --- /dev/null +++ b/source/compiler/dttable1.c @@ -0,0 +1,1671 @@ +/****************************************************************************** + * + * Module Name: dttable1.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 A-I */ + +#include "aslcompiler.h" +#include "dtcompiler.h" + +#define _COMPONENT          DT_COMPILER +        ACPI_MODULE_NAME    ("dttable1") + + +static ACPI_DMTABLE_INFO           TableInfoAsfAddress[] = +{ +    {ACPI_DMT_BUFFER,   0,               "Addresses", 0}, +    {ACPI_DMT_EXIT,     0,               NULL, 0} +}; + +static ACPI_DMTABLE_INFO           TableInfoDmarPciPath[] = +{ +    {ACPI_DMT_PCI_PATH, 0,               "PCI Path", 0}, +    {ACPI_DMT_EXIT,     0,               NULL, 0} +}; + + +/****************************************************************************** + * + * FUNCTION:    DtCompileAsf + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile ASF!. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileAsf ( +    void                    **List) +{ +    ACPI_ASF_INFO           *AsfTable; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    ACPI_DMTABLE_INFO       *InfoTable; +    ACPI_DMTABLE_INFO       *DataInfoTable = NULL; +    UINT32                  DataCount = 0; +    ACPI_STATUS             Status; +    UINT32                  i; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_FIELD                *SubtableStart; + + +    while (*PFieldList) +    { +        SubtableStart = *PFieldList; +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoAsfHdr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        AsfTable = ACPI_CAST_PTR (ACPI_ASF_INFO, Subtable->Buffer); + +        switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ +        { +        case ACPI_ASF_TYPE_INFO: + +            InfoTable = AcpiDmTableInfoAsf0; +            break; + +        case ACPI_ASF_TYPE_ALERT: + +            InfoTable = AcpiDmTableInfoAsf1; +            break; + +        case ACPI_ASF_TYPE_CONTROL: + +            InfoTable = AcpiDmTableInfoAsf2; +            break; + +        case ACPI_ASF_TYPE_BOOT: + +            InfoTable = AcpiDmTableInfoAsf3; +            break; + +        case ACPI_ASF_TYPE_ADDRESS: + +            InfoTable = AcpiDmTableInfoAsf4; +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); +            return (AE_ERROR); +        } + +        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); + +        switch (AsfTable->Header.Type & 0x7F) /* Mask off top bit */ +        { +        case ACPI_ASF_TYPE_INFO: + +            DataInfoTable = NULL; +            break; + +        case ACPI_ASF_TYPE_ALERT: + +            DataInfoTable = AcpiDmTableInfoAsf1a; +            DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, +                ACPI_SUB_PTR (UINT8, Subtable->Buffer, +                    sizeof (ACPI_ASF_HEADER)))->Alerts; +            break; + +        case ACPI_ASF_TYPE_CONTROL: + +            DataInfoTable = AcpiDmTableInfoAsf2a; +            DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, +                ACPI_SUB_PTR (UINT8, Subtable->Buffer, +                    sizeof (ACPI_ASF_HEADER)))->Controls; +            break; + +        case ACPI_ASF_TYPE_BOOT: + +            DataInfoTable = NULL; +            break; + +        case ACPI_ASF_TYPE_ADDRESS: + +            DataInfoTable = TableInfoAsfAddress; +            DataCount = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, +                ACPI_SUB_PTR (UINT8, Subtable->Buffer, +                    sizeof (ACPI_ASF_HEADER)))->Devices; +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "ASF!"); +            return (AE_ERROR); +        } + +        if (DataInfoTable) +        { +            switch (AsfTable->Header.Type & 0x7F) +            { +            case ACPI_ASF_TYPE_ADDRESS: + +                while (DataCount > 0) +                { +                    Status = DtCompileTable (PFieldList, DataInfoTable, +                        &Subtable, TRUE); +                    if (ACPI_FAILURE (Status)) +                    { +                        return (Status); +                    } + +                    DtInsertSubtable (ParentTable, Subtable); +                    DataCount = DataCount - Subtable->Length; +                } +                break; + +            default: + +                for (i = 0; i < DataCount; i++) +                { +                    Status = DtCompileTable (PFieldList, DataInfoTable, +                        &Subtable, TRUE); +                    if (ACPI_FAILURE (Status)) +                    { +                        return (Status); +                    } + +                    DtInsertSubtable (ParentTable, Subtable); +                } +                break; +            } +        } + +        DtPopSubtable (); +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileCpep + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile CPEP. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileCpep ( +    void                    **List) +{ +    ACPI_STATUS             Status; + + +    Status = DtCompileTwoSubtables (List, +        AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0); +    return (Status); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileCsrt + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile CSRT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileCsrt ( +    void                    **List) +{ +    ACPI_STATUS             Status = AE_OK; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    UINT32                  DescriptorCount; +    UINT32                  GroupLength; + + +    /* Subtables (Resource Groups) */ + +    ParentTable = DtPeekSubtable (); +    while (*PFieldList) +    { +        /* Resource group subtable */ + +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        /* Compute the number of resource descriptors */ + +        GroupLength = +            (ACPI_CAST_PTR (ACPI_CSRT_GROUP, +                Subtable->Buffer))->Length - +            (ACPI_CAST_PTR (ACPI_CSRT_GROUP, +                Subtable->Buffer))->SharedInfoLength - +            sizeof (ACPI_CSRT_GROUP); + +        DescriptorCount = (GroupLength  / +            sizeof (ACPI_CSRT_DESCRIPTOR)); + +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); +        ParentTable = DtPeekSubtable (); + +        /* Shared info subtable (One per resource group) */ + +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        DtInsertSubtable (ParentTable, Subtable); + +        /* Sub-Subtables (Resource Descriptors) */ + +        while (*PFieldList && DescriptorCount) +        { + +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            DtInsertSubtable (ParentTable, Subtable); + +            DtPushSubtable (Subtable); +            ParentTable = DtPeekSubtable (); +            if (*PFieldList) +            { +                Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a, +                    &Subtable, TRUE); +                if (ACPI_FAILURE (Status)) +                { +                    return (Status); +                } +                if (Subtable) +                { +                    DtInsertSubtable (ParentTable, Subtable); +                } +            } + +            DtPopSubtable (); +            ParentTable = DtPeekSubtable (); +            DescriptorCount--; +        } + +        DtPopSubtable (); +        ParentTable = DtPeekSubtable (); +    } + +    return (Status); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileDbg2 + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile DBG2. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileDbg2 ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    UINT32                  SubtableCount; +    ACPI_DBG2_HEADER        *Dbg2Header; +    ACPI_DBG2_DEVICE        *DeviceInfo; +    UINT16                  CurrentOffset; +    UINT32                  i; + + +    /* Main table */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); + +    /* Main table fields */ + +    Dbg2Header = ACPI_CAST_PTR (ACPI_DBG2_HEADER, Subtable->Buffer); +    Dbg2Header->InfoOffset = sizeof (ACPI_TABLE_HEADER) + ACPI_PTR_DIFF ( +        ACPI_ADD_PTR (UINT8, Dbg2Header, sizeof (ACPI_DBG2_HEADER)), Dbg2Header); + +    SubtableCount = Dbg2Header->InfoCount; +    DtPushSubtable (Subtable); + +    /* Process all Device Information subtables (Count = InfoCount) */ + +    while (*PFieldList && SubtableCount) +    { +        /* Subtable: Debug Device Information */ + +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        DeviceInfo = ACPI_CAST_PTR (ACPI_DBG2_DEVICE, Subtable->Buffer); +        CurrentOffset = (UINT16) sizeof (ACPI_DBG2_DEVICE); + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        ParentTable = DtPeekSubtable (); + +        /* BaseAddressRegister GAS array (Required, size is RegisterCount) */ + +        DeviceInfo->BaseAddressOffset = CurrentOffset; +        for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) +        { +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS); +            DtInsertSubtable (ParentTable, Subtable); +        } + +        /* AddressSize array (Required, size = RegisterCount) */ + +        DeviceInfo->AddressSizeOffset = CurrentOffset; +        for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++) +        { +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            CurrentOffset += (UINT16) sizeof (UINT32); +            DtInsertSubtable (ParentTable, Subtable); +        } + +        /* NamespaceString device identifier (Required, size = NamePathLength) */ + +        DeviceInfo->NamepathOffset = CurrentOffset; +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        /* Update the device info header */ + +        DeviceInfo->NamepathLength = (UINT16) Subtable->Length; +        CurrentOffset += (UINT16) DeviceInfo->NamepathLength; +        DtInsertSubtable (ParentTable, Subtable); + +        /* OemData - Variable-length data (Optional, size = OemDataLength) */ + +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        /* Update the device info header (zeros if no OEM data present) */ + +        DeviceInfo->OemDataOffset = 0; +        DeviceInfo->OemDataLength = 0; + +        /* Optional subtable (OemData) */ + +        if (Subtable && Subtable->Length) +        { +            DeviceInfo->OemDataOffset = CurrentOffset; +            DeviceInfo->OemDataLength = (UINT16) Subtable->Length; + +            DtInsertSubtable (ParentTable, Subtable); +        } + +        SubtableCount--; +        DtPopSubtable (); /* Get next Device Information subtable */ +    } + +    DtPopSubtable (); +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileDmar + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile DMAR. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileDmar ( +    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_DMAR_HEADER        *DmarHeader; +    ACPI_DMAR_DEVICE_SCOPE  *DmarDeviceScope; +    UINT32                  DeviceScopeLength; +    UINT32                  PciPathLength; + + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmar, &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); +    DtPushSubtable (Subtable); + +    while (*PFieldList) +    { +        /* DMAR Header */ + +        SubtableStart = *PFieldList; +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        DmarHeader = ACPI_CAST_PTR (ACPI_DMAR_HEADER, Subtable->Buffer); + +        switch (DmarHeader->Type) +        { +        case ACPI_DMAR_TYPE_HARDWARE_UNIT: + +            InfoTable = AcpiDmTableInfoDmar0; +            break; + +        case ACPI_DMAR_TYPE_RESERVED_MEMORY: + +            InfoTable = AcpiDmTableInfoDmar1; +            break; + +        case ACPI_DMAR_TYPE_ROOT_ATS: + +            InfoTable = AcpiDmTableInfoDmar2; +            break; + +        case ACPI_DMAR_TYPE_HARDWARE_AFFINITY: + +            InfoTable = AcpiDmTableInfoDmar3; +            break; + +        case ACPI_DMAR_TYPE_NAMESPACE: + +            InfoTable = AcpiDmTableInfoDmar4; +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "DMAR"); +            return (AE_ERROR); +        } + +        /* DMAR Subtable */ + +        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); + +        /* +         * Optional Device Scope subtables +         */ +        if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) || +            (DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE)) +        { +            /* These types do not support device scopes */ + +            DtPopSubtable (); +            continue; +        } + +        DtPushSubtable (Subtable); +        DeviceScopeLength = DmarHeader->Length - Subtable->Length - +            ParentTable->Length; +        while (DeviceScopeLength) +        { +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope, +                &Subtable, FALSE); +            if (Status == AE_NOT_FOUND) +            { +                break; +            } + +            ParentTable = DtPeekSubtable (); +            DtInsertSubtable (ParentTable, Subtable); +            DtPushSubtable (Subtable); + +            DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer); + +            /* Optional PCI Paths */ + +            PciPathLength = DmarDeviceScope->Length - Subtable->Length; +            while (PciPathLength) +            { +                Status = DtCompileTable (PFieldList, TableInfoDmarPciPath, +                    &Subtable, FALSE); +                if (Status == AE_NOT_FOUND) +                { +                    DtPopSubtable (); +                    break; +                } + +                ParentTable = DtPeekSubtable (); +                DtInsertSubtable (ParentTable, Subtable); +                PciPathLength -= Subtable->Length; +            } + +            DtPopSubtable (); +            DeviceScopeLength -= DmarDeviceScope->Length; +        } + +        DtPopSubtable (); +        DtPopSubtable (); +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileDrtm + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile DRTM. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileDrtm ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    UINT32                  Count; +    /* ACPI_TABLE_DRTM         *Drtm; */ +    ACPI_DRTM_VTABLE_LIST   *DrtmVtl; +    ACPI_DRTM_RESOURCE_LIST *DrtmRl; +    /* ACPI_DRTM_DPS_ID        *DrtmDps; */ + + +    ParentTable = DtPeekSubtable (); + +    /* Compile DRTM header */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } +    DtInsertSubtable (ParentTable, Subtable); + +    /* +     * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care +     * should be taken to avoid accessing ACPI_TABLE_HADER fields. +     */ +#if 0 +    Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM, +        Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); +#endif +    /* Compile VTL */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    DtInsertSubtable (ParentTable, Subtable); +    DrtmVtl = ACPI_CAST_PTR (ACPI_DRTM_VTABLE_LIST, Subtable->Buffer); + +    DtPushSubtable (Subtable); +    ParentTable = DtPeekSubtable (); +    Count = 0; + +    while (*PFieldList) +    { +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0a, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } +        if (!Subtable) +        { +            break; +        } +        DtInsertSubtable (ParentTable, Subtable); +        Count++; +    } + +    DrtmVtl->ValidatedTableCount = Count; +    DtPopSubtable (); +    ParentTable = DtPeekSubtable (); + +    /* Compile RL */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    DtInsertSubtable (ParentTable, Subtable); +    DrtmRl = ACPI_CAST_PTR (ACPI_DRTM_RESOURCE_LIST, Subtable->Buffer); + +    DtPushSubtable (Subtable); +    ParentTable = DtPeekSubtable (); +    Count = 0; + +    while (*PFieldList) +    { +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1a, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        if (!Subtable) +        { +            break; +        } + +        DtInsertSubtable (ParentTable, Subtable); +        Count++; +    } + +    DrtmRl->ResourceCount = Count; +    DtPopSubtable (); +    ParentTable = DtPeekSubtable (); + +    /* Compile DPS */ + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } +    DtInsertSubtable (ParentTable, Subtable); +    /* DrtmDps = ACPI_CAST_PTR (ACPI_DRTM_DPS_ID, Subtable->Buffer);*/ + + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileEinj + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile EINJ. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileEinj ( +    void                    **List) +{ +    ACPI_STATUS             Status; + + +    Status = DtCompileTwoSubtables (List, +        AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0); +    return (Status); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileErst + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile ERST. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileErst ( +    void                    **List) +{ +    ACPI_STATUS             Status; + + +    Status = DtCompileTwoSubtables (List, +        AcpiDmTableInfoErst, AcpiDmTableInfoEinj0); +    return (Status); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileGtdt + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile GTDT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileGtdt ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_FIELD                *SubtableStart; +    ACPI_SUBTABLE_HEADER    *GtdtHeader; +    ACPI_DMTABLE_INFO       *InfoTable; +    UINT32                  GtCount; + + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); + +    while (*PFieldList) +    { +        SubtableStart = *PFieldList; +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        GtdtHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); + +        switch (GtdtHeader->Type) +        { +        case ACPI_GTDT_TYPE_TIMER_BLOCK: + +            InfoTable = AcpiDmTableInfoGtdt0; +            break; + +        case ACPI_GTDT_TYPE_WATCHDOG: + +            InfoTable = AcpiDmTableInfoGtdt1; +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "GTDT"); +            return (AE_ERROR); +        } + +        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); + +        /* +         * Additional GT block subtable data +         */ + +        switch (GtdtHeader->Type) +        { +        case ACPI_GTDT_TYPE_TIMER_BLOCK: + +            DtPushSubtable (Subtable); +            ParentTable = DtPeekSubtable (); + +            GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK, +                Subtable->Buffer - sizeof(ACPI_GTDT_HEADER)))->TimerCount; + +            while (GtCount) +            { +                Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt0a, +                    &Subtable, TRUE); +                if (ACPI_FAILURE (Status)) +                { +                    return (Status); +                } + +                DtInsertSubtable (ParentTable, Subtable); +                GtCount--; +            } + +            DtPopSubtable (); +            break; + +        default: + +            break; +        } + +        DtPopSubtable (); +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileFpdt + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile FPDT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileFpdt ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    ACPI_FPDT_HEADER        *FpdtHeader; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    ACPI_DMTABLE_INFO       *InfoTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_FIELD                *SubtableStart; + + +    while (*PFieldList) +    { +        SubtableStart = *PFieldList; +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoFpdtHdr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        FpdtHeader = ACPI_CAST_PTR (ACPI_FPDT_HEADER, Subtable->Buffer); + +        switch (FpdtHeader->Type) +        { +        case ACPI_FPDT_TYPE_BOOT: + +            InfoTable = AcpiDmTableInfoFpdt0; +            break; + +        case ACPI_FPDT_TYPE_S3PERF: + +            InfoTable = AcpiDmTableInfoFpdt1; +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "FPDT"); +            return (AE_ERROR); +            break; +        } + +        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPopSubtable (); +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileHest + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile HEST. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileHest ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_FIELD                *SubtableStart; +    ACPI_DMTABLE_INFO       *InfoTable; +    UINT16                  Type; +    UINT32                  BankCount; + + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoHest, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); + +    while (*PFieldList) +    { +        /* Get subtable type */ + +        SubtableStart = *PFieldList; +        DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); + +        switch (Type) +        { +        case ACPI_HEST_TYPE_IA32_CHECK: + +            InfoTable = AcpiDmTableInfoHest0; +            break; + +        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: + +            InfoTable = AcpiDmTableInfoHest1; +            break; + +        case ACPI_HEST_TYPE_IA32_NMI: + +            InfoTable = AcpiDmTableInfoHest2; +            break; + +        case ACPI_HEST_TYPE_AER_ROOT_PORT: + +            InfoTable = AcpiDmTableInfoHest6; +            break; + +        case ACPI_HEST_TYPE_AER_ENDPOINT: + +            InfoTable = AcpiDmTableInfoHest7; +            break; + +        case ACPI_HEST_TYPE_AER_BRIDGE: + +            InfoTable = AcpiDmTableInfoHest8; +            break; + +        case ACPI_HEST_TYPE_GENERIC_ERROR: + +            InfoTable = AcpiDmTableInfoHest9; +            break; + +        default: + +            /* Cannot continue on unknown type */ + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST"); +            return (AE_ERROR); +        } + +        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        DtInsertSubtable (ParentTable, Subtable); + +        /* +         * Additional subtable data - IA32 Error Bank(s) +         */ +        BankCount = 0; +        switch (Type) +        { +        case ACPI_HEST_TYPE_IA32_CHECK: + +            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK, +                Subtable->Buffer))->NumHardwareBanks; +            break; + +        case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: + +            BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED, +                Subtable->Buffer))->NumHardwareBanks; +            break; + +        default: + +            break; +        } + +        while (BankCount) +        { +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            DtInsertSubtable (ParentTable, Subtable); +            BankCount--; +        } +    } + +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileIort + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile IORT. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileIort ( +    void                    **List) +{ +    ACPI_STATUS             Status; +    DT_SUBTABLE             *Subtable; +    DT_SUBTABLE             *ParentTable; +    DT_FIELD                **PFieldList = (DT_FIELD **) List; +    DT_FIELD                *SubtableStart; +    ACPI_TABLE_IORT         *Iort; +    ACPI_IORT_NODE          *IortNode; +    ACPI_IORT_ITS_GROUP     *IortItsGroup; +    ACPI_IORT_SMMU          *IortSmmu; +    UINT32                  NodeNumber; +    UINT32                  NodeLength; +    UINT32                  IdMappingNumber; +    UINT32                  ItsNumber; +    UINT32                  ContextIrptNumber; +    UINT32                  PmuIrptNumber; +    UINT32                  PaddingLength; + + +    ParentTable = DtPeekSubtable (); + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } +    DtInsertSubtable (ParentTable, Subtable); + +    /* +     * Using ACPI_SUB_PTR, We needn't define a seperate structure. Care +     * should be taken to avoid accessing ACPI_TABLE_HADER fields. +     */ +    Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT, +        Subtable->Buffer, sizeof (ACPI_TABLE_HEADER)); + +    /* +     * OptionalPadding - Variable-length data +     * (Optional, size = OffsetToNodes - sizeof (ACPI_TABLE_IORT)) +     * Optionally allows the generic data types to be used for filling +     * this field. +     */ +    Iort->NodeOffset = sizeof (ACPI_TABLE_IORT); +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } +    if (Subtable) +    { +        DtInsertSubtable (ParentTable, Subtable); +        Iort->NodeOffset += Subtable->Length; +    } +    else +    { +        Status = DtCompileGeneric (ACPI_CAST_PTR (void *, PFieldList), +            AcpiDmTableInfoIortHdr[0].Name, &PaddingLength); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } +        Iort->NodeOffset += PaddingLength; +    } + +    NodeNumber = 0; +    while (*PFieldList) +    { +        SubtableStart = *PFieldList; +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortHdr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        DtInsertSubtable (ParentTable, Subtable); +        IortNode = ACPI_CAST_PTR (ACPI_IORT_NODE, Subtable->Buffer); +        NodeLength = ACPI_OFFSET (ACPI_IORT_NODE, NodeData); + +        DtPushSubtable (Subtable); +        ParentTable = DtPeekSubtable (); + +        switch (IortNode->Type) +        { +        case ACPI_IORT_NODE_ITS_GROUP: + +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            DtInsertSubtable (ParentTable, Subtable); +            IortItsGroup = ACPI_CAST_PTR (ACPI_IORT_ITS_GROUP, Subtable->Buffer); +            NodeLength += Subtable->Length; + +            ItsNumber = 0; +            while (*PFieldList) +            { +                Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort0a, +                    &Subtable, TRUE); +                if (ACPI_FAILURE (Status)) +                { +                    return (Status); +                } +                if (!Subtable) +                { +                    break; +                } + +                DtInsertSubtable (ParentTable, Subtable); +                NodeLength += Subtable->Length; +                ItsNumber++; +            } + +            IortItsGroup->ItsCount = ItsNumber; +            break; + +        case ACPI_IORT_NODE_NAMED_COMPONENT: + +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            DtInsertSubtable (ParentTable, Subtable); +            NodeLength += Subtable->Length; + +            /* +             * Padding - Variable-length data +             * Optionally allows the offset of the ID mappings to be used +             * for filling this field. +             */ +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            if (Subtable) +            { +                DtInsertSubtable (ParentTable, Subtable); +                NodeLength += Subtable->Length; +            } +            else +            { +                if (NodeLength > IortNode->MappingOffset) +                { +                    return (AE_BAD_DATA); +                } + +                if (NodeLength < IortNode->MappingOffset) +                { +                    Status = DtCompilePadding ( +                        IortNode->MappingOffset - NodeLength, +                        &Subtable); +                    if (ACPI_FAILURE (Status)) +                    { +                        return (Status); +                    } + +                    DtInsertSubtable (ParentTable, Subtable); +                    NodeLength = IortNode->MappingOffset; +                } +            } +            break; + +        case ACPI_IORT_NODE_PCI_ROOT_COMPLEX: + +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort2, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            DtInsertSubtable (ParentTable, Subtable); +            NodeLength += Subtable->Length; +            break; + +        case ACPI_IORT_NODE_SMMU: + +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            DtInsertSubtable (ParentTable, Subtable); +            IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer); +            NodeLength += Subtable->Length; + +            /* Compile global interrupt array */ + +            IortSmmu->GlobalInterruptOffset = NodeLength; +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            DtInsertSubtable (ParentTable, Subtable); +            NodeLength += Subtable->Length; + +            /* Compile context interrupt array */ + +            ContextIrptNumber = 0; +            IortSmmu->ContextInterruptOffset = NodeLength; +            while (*PFieldList) +            { +                Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b, +                    &Subtable, TRUE); +                if (ACPI_FAILURE (Status)) +                { +                    return (Status); +                } + +                if (!Subtable) +                { +                    break; +                } + +                DtInsertSubtable (ParentTable, Subtable); +                NodeLength += Subtable->Length; +                ContextIrptNumber++; +            } + +            IortSmmu->ContextInterruptCount = ContextIrptNumber; + +            /* Compile PMU interrupt array */ + +            PmuIrptNumber = 0; +            IortSmmu->PmuInterruptOffset = NodeLength; +            while (*PFieldList) +            { +                Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c, +                    &Subtable, TRUE); +                if (ACPI_FAILURE (Status)) +                { +                    return (Status); +                } + +                if (!Subtable) +                { +                    break; +                } + +                DtInsertSubtable (ParentTable, Subtable); +                NodeLength += Subtable->Length; +                PmuIrptNumber++; +            } + +            IortSmmu->PmuInterruptCount = PmuIrptNumber; +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT"); +            return (AE_ERROR); +        } + +        /* Compile Array of ID mappings */ + +        IortNode->MappingOffset = NodeLength; +        IdMappingNumber = 0; +        while (*PFieldList) +        { +            Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap, +                &Subtable, TRUE); +            if (ACPI_FAILURE (Status)) +            { +                return (Status); +            } + +            if (!Subtable) +            { +                break; +            } + +            DtInsertSubtable (ParentTable, Subtable); +            NodeLength += sizeof (ACPI_IORT_ID_MAPPING); +            IdMappingNumber++; +        } + +        IortNode->MappingCount = IdMappingNumber; + +        /* +         * Node length can be determined by DT_LENGTH option +         * IortNode->Length = NodeLength; +         */ +        DtPopSubtable (); +        ParentTable = DtPeekSubtable (); +        NodeNumber++; +    } + +    Iort->NodeCount = NodeNumber; +    return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION:    DtCompileIvrs + * + * PARAMETERS:  List                - Current field list pointer + * + * RETURN:      Status + * + * DESCRIPTION: Compile IVRS. + * + *****************************************************************************/ + +ACPI_STATUS +DtCompileIvrs ( +    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_IVRS_HEADER        *IvrsHeader; +    UINT8                   EntryType; + + +    Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrs, +        &Subtable, TRUE); +    if (ACPI_FAILURE (Status)) +    { +        return (Status); +    } + +    ParentTable = DtPeekSubtable (); +    DtInsertSubtable (ParentTable, Subtable); + +    while (*PFieldList) +    { +        SubtableStart = *PFieldList; +        Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr, +            &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); +        DtPushSubtable (Subtable); + +        IvrsHeader = ACPI_CAST_PTR (ACPI_IVRS_HEADER, Subtable->Buffer); + +        switch (IvrsHeader->Type) +        { +        case ACPI_IVRS_TYPE_HARDWARE: + +            InfoTable = AcpiDmTableInfoIvrs0; +            break; + +        case ACPI_IVRS_TYPE_MEMORY1: +        case ACPI_IVRS_TYPE_MEMORY2: +        case ACPI_IVRS_TYPE_MEMORY3: + +            InfoTable = AcpiDmTableInfoIvrs1; +            break; + +        default: + +            DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IVRS"); +            return (AE_ERROR); +        } + +        Status = DtCompileTable (PFieldList, InfoTable, &Subtable, TRUE); +        if (ACPI_FAILURE (Status)) +        { +            return (Status); +        } + +        ParentTable = DtPeekSubtable (); +        DtInsertSubtable (ParentTable, Subtable); + +        if (IvrsHeader->Type == ACPI_IVRS_TYPE_HARDWARE) +        { +            while (*PFieldList && +                !strcmp ((*PFieldList)->Name, "Entry Type")) +            { +                SubtableStart = *PFieldList; +                DtCompileInteger (&EntryType, *PFieldList, 1, 0); + +                switch (EntryType) +                { +                /* 4-byte device entries */ + +                case ACPI_IVRS_TYPE_PAD4: +                case ACPI_IVRS_TYPE_ALL: +                case ACPI_IVRS_TYPE_SELECT: +                case ACPI_IVRS_TYPE_START: +                case ACPI_IVRS_TYPE_END: + +                    InfoTable = AcpiDmTableInfoIvrs4; +                    break; + +                /* 8-byte entries, type A */ + +                case ACPI_IVRS_TYPE_ALIAS_SELECT: +                case ACPI_IVRS_TYPE_ALIAS_START: + +                    InfoTable = AcpiDmTableInfoIvrs8a; +                    break; + +                /* 8-byte entries, type B */ + +                case ACPI_IVRS_TYPE_PAD8: +                case ACPI_IVRS_TYPE_EXT_SELECT: +                case ACPI_IVRS_TYPE_EXT_START: + +                    InfoTable = AcpiDmTableInfoIvrs8b; +                    break; + +                /* 8-byte entries, type C */ + +                case ACPI_IVRS_TYPE_SPECIAL: + +                    InfoTable = AcpiDmTableInfoIvrs8c; +                    break; + +                default: + +                    DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, +                        "IVRS Device Entry"); +                    return (AE_ERROR); +                } + +                Status = DtCompileTable (PFieldList, InfoTable, +                    &Subtable, TRUE); +                if (ACPI_FAILURE (Status)) +                { +                    return (Status); +                } + +                DtInsertSubtable (ParentTable, Subtable); +            } +        } + +        DtPopSubtable (); +    } + +    return (AE_OK); +} | 
