#include "aslcompiler.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}
};
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);
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)
{
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
switch (AsfTable->Header.Type & 0x7F)
{
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);
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
}
break;
}
}
DtPopSubtable ();
}
return (AE_OK);
}
ACPI_STATUS
DtCompileCpep (
void **List)
{
ACPI_STATUS Status;
Status = DtCompileTwoSubtables (List,
AcpiDmTableInfoCpep, AcpiDmTableInfoCpep0);
return (Status);
}
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;
ParentTable = DtPeekSubtable ();
while (*PFieldList)
{
Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt0,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
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 ();
Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt1,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
while (*PFieldList && DescriptorCount)
{
Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
DtPushSubtable (Subtable);
ParentTable = DtPeekSubtable ();
if (*PFieldList)
{
Status = DtCompileTable (PFieldList, AcpiDmTableInfoCsrt2a,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
if (Subtable)
{
DtInsertSubtable (ParentTable, Subtable);
}
}
DtPopSubtable ();
ParentTable = DtPeekSubtable ();
DescriptorCount--;
}
DtPopSubtable ();
ParentTable = DtPeekSubtable ();
}
return (Status);
}
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;
Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2, &Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
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);
while (*PFieldList && SubtableCount)
{
Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Device,
&Subtable);
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 ();
DeviceInfo->BaseAddressOffset = CurrentOffset;
for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
{
Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Addr,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
CurrentOffset += (UINT16) sizeof (ACPI_GENERIC_ADDRESS);
DtInsertSubtable (ParentTable, Subtable);
}
DeviceInfo->AddressSizeOffset = CurrentOffset;
for (i = 0; *PFieldList && (i < DeviceInfo->RegisterCount); i++)
{
Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Size,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
CurrentOffset += (UINT16) sizeof (UINT32);
DtInsertSubtable (ParentTable, Subtable);
}
DeviceInfo->NamepathOffset = CurrentOffset;
Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2Name,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DeviceInfo->NamepathLength = (UINT16) Subtable->Length;
CurrentOffset += (UINT16) DeviceInfo->NamepathLength;
DtInsertSubtable (ParentTable, Subtable);
Status = DtCompileTable (PFieldList, AcpiDmTableInfoDbg2OemData,
&Subtable);
if (Status == AE_END_OF_TABLE)
{
goto subtableDone;
}
else if (ACPI_FAILURE (Status))
{
return (Status);
}
DeviceInfo->OemDataOffset = 0;
DeviceInfo->OemDataLength = 0;
if (Subtable && Subtable->Length)
{
DeviceInfo->OemDataOffset = CurrentOffset;
DeviceInfo->OemDataLength = (UINT16) Subtable->Length;
DtInsertSubtable (ParentTable, Subtable);
}
subtableDone:
SubtableCount--;
DtPopSubtable ();
}
DtPopSubtable ();
return (AE_OK);
}
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
DtPushSubtable (Subtable);
while (*PFieldList)
{
SubtableStart = *PFieldList;
Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarHdr,
&Subtable);
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);
}
Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
if ((DmarHeader->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
(DmarHeader->Type == ACPI_DMAR_TYPE_NAMESPACE))
{
DtPopSubtable ();
continue;
}
DtPushSubtable (Subtable);
DeviceScopeLength = DmarHeader->Length - Subtable->Length -
ParentTable->Length;
while (DeviceScopeLength)
{
Status = DtCompileTable (PFieldList, AcpiDmTableInfoDmarScope,
&Subtable);
if (Status == AE_NOT_FOUND)
{
break;
}
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
DtPushSubtable (Subtable);
DmarDeviceScope = ACPI_CAST_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable->Buffer);
PciPathLength = DmarDeviceScope->Length - Subtable->Length;
while (PciPathLength)
{
Status = DtCompileTable (PFieldList, TableInfoDmarPciPath,
&Subtable);
if (Status == AE_NOT_FOUND)
{
DtPopSubtable ();
break;
}
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
PciPathLength -= Subtable->Length;
}
DtPopSubtable ();
DeviceScopeLength -= DmarDeviceScope->Length;
}
DtPopSubtable ();
DtPopSubtable ();
}
return (AE_OK);
}
ACPI_STATUS
DtCompileDrtm (
void **List)
{
ACPI_STATUS Status;
DT_SUBTABLE *Subtable;
DT_SUBTABLE *ParentTable;
DT_FIELD **PFieldList = (DT_FIELD **) List;
UINT32 Count;
ACPI_DRTM_VTABLE_LIST *DrtmVtl;
ACPI_DRTM_RESOURCE_LIST *DrtmRl;
ParentTable = DtPeekSubtable ();
Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
#if 0
Drtm = ACPI_SUB_PTR (ACPI_TABLE_DRTM,
Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
#endif
Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm0,
&Subtable);
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
if (!Subtable)
{
break;
}
DtInsertSubtable (ParentTable, Subtable);
Count++;
}
DrtmVtl->ValidatedTableCount = Count;
DtPopSubtable ();
ParentTable = DtPeekSubtable ();
Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm1,
&Subtable);
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
if (!Subtable)
{
break;
}
DtInsertSubtable (ParentTable, Subtable);
Count++;
}
DrtmRl->ResourceCount = Count;
DtPopSubtable ();
ParentTable = DtPeekSubtable ();
Status = DtCompileTable (PFieldList, AcpiDmTableInfoDrtm2,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
return (AE_OK);
}
ACPI_STATUS
DtCompileEinj (
void **List)
{
ACPI_STATUS Status;
Status = DtCompileTwoSubtables (List,
AcpiDmTableInfoEinj, AcpiDmTableInfoEinj0);
return (Status);
}
ACPI_STATUS
DtCompileErst (
void **List)
{
ACPI_STATUS Status;
Status = DtCompileTwoSubtables (List,
AcpiDmTableInfoErst, AcpiDmTableInfoEinj0);
return (Status);
}
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
while (*PFieldList)
{
SubtableStart = *PFieldList;
Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdtHdr,
&Subtable);
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
GtCount--;
}
DtPopSubtable ();
break;
default:
break;
}
DtPopSubtable ();
}
return (AE_OK);
}
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);
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
DtPopSubtable ();
}
return (AE_OK);
}
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
while (*PFieldList)
{
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;
case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
InfoTable = AcpiDmTableInfoHest10;
break;
case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
InfoTable = AcpiDmTableInfoHest11;
break;
default:
DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HEST");
return (AE_ERROR);
}
Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
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;
case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
Subtable->Buffer))->NumHardwareBanks;
break;
default:
break;
}
while (BankCount)
{
Status = DtCompileTable (PFieldList, AcpiDmTableInfoHestBank,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
BankCount--;
}
}
return (AE_OK);
}
ACPI_STATUS
DtCompileHmat (
void **List)
{
ACPI_STATUS Status;
DT_SUBTABLE *Subtable;
DT_SUBTABLE *ParentTable;
DT_FIELD **PFieldList = (DT_FIELD **) List;
DT_FIELD *SubtableStart;
DT_FIELD *EntryStart;
ACPI_HMAT_STRUCTURE *HmatStruct;
ACPI_HMAT_LOCALITY *HmatLocality;
ACPI_HMAT_CACHE *HmatCache;
ACPI_DMTABLE_INFO *InfoTable;
UINT32 IntPDNumber;
UINT32 TgtPDNumber;
UINT64 EntryNumber;
UINT16 SMBIOSHandleNumber;
ParentTable = DtPeekSubtable ();
Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmat,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
while (*PFieldList)
{
SubtableStart = *PFieldList;
Status = DtCompileTable (PFieldList, AcpiDmTableInfoHmatHdr,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
HmatStruct = ACPI_CAST_PTR (ACPI_HMAT_STRUCTURE, Subtable->Buffer);
HmatStruct->Length = Subtable->Length;
switch (HmatStruct->Type)
{
case ACPI_HMAT_TYPE_ADDRESS_RANGE:
InfoTable = AcpiDmTableInfoHmat0;
break;
case ACPI_HMAT_TYPE_LOCALITY:
InfoTable = AcpiDmTableInfoHmat1;
break;
case ACPI_HMAT_TYPE_CACHE:
InfoTable = AcpiDmTableInfoHmat2;
break;
default:
DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "HMAT");
return (AE_ERROR);
}
Status = DtCompileTable (PFieldList, InfoTable, &Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
HmatStruct->Length += Subtable->Length;
switch (HmatStruct->Type)
{
case ACPI_HMAT_TYPE_LOCALITY:
HmatLocality = ACPI_SUB_PTR (ACPI_HMAT_LOCALITY,
Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
IntPDNumber = 0;
while (*PFieldList)
{
Status = DtCompileTable (PFieldList,
AcpiDmTableInfoHmat1a, &Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
if (!Subtable)
{
break;
}
DtInsertSubtable (ParentTable, Subtable);
HmatStruct->Length += Subtable->Length;
IntPDNumber++;
}
HmatLocality->NumberOfInitiatorPDs = IntPDNumber;
TgtPDNumber = 0;
while (*PFieldList)
{
Status = DtCompileTable (PFieldList,
AcpiDmTableInfoHmat1b, &Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
if (!Subtable)
{
break;
}
DtInsertSubtable (ParentTable, Subtable);
HmatStruct->Length += Subtable->Length;
TgtPDNumber++;
}
HmatLocality->NumberOfTargetPDs = TgtPDNumber;
EntryStart = *PFieldList;
EntryNumber = 0;
while (*PFieldList)
{
Status = DtCompileTable (PFieldList,
AcpiDmTableInfoHmat1c, &Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
if (!Subtable)
{
break;
}
DtInsertSubtable (ParentTable, Subtable);
HmatStruct->Length += Subtable->Length;
EntryNumber++;
}
if (EntryNumber !=
((UINT64)IntPDNumber * (UINT64)TgtPDNumber))
{
DtFatal (ASL_MSG_INVALID_EXPRESSION, EntryStart, "HMAT");
return (AE_ERROR);
}
break;
case ACPI_HMAT_TYPE_CACHE:
HmatCache = ACPI_SUB_PTR (ACPI_HMAT_CACHE,
Subtable->Buffer, sizeof (ACPI_HMAT_STRUCTURE));
SMBIOSHandleNumber = 0;
while (*PFieldList)
{
Status = DtCompileTable (PFieldList,
AcpiDmTableInfoHmat2a, &Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
if (!Subtable)
{
break;
}
DtInsertSubtable (ParentTable, Subtable);
HmatStruct->Length += Subtable->Length;
SMBIOSHandleNumber++;
}
HmatCache->NumberOfSMBIOSHandles = SMBIOSHandleNumber;
break;
default:
break;
}
}
return (AE_OK);
}
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
Iort = ACPI_SUB_PTR (ACPI_TABLE_IORT,
Subtable->Buffer, sizeof (ACPI_TABLE_HEADER));
Iort->NodeOffset = sizeof (ACPI_TABLE_IORT);
Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortPad,
&Subtable);
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);
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);
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);
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
NodeLength += Subtable->Length;
Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort1a,
&Subtable);
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
NodeLength += Subtable->Length;
break;
case ACPI_IORT_NODE_SMMU:
Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
IortSmmu = ACPI_CAST_PTR (ACPI_IORT_SMMU, Subtable->Buffer);
NodeLength += Subtable->Length;
IortSmmu->GlobalInterruptOffset = NodeLength;
Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3a,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
NodeLength += Subtable->Length;
ContextIrptNumber = 0;
IortSmmu->ContextInterruptOffset = NodeLength;
while (*PFieldList)
{
Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3b,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
if (!Subtable)
{
break;
}
DtInsertSubtable (ParentTable, Subtable);
NodeLength += Subtable->Length;
ContextIrptNumber++;
}
IortSmmu->ContextInterruptCount = ContextIrptNumber;
PmuIrptNumber = 0;
IortSmmu->PmuInterruptOffset = NodeLength;
while (*PFieldList)
{
Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort3c,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
if (!Subtable)
{
break;
}
DtInsertSubtable (ParentTable, Subtable);
NodeLength += Subtable->Length;
PmuIrptNumber++;
}
IortSmmu->PmuInterruptCount = PmuIrptNumber;
break;
case ACPI_IORT_NODE_SMMU_V3:
Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort4,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
NodeLength += Subtable->Length;
break;
case ACPI_IORT_NODE_PMCG:
Status = DtCompileTable (PFieldList, AcpiDmTableInfoIort5,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
NodeLength += Subtable->Length;
break;
default:
DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "IORT");
return (AE_ERROR);
}
IortNode->MappingOffset = NodeLength;
IdMappingNumber = 0;
while (*PFieldList)
{
Status = DtCompileTable (PFieldList, AcpiDmTableInfoIortMap,
&Subtable);
if (ACPI_FAILURE (Status))
{
return (Status);
}
if (!Subtable)
{
break;
}
DtInsertSubtable (ParentTable, Subtable);
NodeLength += sizeof (ACPI_IORT_ID_MAPPING);
IdMappingNumber++;
}
IortNode->MappingCount = IdMappingNumber;
if (!IdMappingNumber)
{
IortNode->MappingOffset = 0;
}
DtPopSubtable ();
ParentTable = DtPeekSubtable ();
NodeNumber++;
}
Iort->NodeCount = NodeNumber;
return (AE_OK);
}
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
ParentTable = DtPeekSubtable ();
DtInsertSubtable (ParentTable, Subtable);
while (*PFieldList)
{
SubtableStart = *PFieldList;
Status = DtCompileTable (PFieldList, AcpiDmTableInfoIvrsHdr,
&Subtable);
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);
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)
{
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;
case ACPI_IVRS_TYPE_ALIAS_SELECT:
case ACPI_IVRS_TYPE_ALIAS_START:
InfoTable = AcpiDmTableInfoIvrs8a;
break;
case ACPI_IVRS_TYPE_PAD8:
case ACPI_IVRS_TYPE_EXT_SELECT:
case ACPI_IVRS_TYPE_EXT_START:
InfoTable = AcpiDmTableInfoIvrs8b;
break;
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);
if (ACPI_FAILURE (Status))
{
return (Status);
}
DtInsertSubtable (ParentTable, Subtable);
}
}
DtPopSubtable ();
}
return (AE_OK);
}