diff options
Diffstat (limited to 'MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c')
-rw-r--r-- | MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c | 210 |
1 files changed, 165 insertions, 45 deletions
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c index f2a7be5778..56f3c8bc65 100644 --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c @@ -1968,10 +1968,18 @@ InstallAcpiTableFromAcpiSiliconHob ( EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *SiAcpiHobRsdp;
EFI_ACPI_DESCRIPTION_HEADER *SiCommonAcpiTable;
EFI_STATUS Status;
- UINT8 *TempBuffer;
UINTN NumOfTblEntries;
+ EFI_ACPI_TABLE_VERSION Version;
+ UINT64 SocTablePtr;
+ EFI_ACPI_DESCRIPTION_HEADER *SocEntryTable;
+ UINTN Index;
+ UINTN TableKey;
+ VOID *NeedToInstallTable;
+ UINT8 *Buffer;
+ EFI_PHYSICAL_ADDRESS PageAddress;
+ UINTN TotalSocTablesize;
- DEBUG ((DEBUG_INFO, "InstallAcpiTableFromAcpiSiliconHob\n"));
+ DEBUG ((DEBUG_INFO, "InstallAcpiTableFromAcpiSiliconHob - Start\n"));
//
// Initial variable.
//
@@ -1979,6 +1987,8 @@ InstallAcpiTableFromAcpiSiliconHob ( SiCommonAcpiTable = NULL;
AcpiSiliconHob = GET_GUID_HOB_DATA (GuidHob);
Status = EFI_SUCCESS;
+ Version = PcdGet32 (PcdAcpiExposedTableVersions);
+ TableKey = 0;
//
// Got RSDP table from ACPI Silicon Hob.
//
@@ -1988,63 +1998,173 @@ InstallAcpiTableFromAcpiSiliconHob ( return EFI_NOT_FOUND;
}
- DEBUG ((DEBUG_INFO, "Silicon ACPI RSDP address : 0x%lx\n", SiAcpiHobRsdp));
+ DEBUG ((DEBUG_INFO, "Silicon ACPI RSDP address : 0x%016lx\n", SiAcpiHobRsdp));
AcpiTableInstance->Rsdp3 = SiAcpiHobRsdp;
- if (SiAcpiHobRsdp->RsdtAddress != 0x00000000) {
- //
- // Initial RSDT.
- //
- TempBuffer = (UINT8 *)(UINTN)(SiAcpiHobRsdp->RsdtAddress);
- SiCommonAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *)TempBuffer;
- AcpiTableInstance->Rsdt3 = SiCommonAcpiTable;
+ //
+ // Got XSDT address from RSDP table.
+ //
+ Buffer = (UINT8 *)(UINTN)(SiAcpiHobRsdp->XsdtAddress);
+ SiCommonAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *)Buffer;
- if (SiCommonAcpiTable->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
- DEBUG ((DEBUG_ERROR, "RSDT length is incorrect\n"));
- return EFI_ABORTED;
- }
+ DEBUG ((DEBUG_INFO, "Silicon ACPI XSDT address : 0x%016lx\n", SiCommonAcpiTable));
+ if (SiCommonAcpiTable->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
+ DEBUG ((DEBUG_ERROR, "XSDT length is incorrect\n"));
+ return EFI_ABORTED;
+ }
+
+ //
+ // Calcaue 64bit Acpi table number.
+ //
+ NumOfTblEntries = (SiCommonAcpiTable->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT64);
+ DEBUG ((DEBUG_ERROR, "64bit NumOfTblEntries : 0x%x\n", NumOfTblEntries));
+ //
+ // Reserved the ACPI reclaim memory for XSDT.
+ //
+ //
+ TotalSocTablesize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + sizeof (UINT64);
+ PageAddress = 0xFFFFFFFF;
+ Status = gBS->AllocatePages (
+ mAcpiTableAllocType,
+ EfiACPIReclaimMemory,
+ EFI_SIZE_TO_PAGES (TotalSocTablesize),
+ &PageAddress
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to allocate EfiACPIReclaimMemory for XSDT. Status : %r\n", Status));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (&PageAddress, TotalSocTablesize);
+ AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)PageAddress;
+
+ //
+ // Initial XSDT table content.
+ //
+ AcpiTableInstance->Xsdt->Signature = SiCommonAcpiTable->Signature;
+ //
+ // Always reserve first one for FADT table.
+ //
+ AcpiTableInstance->Xsdt->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + sizeof (UINT64);
+ AcpiTableInstance->Xsdt->Revision = SiCommonAcpiTable->Revision;
+ CopyMem (
+ &AcpiTableInstance->Xsdt->OemId,
+ SiCommonAcpiTable->OemId,
+ sizeof (AcpiTableInstance->Xsdt->OemId)
+ );
+ CopyMem (
+ &AcpiTableInstance->Xsdt->OemTableId,
+ &SiCommonAcpiTable->OemTableId,
+ sizeof (UINT64)
+ );
+ AcpiTableInstance->Xsdt->OemRevision = SiCommonAcpiTable->OemRevision;
+ AcpiTableInstance->Xsdt->CreatorId = SiCommonAcpiTable->CreatorId;
+ AcpiTableInstance->Xsdt->CreatorRevision = SiCommonAcpiTable->CreatorRevision;
+ AcpiTableInstance->NumberOfTableEntries3 = 1;
+ //
+ // Extract ACPI table from AcpiSiliconHob XSDT.
+ //
+ for (Index = 0; Index < NumOfTblEntries; Index++) {
+ CopyMem (&SocTablePtr, (((UINT8 *)(SiCommonAcpiTable + 1)) + ((sizeof (UINT64)) * Index)), sizeof (UINT64));
+ SocEntryTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)SocTablePtr;
//
- // Calcaue 32bit Acpi table number.
+ // Display table information.
//
- NumOfTblEntries = (SiCommonAcpiTable->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT32);
- AcpiTableInstance->NumberOfTableEntries1 = NumOfTblEntries;
- DEBUG ((DEBUG_INFO, "32bit NumOfTblEntries : 0x%x\n", NumOfTblEntries));
+ DEBUG ((DEBUG_INFO, "[%x] Table address : 0x%016lx\n", Index, SocTablePtr));
+
+ Buffer = (UINT8 *)&SocEntryTable->Signature;
+ DEBUG ((DEBUG_INFO, "Table signature = %c%c%c%c\n", Buffer[0], Buffer[1], Buffer[2], Buffer[3]));
+
+ DEBUG ((DEBUG_INFO, "Table Length : 0x%x\n", SocEntryTable->Length));
+
+ Buffer = (UINT8 *)&SocEntryTable->OemId;
+ DEBUG (
+ (DEBUG_INFO, "Table OemId = %c%c%c%c%c%c\n",
+ Buffer[0],
+ Buffer[1],
+ Buffer[2],
+ Buffer[3],
+ Buffer[4],
+ Buffer[5]
+ )
+ );
+
+ Buffer = (UINT8 *)&SocEntryTable->OemTableId;
+ DEBUG (
+ (DEBUG_INFO, "Table OemTableId = %c%c%c%c%c%c%c%c\n",
+ Buffer[0],
+ Buffer[1],
+ Buffer[2],
+ Buffer[3],
+ Buffer[4],
+ Buffer[5],
+ Buffer[6],
+ Buffer[7]
+ )
+ );
+ DEBUG ((DEBUG_INFO, "\n"));
//
- // Enlarge the max table number from mEfiAcpiMaxNumTables to current ACPI tables + EFI_ACPI_MAX_NUM_TABLES
+ // Add ACPI table in the DXE AcpiTableInstance.
//
- if (AcpiTableInstance->NumberOfTableEntries1 >= EFI_ACPI_MAX_NUM_TABLES) {
- mEfiAcpiMaxNumTables = AcpiTableInstance->NumberOfTableEntries1 + EFI_ACPI_MAX_NUM_TABLES;
- DEBUG ((DEBUG_ERROR, "mEfiAcpiMaxNumTables : 0x%x\n", mEfiAcpiMaxNumTables));
+ Status = AddTableToList (AcpiTableInstance, SocEntryTable, TRUE, Version, TRUE, &TableKey);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromAcpiSiliconHob: Fail to add ACPI table at 0x%p\n", SocEntryTable));
+ ASSERT_EFI_ERROR (Status);
+ break;
}
- } else {
- //
- // Initial XSDT.
- //
- TempBuffer = (UINT8 *)(UINTN)(SiAcpiHobRsdp->XsdtAddress);
- SiCommonAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *)TempBuffer;
- AcpiTableInstance->Xsdt = SiCommonAcpiTable;
- if (SiCommonAcpiTable->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
- DEBUG ((DEBUG_ERROR, "XSDT length is incorrect\n"));
- return EFI_ABORTED;
- }
+ if (SocEntryTable->Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
+ //
+ // According ACPI spec, if XDsdt field contains a nonzero value which can be used by the OSPM, then the Dsdt field must be ignored by the OSPM.
+ //
+ if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->XDsdt != 0) {
+ NeedToInstallTable = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->XDsdt;
+ } else if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->Dsdt != 0) {
+ NeedToInstallTable = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->Dsdt;
+ }
- //
- // Calcaue 64bit Acpi table number.
- //
- NumOfTblEntries = (SiCommonAcpiTable->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT64);
- AcpiTableInstance->NumberOfTableEntries3 = NumOfTblEntries;
- DEBUG ((DEBUG_ERROR, "64bit NumOfTblEntries : 0x%x\n", NumOfTblEntries));
- //
- // Enlarge the max table number from mEfiAcpiMaxNumTables to current ACPI tables + EFI_ACPI_MAX_NUM_TABLES
- //
- if (AcpiTableInstance->NumberOfTableEntries3 >= EFI_ACPI_MAX_NUM_TABLES) {
- mEfiAcpiMaxNumTables = AcpiTableInstance->NumberOfTableEntries3 + EFI_ACPI_MAX_NUM_TABLES;
- DEBUG ((DEBUG_ERROR, "mEfiAcpiMaxNumTables : 0x%x\n", mEfiAcpiMaxNumTables));
+ //
+ // if signature can not be found from the XDsdt / Dsdt field then skip it.
+ //
+ if (((EFI_ACPI_DESCRIPTION_HEADER *)NeedToInstallTable)->Signature == EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
+ Status = AddTableToList (AcpiTableInstance, NeedToInstallTable, TRUE, Version, TRUE, &TableKey);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to add DSDT in the DXE Table list!\n"));
+ ASSERT_EFI_ERROR (Status);
+ break;
+ } else {
+ DEBUG ((DEBUG_ERROR, "Installed DSDT in the DXE Table list!\n"));
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR, "The DSDT content is not correct, then skip it!\n"));
+ }
+
+ //
+ // According ACPI spec, if XFirmwareCtrl field contains a nonzero value which can be used by the OSPM, then the FirmwareCtrl field must be ignored by the OSPM.
+ //
+ if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->XFirmwareCtrl != 0) {
+ NeedToInstallTable = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->XFirmwareCtrl;
+ } else if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->FirmwareCtrl != 0) {
+ NeedToInstallTable = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->FirmwareCtrl;
+ }
+
+ if (((EFI_ACPI_DESCRIPTION_HEADER *)NeedToInstallTable)->Signature == EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
+ Status = AddTableToList (AcpiTableInstance, NeedToInstallTable, TRUE, Version, TRUE, &TableKey);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to add FACS in the DXE Table list!\n"));
+ ASSERT_EFI_ERROR (Status);
+ break;
+ } else {
+ DEBUG ((DEBUG_ERROR, "Installed FACS in the DXE Table list!\n"));
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR, "The FACS content is not correct, then skip it!\n"));
+ }
}
}
+ DEBUG ((DEBUG_INFO, "InstallAcpiTableFromAcpiSiliconHob - End\n"));
return Status;
}
|