| /****************************************************************************** |
| * |
| * Module Name: dttable2.c - handling for specific ACPI tables |
| * |
| *****************************************************************************/ |
| |
| /* |
| * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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" |
| |
| #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); |
| 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); |
| 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); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| while (*PFieldList) |
| { |
| SubtableStart = *PFieldList; |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoMadtHdr, |
| &Subtable); |
| 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; |
| |
| case ACPI_MADT_TYPE_MULTIPROC_WAKEUP: |
| |
| InfoTable = AcpiDmTableInfoMadt16; |
| break; |
| |
| default: |
| |
| if (MadtHeader->Type >= ACPI_MADT_TYPE_OEM_RESERVED) |
| { |
| InfoTable = AcpiDmTableInfoMadt17; |
| } |
| else |
| { |
| DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "MADT"); |
| return (AE_ERROR); |
| } |
| |
| break; |
| } |
| |
| Status = DtCompileTable (PFieldList, InfoTable, &Subtable); |
| 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: DtCompileMpam |
| * |
| * PARAMETERS: List - Current field list pointer |
| * |
| * RETURN: Status |
| * |
| * DESCRIPTION: Compile MPAM. |
| * |
| *****************************************************************************/ |
| |
| ACPI_STATUS |
| DtCompileMpam ( |
| void **List) |
| { |
| ACPI_STATUS Status; |
| DT_SUBTABLE *ParentTable; |
| DT_SUBTABLE *Subtable; |
| DT_FIELD *SubtableStart; |
| DT_FIELD **PFieldList = (DT_FIELD **) List; |
| ACPI_MPAM_MSC_NODE *MpamMscNode; |
| ACPI_MPAM_RESOURCE_NODE *MpamResourceNode; |
| UINT32 FuncDepsCount; |
| UINT32 RisLength; |
| ACPI_DMTABLE_INFO *InfoTable; |
| |
| ParentTable = DtPeekSubtable (); |
| |
| while (*PFieldList) |
| { |
| SubtableStart = *PFieldList; |
| |
| /* Main MSC Node table */ |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam0, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| MpamMscNode = ACPI_CAST_PTR (ACPI_MPAM_MSC_NODE, Subtable->Buffer); |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPushSubtable (Subtable); |
| |
| ParentTable = DtPeekSubtable (); |
| |
| /* |
| * RIS(es) per MSC node have variable lengths depending on how many RISes there and |
| * any how many functional dependencies per RIS. Calculate it in order |
| * to properly set the overall MSC length. |
| */ |
| RisLength = 0; |
| |
| /* Iterate over RIS subtables per MSC node */ |
| for (UINT32 ris = 0; ris < MpamMscNode->NumResouceNodes; ris++) |
| { |
| /* Compile RIS subtable */ |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| MpamResourceNode = ACPI_CAST_PTR (ACPI_MPAM_RESOURCE_NODE, Subtable->Buffer); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPushSubtable (Subtable); |
| |
| ParentTable = DtPeekSubtable (); |
| |
| switch (MpamResourceNode->LocatorType) |
| { |
| case ACPI_MPAM_LOCATION_TYPE_PROCESSOR_CACHE: |
| InfoTable = AcpiDmTableInfoMpam1A; |
| break; |
| case ACPI_MPAM_LOCATION_TYPE_MEMORY: |
| InfoTable = AcpiDmTableInfoMpam1B; |
| break; |
| case ACPI_MPAM_LOCATION_TYPE_SMMU: |
| InfoTable = AcpiDmTableInfoMpam1C; |
| break; |
| case ACPI_MPAM_LOCATION_TYPE_MEMORY_CACHE: |
| InfoTable = AcpiDmTableInfoMpam1D; |
| break; |
| case ACPI_MPAM_LOCATION_TYPE_ACPI_DEVICE: |
| InfoTable = AcpiDmTableInfoMpam1E; |
| break; |
| case ACPI_MPAM_LOCATION_TYPE_INTERCONNECT: |
| InfoTable = AcpiDmTableInfoMpam1F; |
| break; |
| case ACPI_MPAM_LOCATION_TYPE_UNKNOWN: |
| InfoTable = AcpiDmTableInfoMpam1G; |
| default: |
| DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "Resource Locator Type"); |
| return (AE_ERROR); |
| } |
| |
| /* Compile Resource Locator Table */ |
| Status = DtCompileTable (PFieldList, InfoTable, |
| &Subtable); |
| |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| /* Compile the number of functional dependencies per RIS */ |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1Deps, |
| &Subtable); |
| |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| DtInsertSubtable (ParentTable, Subtable); |
| FuncDepsCount = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); |
| |
| RisLength += sizeof(ACPI_MPAM_RESOURCE_NODE) + |
| FuncDepsCount * sizeof(ACPI_MPAM_FUNC_DEPS); |
| |
| /* Iterate over functional dependencies per RIS */ |
| for (UINT32 funcDep = 0; funcDep < FuncDepsCount; funcDep++) |
| { |
| /* Compiler functional dependencies table */ |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam2, |
| &Subtable); |
| |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| DtInsertSubtable (ParentTable, Subtable); |
| } |
| |
| DtPopSubtable (); |
| } |
| |
| /* Check if the length of the MSC is correct and override with the correct length */ |
| if (MpamMscNode->Length != sizeof(ACPI_MPAM_MSC_NODE) + RisLength) |
| { |
| MpamMscNode->Length = (UINT16) (sizeof(ACPI_MPAM_MSC_NODE) + RisLength); |
| DbgPrint (ASL_DEBUG_OUTPUT, "Overriding MSC->Length: %X\n", MpamMscNode->Length); |
| } |
| |
| DtPopSubtable (); |
| } |
| |
| return (AE_OK); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * 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); |
| 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); |
| 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); |
| 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); |
| 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); |
| 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); |
| 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: 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); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPushSubtable (Subtable); |
| |
| /* Subtables */ |
| |
| while (*PFieldList) |
| { |
| SubtableStart = *PFieldList; |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfitHdr, |
| &Subtable); |
| 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; |
| |
| case ACPI_NFIT_TYPE_CAPABILITIES: |
| |
| InfoTable = AcpiDmTableInfoNfit7; |
| break; |
| |
| default: |
| |
| DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "NFIT"); |
| return (AE_ERROR); |
| } |
| |
| Status = DtCompileTable (PFieldList, InfoTable, &Subtable); |
| 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); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| if (!Subtable) |
| { |
| DtPopSubtable (); |
| break; |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| Count++; |
| } |
| |
| Interleave->LineCount = Count; |
| break; |
| |
| case ACPI_NFIT_TYPE_SMBIOS: |
| |
| if (*PFieldList) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNfit3a, |
| &Subtable); |
| 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); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| if (!Subtable) |
| { |
| DtPopSubtable (); |
| break; |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| Count++; |
| } |
| |
| Hint->HintCount = (UINT16) Count; |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| return (AE_OK); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: DtCompileNhlt |
| * |
| * PARAMETERS: List - Current field list pointer |
| * |
| * RETURN: Status |
| * |
| * DESCRIPTION: Compile NHLT. |
| * |
| *****************************************************************************/ |
| |
| ACPI_STATUS |
| DtCompileNhlt ( |
| void **List) |
| { |
| ACPI_STATUS Status; |
| UINT32 EndpointCount; |
| UINT32 MicrophoneCount; |
| UINT32 FormatsCount; |
| DT_SUBTABLE *Subtable; |
| DT_SUBTABLE *ParentTable; |
| DT_FIELD **PFieldList = (DT_FIELD **) List; |
| UINT32 CapabilitiesSize; |
| UINT8 ArrayType; |
| UINT8 ConfigType; |
| UINT8 DeviceInfoCount; |
| UINT32 i; |
| UINT32 j; |
| ACPI_TABLE_NHLT_ENDPOINT_COUNT *MainTable; |
| ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A *DevSpecific; |
| ACPI_NHLT_VENDOR_MIC_COUNT *MicCount; |
| ACPI_NHLT_FORMATS_CONFIG *FormatsConfig; |
| ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D *ConfigSpecific; |
| ACPI_NHLT_DEVICE_INFO_COUNT *DeviceInfo; |
| ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B *Terminator; |
| |
| |
| /* Main table */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| /* Get the Endpoint Descriptor count */ |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPushSubtable (Subtable); |
| |
| MainTable = ACPI_CAST_PTR (ACPI_TABLE_NHLT_ENDPOINT_COUNT, Subtable->Buffer); |
| EndpointCount = MainTable->EndpointCount; |
| |
| /* Subtables */ |
| |
| while (*PFieldList) |
| { |
| /* Variable number of Endpoint descriptors */ |
| |
| for (i = 0; i < EndpointCount; i++) |
| { |
| /* Do the Endpoint Descriptor */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt0, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPushSubtable (Subtable); |
| |
| /* Do the Device Specific table */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5b, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPushSubtable (Subtable); |
| |
| DevSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Subtable->Buffer); |
| CapabilitiesSize = DevSpecific->CapabilitiesSize; |
| |
| ArrayType = 0; |
| ConfigType = 0; |
| |
| switch (CapabilitiesSize) |
| { |
| case 0: |
| break; |
| |
| case 1: |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5c, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| break; |
| |
| case 2: |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| break; |
| |
| case 3: |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5a, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| ConfigSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D, Subtable->Buffer); |
| ArrayType = ConfigSpecific->ArrayType; |
| ConfigType = ConfigSpecific->ConfigType; |
| break; |
| |
| case 7: |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt6b, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| ConfigSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D, Subtable->Buffer); |
| ArrayType = ConfigSpecific->ArrayType; |
| ConfigType = ConfigSpecific->ConfigType; |
| break; |
| |
| default: |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5a, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| ConfigSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_D, Subtable->Buffer); |
| ArrayType = ConfigSpecific->ArrayType; |
| ConfigType = ConfigSpecific->ConfigType; |
| break; |
| |
| } /* switch (CapabilitiesSize) */ |
| |
| if (CapabilitiesSize >= 3) |
| { |
| /* Check for a vendor-defined mic array */ |
| |
| if (ConfigType == ACPI_NHLT_CONFIG_TYPE_MIC_ARRAY) |
| { |
| if ((ArrayType & ACPI_NHLT_ARRAY_TYPE_MASK) == ACPI_NHLT_VENDOR_DEFINED) |
| { |
| /* Get the microphone count */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt6a, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| MicCount = ACPI_CAST_PTR (ACPI_NHLT_VENDOR_MIC_COUNT, Subtable->Buffer); |
| MicrophoneCount = MicCount->MicrophoneCount; |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| /* Variable number of microphones */ |
| |
| for (j = 0; j < MicrophoneCount; j++) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt6, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| } |
| |
| /* Do the MIC_SNR_SENSITIVITY_EXTENSION, if present */ |
| |
| if (ArrayType & ACPI_NHLT_ARRAY_TYPE_EXT_MASK) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt9, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| } |
| } |
| } |
| } |
| |
| /* Get the formats count */ |
| |
| DtPopSubtable (); |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt4, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| FormatsConfig = ACPI_CAST_PTR (ACPI_NHLT_FORMATS_CONFIG, Subtable->Buffer); |
| FormatsCount = FormatsConfig->FormatsCount; |
| |
| /* Variable number of wave_format_extensible structs */ |
| |
| for (j = 0; j < FormatsCount; j++) |
| { |
| /* Do the main wave_format_extensible structure */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt3, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPushSubtable (Subtable); |
| |
| /* Do the capabilities list */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt3a, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| DtPopSubtable (); |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| } /* for (j = 0; j < FormatsCount; j++) */ |
| |
| /* |
| * If we are not done with the current Endpoint yet, then there must be |
| * some non documented structure(s) yet to be processed. First, get |
| * the count of such structure(s). |
| */ |
| if (*PFieldList && !(strcmp ((const char *) (*PFieldList)->Name, "Device Info struct count"))) |
| { |
| /* Get the count of non documented structures */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt7, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| DeviceInfo = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_INFO_COUNT, Subtable->Buffer); |
| DeviceInfoCount = DeviceInfo->StructureCount; |
| |
| for (j = 0; j < DeviceInfoCount; j++) |
| { |
| /* |
| * Compile the following Device Info fields: |
| * 1) Device ID |
| * 2) Device Instance ID |
| * 3) Device Port ID |
| */ |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt7a, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| } /* for (j = 0; j < LinuxSpecificCount; j++) */ |
| |
| /* Undocumented data at the end of endpoint */ |
| if (*PFieldList && !(strcmp ((const char *) (*PFieldList)->Name, "Bytes"))) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt7b, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| } |
| } |
| |
| DtPopSubtable (); |
| |
| } /* for (i = 0; i < EndpointCount; i++) */ |
| |
| /* |
| * All Endpoint Descriptors are completed. |
| * Do the table terminator specific config (not in NHLT spec, optional) |
| */ |
| if (*PFieldList && !(strcmp ((const char *) (*PFieldList)->Name, "Capabilities Size"))) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt5b, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| Terminator = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B, Subtable->Buffer); |
| |
| if (Terminator->CapabilitiesSize) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoNhlt3a, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| } |
| } |
| |
| return (AE_OK); |
| } |
| |
| 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); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| /* Subtables */ |
| |
| while (*PFieldList) |
| { |
| SubtableStart = *PFieldList; |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPcctHdr, |
| &Subtable); |
| 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; |
| |
| case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2: |
| |
| InfoTable = AcpiDmTableInfoPcct2; |
| break; |
| |
| case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE: |
| |
| InfoTable = AcpiDmTableInfoPcct3; |
| break; |
| |
| case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE: |
| |
| InfoTable = AcpiDmTableInfoPcct4; |
| break; |
| |
| case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE: |
| |
| InfoTable = AcpiDmTableInfoPcct5; |
| break; |
| |
| default: |
| |
| DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PCCT"); |
| return (AE_ERROR); |
| } |
| |
| Status = DtCompileTable (PFieldList, InfoTable, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPopSubtable (); |
| } |
| |
| return (AE_OK); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: DtCompilePdtt |
| * |
| * PARAMETERS: List - Current field list pointer |
| * |
| * RETURN: Status |
| * |
| * DESCRIPTION: Compile PDTT. |
| * |
| *****************************************************************************/ |
| |
| ACPI_STATUS |
| DtCompilePdtt ( |
| void **List) |
| { |
| ACPI_STATUS Status; |
| DT_SUBTABLE *Subtable; |
| DT_SUBTABLE *ParentTable; |
| DT_FIELD **PFieldList = (DT_FIELD **) List; |
| ACPI_TABLE_PDTT *PdttHeader; |
| UINT32 Count = 0; |
| |
| |
| /* Main table */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| PdttHeader = ACPI_CAST_PTR (ACPI_TABLE_PDTT, ParentTable->Buffer); |
| PdttHeader->ArrayOffset = sizeof (ACPI_TABLE_PDTT); |
| |
| /* There is only one type of subtable at this time, no need to decode */ |
| |
| while (*PFieldList) |
| { |
| /* List of subchannel IDs, each 2 bytes */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPdtt0, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| DtInsertSubtable (ParentTable, Subtable); |
| Count++; |
| } |
| |
| PdttHeader->TriggerCount = (UINT8) Count; |
| return (AE_OK); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: DtCompilePhat |
| * |
| * PARAMETERS: List - Current field list pointer |
| * |
| * RETURN: Status |
| * |
| * DESCRIPTION: Compile Phat. |
| * |
| *****************************************************************************/ |
| |
| ACPI_STATUS |
| DtCompilePhat ( |
| void **List) |
| { |
| ACPI_STATUS Status = AE_OK; |
| DT_SUBTABLE *Subtable; |
| DT_SUBTABLE *ParentTable; |
| DT_FIELD **PFieldList = (DT_FIELD **) List; |
| ACPI_PHAT_HEADER *PhatHeader; |
| ACPI_DMTABLE_INFO *Info; |
| ACPI_PHAT_VERSION_DATA *VersionData; |
| UINT32 DeviceDataLength; |
| UINT32 RecordCount; |
| DT_FIELD *DataOffsetField; |
| DT_FIELD *DevicePathField; |
| UINT32 TableOffset = 0; |
| UINT32 DataOffsetValue; |
| UINT32 i; |
| |
| |
| /* The table consists of subtables */ |
| |
| while (*PFieldList) |
| { |
| /* Compile the common subtable header */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhatHdr, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| TableOffset += Subtable->Length; |
| DbgPrint (ASL_DEBUG_OUTPUT, "0 Subtable->Length: %X\n", Subtable->Length); |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPushSubtable (Subtable); |
| |
| PhatHeader = ACPI_CAST_PTR (ACPI_PHAT_HEADER, Subtable->Buffer); |
| |
| switch (PhatHeader->Type) |
| { |
| case ACPI_PHAT_TYPE_FW_VERSION_DATA: |
| |
| /* Compile the middle portion of the Firmware Version Data */ |
| |
| Info = AcpiDmTableInfoPhat0; |
| PhatHeader->Length = sizeof (ACPI_PHAT_VERSION_DATA); |
| DataOffsetField = NULL; |
| break; |
| |
| case ACPI_PHAT_TYPE_FW_HEALTH_DATA: |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "1 Offset: %X, Name: \"%s\" Length: %X\n", |
| (*PFieldList)->TableOffset, (*PFieldList)->Name, Subtable->Length); |
| |
| DataOffsetField = *PFieldList; |
| |
| /* Walk the field list to get to the "Device-specific data Offset" field */ |
| |
| TableOffset = sizeof (ACPI_PHAT_HEALTH_DATA); |
| for (i = 0; i < 3; i++) |
| { |
| DataOffsetField = DataOffsetField->Next; |
| DbgPrint (ASL_DEBUG_OUTPUT, "2 Offset: %X, Name: \"%s\" Length: %X Value: %s:\n", |
| TableOffset, DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value); |
| } |
| |
| /* Convert DataOffsetField->Value (a char * string) to an integer value */ |
| |
| sscanf (DataOffsetField->Value, "%X", &DataOffsetValue); |
| |
| /* |
| * Get the next field (Device Path): |
| * DataOffsetField points to "Device-Specific Offset", next field is |
| * "Device Path". |
| */ |
| DevicePathField = DataOffsetField->Next; |
| |
| /* Compute the size of the input ASCII string as a unicode string (*2 + 2) */ |
| |
| DevicePathField->StringLength = (strlen ((const char *) DevicePathField->Value) * 2) + 2; |
| TableOffset += DevicePathField->StringLength; |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "3 Offset: %X, Length: %X devicepathLength: %X\n", |
| TableOffset, Subtable->Length, DevicePathField->StringLength); |
| |
| /* Set the DataOffsetField to the current TableOffset */ |
| /* Must set the DataOffsetField here (not later) */ |
| |
| if (DataOffsetValue != 0) |
| { |
| snprintf (DataOffsetField->Value, Subtable->Length, "%X", TableOffset); |
| } |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "4 Offset: %X, Length: %X\n", TableOffset, Subtable->Length); |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "5 TableOffset: %X, DataOffsetField->StringLength: " |
| "%X DevicePathField Length: %X DevicePathField->Value: %s, DataOffsetField->Value: %s DataOffsetField->ByteOffset %X\n", |
| TableOffset, DataOffsetField->StringLength, DevicePathField->StringLength, |
| DevicePathField->Value, DataOffsetField->Value, DataOffsetField->ByteOffset); |
| |
| /* Compile the middle portion of the Health Data Record */ |
| |
| Info = AcpiDmTableInfoPhat1; |
| PhatHeader->Length = sizeof (ACPI_PHAT_HEALTH_DATA); |
| break; |
| |
| default: |
| |
| DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT"); |
| return (AE_ERROR); |
| } |
| |
| /* Compile either the Version Data or the Health Data */ |
| |
| Status = DtCompileTable (PFieldList, Info, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "6 Offset: %X, Name: \"%s\" SubtableLength: %X\n", |
| TableOffset /* - StartTableOffset*/, (*PFieldList)->Name, Subtable->Length); |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| switch (PhatHeader->Type) |
| { |
| case ACPI_PHAT_TYPE_FW_VERSION_DATA: |
| |
| VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA, |
| (Subtable->Buffer - sizeof (ACPI_PHAT_HEADER))); |
| RecordCount = VersionData->ElementCount; |
| |
| /* Compile all of the Version Elements */ |
| |
| while (RecordCount) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat0a, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| TableOffset += Subtable->Length; |
| RecordCount--; |
| PhatHeader->Length += sizeof (ACPI_PHAT_VERSION_ELEMENT); |
| } |
| |
| DtPopSubtable (); |
| break; |
| |
| case ACPI_PHAT_TYPE_FW_HEALTH_DATA: |
| |
| /* Compile the Device Path */ |
| |
| DeviceDataLength = Subtable->Length; |
| TableOffset += Subtable->Length; |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "7 Device Path Length: %X FieldName: \"%s\" FieldLength: " |
| "%s FieldValue: %s SubtableLength: %X TableOffset: %X\n", DeviceDataLength, |
| (*PFieldList)->Name, DataOffsetField->Value, (*PFieldList)->Value, |
| Subtable->Length, TableOffset); |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1a, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| /* *PFieldList will be null if previous field was at the end-of-ParseTree (EOF) */ |
| |
| if (!*PFieldList) |
| { |
| DbgPrint (ASL_DEBUG_OUTPUT, "8 Exit on end-of-ParseTree\n"); |
| return (AE_OK); |
| } |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "9 Device Data Length: %X FieldName: \"%s" |
| " TableOffset: %X FieldLength: %X Field Value: %s SubtableLength: %X\n", |
| DeviceDataLength, (*PFieldList)->Name, TableOffset, |
| (*PFieldList)->StringLength, (*PFieldList)->Value, Subtable->Length); |
| |
| PhatHeader->Length += (UINT16) Subtable->Length; |
| |
| /* Convert DataOffsetField->Value (a hex char * string) to an integer value */ |
| |
| sscanf (DataOffsetField->Value, "%X", &DataOffsetValue); |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "10 Device-Specific Offset: %X Table Offset: %X\n", |
| DataOffsetValue, TableOffset); |
| if (DataOffsetValue != 0) |
| { |
| /* Compile Device-Specific Data - only if the Data Offset is non-zero */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPhat1b, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "11 Subtable: %p Table Offset: %X\n", |
| Subtable, TableOffset); |
| if (Subtable) |
| { |
| DbgPrint (ASL_DEBUG_OUTPUT, "12 Device Specific Offset: " |
| "%X FieldName \"%s\" SubtableLength %X\n", |
| DeviceDataLength, DataOffsetField->Name, Subtable->Length); |
| |
| DeviceDataLength += Subtable->Length; |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| PhatHeader->Length += (UINT16) Subtable->Length; |
| } |
| } |
| |
| DtPopSubtable (); |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "13 FieldName: \"%s\" FieldLength: %X Field Value: %s\n", |
| DataOffsetField->Name, DataOffsetField->StringLength, DataOffsetField->Value); |
| break; |
| |
| default: |
| |
| DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, *PFieldList, "PHAT"); |
| return (AE_ERROR); |
| } |
| } |
| |
| return (Status); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * 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; |
| UINT16 Type; |
| |
| |
| /* Main table */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPushSubtable (Subtable); |
| |
| /* Subtables */ |
| |
| while (*PFieldList) |
| { |
| SubtableStart = *PFieldList; |
| DtCompileInteger ((UINT8 *) &Type, *PFieldList, 2, 0); |
| |
| switch (Type) |
| { |
| case ACPI_PMTT_TYPE_SOCKET: |
| |
| /* Subtable: Socket Structure */ |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_SOCKET (0)\n"); |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt0, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| break; |
| |
| case ACPI_PMTT_TYPE_CONTROLLER: |
| |
| /* Subtable: Memory Controller Structure */ |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_CONTROLLER (1)\n"); |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt1, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| break; |
| |
| case ACPI_PMTT_TYPE_DIMM: |
| |
| /* Subtable: Physical Component (DIMM) Structure */ |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_DIMM (2)\n"); |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmtt2, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| break; |
| |
| case ACPI_PMTT_TYPE_VENDOR: |
| |
| /* Subtable: Vendor-specific Structure */ |
| |
| DbgPrint (ASL_DEBUG_OUTPUT, "Compile PMTT_TYPE_VENDOR(FF)\n"); |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPmttVendor, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| break; |
| |
| default: |
| |
| DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PMTT"); |
| return (AE_ERROR); |
| } |
| |
| DtInsertSubtable (ParentTable, Subtable); |
| } |
| |
| return (Status); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: DtCompilePptt |
| * |
| * PARAMETERS: List - Current field list pointer |
| * |
| * RETURN: Status |
| * |
| * DESCRIPTION: Compile PPTT. |
| * |
| *****************************************************************************/ |
| |
| ACPI_STATUS |
| DtCompilePptt ( |
| void **List) |
| { |
| ACPI_STATUS Status; |
| ACPI_SUBTABLE_HEADER *PpttHeader; |
| ACPI_PPTT_PROCESSOR *PpttProcessor = NULL; |
| DT_SUBTABLE *Subtable; |
| DT_SUBTABLE *ParentTable; |
| ACPI_DMTABLE_INFO *InfoTable; |
| DT_FIELD **PFieldList = (DT_FIELD **) List; |
| DT_FIELD *SubtableStart; |
| ACPI_TABLE_HEADER *PpttAcpiHeader; |
| |
| |
| ParentTable = DtPeekSubtable (); |
| while (*PFieldList) |
| { |
| SubtableStart = *PFieldList; |
| |
| /* Compile PPTT subtable header */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPpttHdr, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| DtInsertSubtable (ParentTable, Subtable); |
| PpttHeader = ACPI_CAST_PTR (ACPI_SUBTABLE_HEADER, Subtable->Buffer); |
| PpttHeader->Length = (UINT8)(Subtable->Length); |
| |
| switch (PpttHeader->Type) |
| { |
| case ACPI_PPTT_TYPE_PROCESSOR: |
| |
| InfoTable = AcpiDmTableInfoPptt0; |
| break; |
| |
| case ACPI_PPTT_TYPE_CACHE: |
| |
| InfoTable = AcpiDmTableInfoPptt1; |
| break; |
| |
| case ACPI_PPTT_TYPE_ID: |
| |
| InfoTable = AcpiDmTableInfoPptt2; |
| break; |
| |
| default: |
| |
| DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "PPTT"); |
| return (AE_ERROR); |
| } |
| |
| /* Compile PPTT subtable body */ |
| |
| Status = DtCompileTable (PFieldList, InfoTable, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| DtInsertSubtable (ParentTable, Subtable); |
| PpttHeader->Length += (UINT8)(Subtable->Length); |
| |
| /* Compile PPTT subtable additional */ |
| |
| switch (PpttHeader->Type) |
| { |
| case ACPI_PPTT_TYPE_PROCESSOR: |
| |
| PpttProcessor = ACPI_SUB_PTR (ACPI_PPTT_PROCESSOR, |
| Subtable->Buffer, sizeof (ACPI_SUBTABLE_HEADER)); |
| if (PpttProcessor) |
| { |
| /* Compile initiator proximity domain list */ |
| |
| PpttProcessor->NumberOfPrivResources = 0; |
| while (*PFieldList) |
| { |
| Status = DtCompileTable (PFieldList, |
| AcpiDmTableInfoPptt0a, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| if (!Subtable) |
| { |
| break; |
| } |
| |
| DtInsertSubtable (ParentTable, Subtable); |
| PpttHeader->Length += (UINT8)(Subtable->Length); |
| PpttProcessor->NumberOfPrivResources++; |
| } |
| } |
| break; |
| |
| case ACPI_PPTT_TYPE_CACHE: |
| |
| PpttAcpiHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, |
| AslGbl_RootTable->Buffer); |
| if (PpttAcpiHeader->Revision < 3) |
| { |
| break; |
| } |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPptt1a, |
| &Subtable); |
| DtInsertSubtable (ParentTable, Subtable); |
| PpttHeader->Length += (UINT8)(Subtable->Length); |
| break; |
| |
| default: |
| |
| break; |
| } |
| } |
| |
| return (AE_OK); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: DtCompilePrmt |
| * |
| * PARAMETERS: List - Current field list pointer |
| * |
| * RETURN: Status |
| * |
| * DESCRIPTION: Compile PRMT. |
| * |
| *****************************************************************************/ |
| |
| ACPI_STATUS |
| DtCompilePrmt ( |
| void **List) |
| { |
| ACPI_STATUS Status; |
| ACPI_TABLE_PRMT_HEADER *PrmtHeader; |
| ACPI_PRMT_MODULE_INFO *PrmtModuleInfo; |
| DT_SUBTABLE *Subtable; |
| DT_SUBTABLE *ParentTable; |
| DT_FIELD **PFieldList = (DT_FIELD **) List; |
| UINT32 i, j; |
| |
| ParentTable = DtPeekSubtable (); |
| |
| /* Compile PRMT subtable header */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHdr, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| DtInsertSubtable (ParentTable, Subtable); |
| PrmtHeader = ACPI_CAST_PTR (ACPI_TABLE_PRMT_HEADER, Subtable->Buffer); |
| |
| for (i = 0; i < PrmtHeader->ModuleInfoCount; i++) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtModule, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| DtInsertSubtable (ParentTable, Subtable); |
| PrmtModuleInfo = ACPI_CAST_PTR (ACPI_PRMT_MODULE_INFO, Subtable->Buffer); |
| |
| for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; j++) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoPrmtHandler, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| DtInsertSubtable (ParentTable, Subtable); |
| } |
| } |
| |
| return (AE_OK); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: DtCompileRgrt |
| * |
| * PARAMETERS: List - Current field list pointer |
| * |
| * RETURN: Status |
| * |
| * DESCRIPTION: Compile RGRT. |
| * |
| *****************************************************************************/ |
| |
| ACPI_STATUS |
| DtCompileRgrt ( |
| void **List) |
| { |
| ACPI_STATUS Status; |
| DT_SUBTABLE *Subtable; |
| DT_SUBTABLE *ParentTable; |
| DT_FIELD **PFieldList = (DT_FIELD **) List; |
| |
| |
| /* Compile the main table */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| /* Compile the "Subtable" -- actually just the binary (PNG) image */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoRgrt0, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| DtInsertSubtable (ParentTable, Subtable); |
| return (AE_OK); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: DtCompileRhct |
| * |
| * PARAMETERS: List - Current field list pointer |
| * |
| * RETURN: Status |
| * |
| * DESCRIPTION: Compile RHCT. |
| * |
| *****************************************************************************/ |
| |
| ACPI_STATUS |
| DtCompileRhct ( |
| void **List) |
| { |
| ACPI_STATUS Status; |
| ACPI_RHCT_NODE_HEADER *RhctHeader; |
| ACPI_RHCT_HART_INFO *RhctHartInfo = NULL; |
| DT_SUBTABLE *Subtable; |
| DT_SUBTABLE *ParentTable; |
| ACPI_DMTABLE_INFO *InfoTable; |
| DT_FIELD **PFieldList = (DT_FIELD **) List; |
| DT_FIELD *SubtableStart; |
| |
| |
| /* Compile the main table */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhct, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| while (*PFieldList) |
| { |
| SubtableStart = *PFieldList; |
| |
| /* Compile RHCT subtable header */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoRhctNodeHdr, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| DtInsertSubtable (ParentTable, Subtable); |
| RhctHeader = ACPI_CAST_PTR (ACPI_RHCT_NODE_HEADER, Subtable->Buffer); |
| RhctHeader->Length = (UINT16)(Subtable->Length); |
| |
| switch (RhctHeader->Type) |
| { |
| case ACPI_RHCT_NODE_TYPE_ISA_STRING: |
| |
| InfoTable = AcpiDmTableInfoRhctIsa1; |
| break; |
| |
| case ACPI_RHCT_NODE_TYPE_HART_INFO: |
| |
| InfoTable = AcpiDmTableInfoRhctHartInfo1; |
| break; |
| |
| default: |
| |
| DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "RHCT"); |
| return (AE_ERROR); |
| } |
| |
| /* Compile RHCT subtable body */ |
| |
| Status = DtCompileTable (PFieldList, InfoTable, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| DtInsertSubtable (ParentTable, Subtable); |
| RhctHeader->Length += (UINT16)(Subtable->Length); |
| |
| /* Compile RHCT subtable additionals */ |
| |
| switch (RhctHeader->Type) |
| { |
| case ACPI_RHCT_NODE_TYPE_HART_INFO: |
| |
| RhctHartInfo = ACPI_SUB_PTR (ACPI_RHCT_HART_INFO, |
| Subtable->Buffer, sizeof (ACPI_RHCT_NODE_HEADER)); |
| if (RhctHartInfo) |
| { |
| |
| RhctHartInfo->NumOffsets = 0; |
| while (*PFieldList) |
| { |
| Status = DtCompileTable (PFieldList, |
| AcpiDmTableInfoRhctHartInfo2, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| if (!Subtable) |
| { |
| break; |
| } |
| |
| DtInsertSubtable (ParentTable, Subtable); |
| RhctHeader->Length += (UINT16)(Subtable->Length); |
| RhctHartInfo->NumOffsets++; |
| } |
| } |
| break; |
| |
| default: |
| |
| break; |
| } |
| } |
| |
| return (AE_OK); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * 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_FPDT_HEADER *S3ptHeader; |
| DT_SUBTABLE *Subtable; |
| DT_SUBTABLE *ParentTable; |
| ACPI_DMTABLE_INFO *InfoTable; |
| DT_FIELD *SubtableStart; |
| |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3pt, |
| &AslGbl_RootTable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| DtPushSubtable (AslGbl_RootTable); |
| |
| while (*PFieldList) |
| { |
| SubtableStart = *PFieldList; |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoS3ptHdr, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPushSubtable (Subtable); |
| |
| S3ptHeader = ACPI_CAST_PTR (ACPI_FPDT_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); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPopSubtable (); |
| } |
| |
| return (AE_OK); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: DtCompileSdev |
| * |
| * PARAMETERS: List - Current field list pointer |
| * |
| * RETURN: Status |
| * |
| * DESCRIPTION: Compile SDEV. |
| * |
| *****************************************************************************/ |
| |
| ACPI_STATUS |
| DtCompileSdev ( |
| void **List) |
| { |
| ACPI_STATUS Status; |
| ACPI_SDEV_HEADER *SdevHeader; |
| ACPI_SDEV_HEADER *SecureComponentHeader; |
| DT_SUBTABLE *Subtable; |
| DT_SUBTABLE *ParentTable; |
| ACPI_DMTABLE_INFO *InfoTable; |
| ACPI_DMTABLE_INFO *SecureComponentInfoTable = NULL; |
| DT_FIELD **PFieldList = (DT_FIELD **) List; |
| DT_FIELD *SubtableStart; |
| ACPI_SDEV_PCIE *Pcie = NULL; |
| ACPI_SDEV_NAMESPACE *Namesp = NULL; |
| UINT32 EntryCount; |
| ACPI_SDEV_SECURE_COMPONENT *SecureComponent = NULL; |
| UINT16 ComponentLength = 0; |
| |
| |
| /* Subtables */ |
| |
| while (*PFieldList) |
| { |
| /* Compile common SDEV subtable header */ |
| |
| SubtableStart = *PFieldList; |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevHdr, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPushSubtable (Subtable); |
| |
| SdevHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); |
| SdevHeader->Length = (UINT8)(sizeof (ACPI_SDEV_HEADER)); |
| |
| switch (SdevHeader->Type) |
| { |
| case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: |
| |
| InfoTable = AcpiDmTableInfoSdev0; |
| Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable->Buffer); |
| SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT, |
| ACPI_ADD_PTR (UINT8, Subtable->Buffer, sizeof(ACPI_SDEV_NAMESPACE))); |
| break; |
| |
| case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: |
| |
| InfoTable = AcpiDmTableInfoSdev1; |
| Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable->Buffer); |
| break; |
| |
| default: |
| |
| DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); |
| return (AE_ERROR); |
| } |
| |
| /* Compile SDEV subtable body */ |
| |
| Status = DtCompileTable (PFieldList, InfoTable, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| /* Optional data fields are appended to the main subtable body */ |
| |
| switch (SdevHeader->Type) |
| { |
| case ACPI_SDEV_TYPE_NAMESPACE_DEVICE: |
| |
| /* |
| * Device Id Offset will be be calculated differently depending on |
| * the presence of secure access components. |
| */ |
| Namesp->DeviceIdOffset = 0; |
| ComponentLength = 0; |
| |
| /* If the secure access component exists, get the structures */ |
| |
| if (SdevHeader->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0b, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT); |
| |
| /* Compile a secure access component header */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdevSecCompHdr, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| /* Compile the secure access component */ |
| |
| SecureComponentHeader = ACPI_CAST_PTR (ACPI_SDEV_HEADER, Subtable->Buffer); |
| switch (SecureComponentHeader->Type) |
| { |
| case ACPI_SDEV_TYPE_ID_COMPONENT: |
| |
| SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId; |
| Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_ID_COMPONENT); |
| ComponentLength = sizeof (ACPI_SDEV_ID_COMPONENT); |
| break; |
| |
| case ACPI_SDEV_TYPE_MEM_COMPONENT: |
| |
| SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem; |
| Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_MEM_COMPONENT); |
| ComponentLength = sizeof (ACPI_SDEV_MEM_COMPONENT); |
| break; |
| |
| default: |
| |
| /* Any other secure component types are undefined */ |
| |
| return (AE_ERROR); |
| } |
| |
| Status = DtCompileTable (PFieldList, SecureComponentInfoTable, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| SecureComponent->SecureComponentOffset = |
| sizeof (ACPI_SDEV_NAMESPACE) + sizeof (ACPI_SDEV_SECURE_COMPONENT); |
| SecureComponent->SecureComponentLength = ComponentLength; |
| |
| |
| /* |
| * Add the secure component to the subtable to be added for the |
| * the namespace subtable's length |
| */ |
| ComponentLength += sizeof (ACPI_SDEV_SECURE_COMPONENT); |
| } |
| |
| /* Append DeviceId namespace string */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev0a, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| if (!Subtable) |
| { |
| break; |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| Namesp->DeviceIdOffset += sizeof (ACPI_SDEV_NAMESPACE); |
| |
| Namesp->DeviceIdLength = (UINT16) Subtable->Length; |
| |
| /* Append Vendor data */ |
| |
| Namesp->VendorDataLength = 0; |
| Namesp->VendorDataOffset = 0; |
| |
| if (*PFieldList) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| if (Subtable) |
| { |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| Namesp->VendorDataOffset = |
| Namesp->DeviceIdOffset + Namesp->DeviceIdLength; |
| Namesp->VendorDataLength = |
| (UINT16) Subtable->Length; |
| |
| /* Final size of entire namespace structure */ |
| |
| SdevHeader->Length = (UINT16)(sizeof(ACPI_SDEV_NAMESPACE) + |
| Subtable->Length + Namesp->DeviceIdLength) + ComponentLength; |
| } |
| } |
| |
| break; |
| |
| case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE: |
| |
| /* Append the PCIe path info first */ |
| |
| EntryCount = 0; |
| while (*PFieldList && !strcmp ((*PFieldList)->Name, "Device")) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1a, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| if (!Subtable) |
| { |
| DtPopSubtable (); |
| break; |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| EntryCount++; |
| } |
| |
| /* Path offset will point immediately after the main subtable */ |
| |
| Pcie->PathOffset = sizeof (ACPI_SDEV_PCIE); |
| Pcie->PathLength = (UINT16) |
| (EntryCount * sizeof (ACPI_SDEV_PCIE_PATH)); |
| |
| /* Append the Vendor Data last */ |
| |
| Pcie->VendorDataLength = 0; |
| Pcie->VendorDataOffset = 0; |
| |
| if (*PFieldList) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoSdev1b, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| if (Subtable) |
| { |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| Pcie->VendorDataOffset = |
| Pcie->PathOffset + Pcie->PathLength; |
| Pcie->VendorDataLength = (UINT16) |
| Subtable->Length; |
| } |
| } |
| |
| SdevHeader->Length = |
| sizeof (ACPI_SDEV_PCIE) + |
| Pcie->PathLength + Pcie->VendorDataLength; |
| break; |
| |
| default: |
| |
| DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SDEV"); |
| return (AE_ERROR); |
| } |
| |
| 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); |
| 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; |
| DT_FIELD *EndOfFieldList = NULL; |
| UINT32 Localities; |
| UINT32 LocalityListLength; |
| UINT8 *LocalityBuffer; |
| |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoSlit, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| Localities = *ACPI_CAST_PTR (UINT32, Subtable->Buffer); |
| LocalityBuffer = UtLocalCalloc (Localities); |
| LocalityListLength = 0; |
| |
| /* Compile each locality buffer */ |
| |
| FieldList = *PFieldList; |
| while (FieldList) |
| { |
| DtCompileBuffer (LocalityBuffer, |
| FieldList->Value, FieldList, Localities); |
| |
| LocalityListLength++; |
| DtCreateSubtable (LocalityBuffer, Localities, &Subtable); |
| DtInsertSubtable (ParentTable, Subtable); |
| EndOfFieldList = FieldList; |
| FieldList = FieldList->Next; |
| } |
| |
| if (LocalityListLength != Localities) |
| { |
| sprintf(AslGbl_MsgBuffer, |
| "Found %u entries, must match LocalityCount: %u", |
| LocalityListLength, Localities); |
| DtError (ASL_ERROR, ASL_MSG_ENTRY_LIST, EndOfFieldList, AslGbl_MsgBuffer); |
| ACPI_FREE (LocalityBuffer); |
| return (AE_LIMIT); |
| } |
| |
| 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); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| while (*PFieldList) |
| { |
| SubtableStart = *PFieldList; |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoSratHdr, |
| &Subtable); |
| 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; |
| |
| case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY: |
| |
| InfoTable = AcpiDmTableInfoSrat4; |
| break; |
| |
| case ACPI_SRAT_TYPE_GENERIC_AFFINITY: |
| |
| InfoTable = AcpiDmTableInfoSrat5; |
| break; |
| |
| case ACPI_SRAT_TYPE_GENERIC_PORT_AFFINITY: |
| |
| InfoTable = AcpiDmTableInfoSrat6; |
| break; |
| |
| default: |
| |
| DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT"); |
| return (AE_ERROR); |
| } |
| |
| Status = DtCompileTable (PFieldList, InfoTable, &Subtable); |
| 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); |
| 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); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| } |
| |
| return (AE_OK); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: DtCompileSvkl |
| * |
| * PARAMETERS: PFieldList - Current field list pointer |
| * |
| * RETURN: Status |
| * |
| * DESCRIPTION: Compile SVKL. |
| * |
| * NOTES: SVKL is essentially a flat table, with a small main table and |
| * a variable number of a single type of subtable. |
| * |
| *****************************************************************************/ |
| |
| ACPI_STATUS |
| DtCompileSvkl ( |
| void **List) |
| { |
| DT_FIELD **PFieldList = (DT_FIELD **) List; |
| DT_SUBTABLE *Subtable; |
| DT_SUBTABLE *ParentTable; |
| ACPI_STATUS Status; |
| |
| |
| /* Compile the main table */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| /* Compile each subtable */ |
| |
| while (*PFieldList) |
| { |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoSvkl0, |
| &Subtable); |
| 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); |
| 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); |
| break; |
| |
| case ACPI_TCPA_SERVER_TABLE: |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoTcpaServer, |
| &Subtable); |
| 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: DtCompileTpm2Rev3 |
| * |
| * PARAMETERS: PFieldList - Current field list pointer |
| * |
| * RETURN: Status |
| * |
| * DESCRIPTION: Compile TPM2 revision 3 |
| * |
| *****************************************************************************/ |
| static ACPI_STATUS |
| DtCompileTpm2Rev3 ( |
| void **List) |
| { |
| DT_FIELD **PFieldList = (DT_FIELD **) List; |
| DT_SUBTABLE *Subtable; |
| ACPI_TABLE_TPM23 *Tpm23Header; |
| DT_SUBTABLE *ParentTable; |
| ACPI_STATUS Status = AE_OK; |
| |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23, |
| &Subtable); |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| Tpm23Header = ACPI_CAST_PTR (ACPI_TABLE_TPM23, ParentTable->Buffer); |
| |
| /* Subtable type depends on the StartMethod */ |
| |
| switch (Tpm23Header->StartMethod) |
| { |
| case ACPI_TPM23_ACPI_START_METHOD: |
| |
| /* Subtable specific to to ARM_SMC */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm23a, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| break; |
| |
| default: |
| break; |
| } |
| |
| return (Status); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * FUNCTION: DtCompileTpm2 |
| * |
| * PARAMETERS: PFieldList - Current field list pointer |
| * |
| * RETURN: Status |
| * |
| * DESCRIPTION: Compile TPM2. |
| * |
| *****************************************************************************/ |
| |
| ACPI_STATUS |
| DtCompileTpm2 ( |
| void **List) |
| { |
| DT_FIELD **PFieldList = (DT_FIELD **) List; |
| DT_SUBTABLE *Subtable; |
| ACPI_TABLE_TPM2 *Tpm2Header; |
| DT_SUBTABLE *ParentTable; |
| ACPI_STATUS Status = AE_OK; |
| ACPI_TABLE_HEADER *Header; |
| |
| |
| ParentTable = DtPeekSubtable (); |
| |
| Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer); |
| |
| if (Header->Revision == 3) |
| { |
| return (DtCompileTpm2Rev3 (List)); |
| } |
| |
| /* Compile the main table */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| Tpm2Header = ACPI_CAST_PTR (ACPI_TABLE_TPM2, ParentTable->Buffer); |
| |
| /* Method parameters */ |
| /* Optional: Log area minimum length */ |
| /* Optional: Log area start address */ |
| /* TBD: Optional fields above not fully implemented (not optional at this time) */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm2a, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| |
| /* Subtable type depends on the StartMethod */ |
| |
| switch (Tpm2Header->StartMethod) |
| { |
| case ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC: |
| |
| /* Subtable specific to to ARM_SMC */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoTpm211, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| break; |
| |
| case ACPI_TPM2_START_METHOD: |
| case ACPI_TPM2_MEMORY_MAPPED: |
| case ACPI_TPM2_COMMAND_BUFFER: |
| case ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD: |
| break; |
| |
| case ACPI_TPM2_RESERVED1: |
| case ACPI_TPM2_RESERVED3: |
| case ACPI_TPM2_RESERVED4: |
| case ACPI_TPM2_RESERVED5: |
| case ACPI_TPM2_RESERVED9: |
| case ACPI_TPM2_RESERVED10: |
| |
| AcpiOsPrintf ("\n**** Reserved TPM2 Start Method type 0x%X\n", |
| Tpm2Header->StartMethod); |
| Status = AE_ERROR; |
| break; |
| |
| case ACPI_TPM2_NOT_ALLOWED: |
| default: |
| |
| AcpiOsPrintf ("\n**** Unknown TPM2 Start Method type 0x%X\n", |
| Tpm2Header->StartMethod); |
| Status = AE_ERROR; |
| break; |
| } |
| |
| 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); |
| 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: DtCompileViot |
| * |
| * PARAMETERS: List - Current field list pointer |
| * |
| * RETURN: Status |
| * |
| * DESCRIPTION: Compile VIOT. |
| * |
| *****************************************************************************/ |
| |
| ACPI_STATUS |
| DtCompileViot ( |
| void **List) |
| { |
| ACPI_STATUS Status; |
| DT_SUBTABLE *Subtable; |
| DT_SUBTABLE *ParentTable; |
| DT_FIELD **PFieldList = (DT_FIELD **) List; |
| DT_FIELD *SubtableStart; |
| ACPI_TABLE_VIOT *Viot; |
| ACPI_VIOT_HEADER *ViotHeader; |
| ACPI_DMTABLE_INFO *InfoTable; |
| UINT16 NodeCount; |
| |
| ParentTable = DtPeekSubtable (); |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoViot, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| DtInsertSubtable (ParentTable, Subtable); |
| |
| /* |
| * Using ACPI_SUB_PTR, We needn't define a separate structure. Care |
| * should be taken to avoid accessing ACPI_TABLE_HEADER fields. |
| */ |
| Viot = ACPI_SUB_PTR (ACPI_TABLE_VIOT, Subtable->Buffer, |
| sizeof (ACPI_TABLE_HEADER)); |
| |
| Viot->NodeOffset = sizeof (ACPI_TABLE_VIOT); |
| |
| NodeCount = 0; |
| while (*PFieldList) { |
| SubtableStart = *PFieldList; |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoViotHeader, |
| &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPushSubtable (Subtable); |
| |
| ViotHeader = ACPI_CAST_PTR (ACPI_VIOT_HEADER, Subtable->Buffer); |
| |
| switch (ViotHeader->Type) |
| { |
| case ACPI_VIOT_NODE_PCI_RANGE: |
| |
| InfoTable = AcpiDmTableInfoViot1; |
| break; |
| |
| case ACPI_VIOT_NODE_MMIO: |
| |
| InfoTable = AcpiDmTableInfoViot2; |
| break; |
| |
| case ACPI_VIOT_NODE_VIRTIO_IOMMU_PCI: |
| |
| InfoTable = AcpiDmTableInfoViot3; |
| break; |
| |
| case ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO: |
| |
| InfoTable = AcpiDmTableInfoViot4; |
| break; |
| |
| default: |
| |
| DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "VIOT"); |
| return (AE_ERROR); |
| } |
| |
| Status = DtCompileTable (PFieldList, InfoTable, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| DtPopSubtable (); |
| NodeCount++; |
| } |
| |
| Viot->NodeCount = NodeCount; |
| return (AE_OK); |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * 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; |
| |
| |
| /* Compile the main table */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| ParentTable = DtPeekSubtable (); |
| DtInsertSubtable (ParentTable, Subtable); |
| Table = ACPI_CAST_PTR (ACPI_TABLE_WPBT, ParentTable->Buffer); |
| |
| /* |
| * Exit now if there are no arguments specified. This is indicated by: |
| * The "Command-line Arguments" field has not been specified (if specified, |
| * it will be the last field in the field list -- after the main table). |
| * Set the Argument Length in the main table to zero. |
| */ |
| if (!*PFieldList) |
| { |
| Table->ArgumentsLength = 0; |
| return (AE_OK); |
| } |
| |
| /* Compile the argument list subtable */ |
| |
| Status = DtCompileTable (PFieldList, AcpiDmTableInfoWpbt0, &Subtable); |
| if (ACPI_FAILURE (Status)) |
| { |
| return (Status); |
| } |
| |
| /* Extract the length of the Arguments buffer, insert into main table */ |
| |
| Table->ArgumentsLength = (UINT16) Subtable->TotalLength; |
| 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 (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", |
| (*PFieldList)->Name); |
| DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, |
| (*PFieldList), AslGbl_MsgBuffer); |
| |
| *PFieldList = (*PFieldList)->Next; |
| continue; |
| } |
| |
| Status = DtCompileTable (PFieldList, Info, |
| &Subtable); |
| if (ACPI_SUCCESS (Status)) |
| { |
| DtInsertSubtable (ParentTable, Subtable); |
| if (Length) |
| { |
| *Length += Subtable->Length; |
| } |
| } |
| else |
| { |
| *PFieldList = (*PFieldList)->Next; |
| |
| if (Status == AE_NOT_FOUND) |
| { |
| sprintf (AslGbl_MsgBuffer, "Generic data type \"%s\" not found", |
| (*PFieldList)->Name); |
| DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, |
| (*PFieldList), AslGbl_MsgBuffer); |
| } |
| } |
| } |
| |
| return (AE_OK); |
| } |