/** @file\r
ACPI Table Protocol Implementation\r
\r
- Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
//\r
#include "AcpiTable.h"\r
//\r
-// The maximum number of tables that pre-allocated. \r
+// The maximum number of tables that pre-allocated.\r
//\r
-UINTN mEfiAcpiMaxNumTables = EFI_ACPI_MAX_NUM_TABLES; \r
+UINTN mEfiAcpiMaxNumTables = EFI_ACPI_MAX_NUM_TABLES;\r
+\r
+//\r
+// Allocation strategy to use for AllocatePages ().\r
+// Runtime value depends on PcdExposedAcpiTableVersions.\r
+//\r
+STATIC EFI_ALLOCATE_TYPE mAcpiTableAllocType;\r
\r
/**\r
This function adds an ACPI table to the table list. It will detect FACS and\r
// Protocol function implementations.\r
//\r
\r
-/**\r
- This function adds, removes, or updates ACPI tables. If the address is not\r
- null and the handle value is null, the table is added. If both the address and \r
- handle are not null, the table at handle is updated with the table at address.\r
- If the address is null and the handle is not, the table at handle is deleted.\r
-\r
- @param AcpiTableInstance Instance of the protocol.\r
- @param Table Pointer to a table.\r
- @param Checksum Boolean indicating if the checksum should be calculated.\r
- @param Version Version(s) to set.\r
- @param Handle Handle of the table.\r
-\r
- @return EFI_SUCCESS The function completed successfully.\r
- @return EFI_INVALID_PARAMETER Both the Table and *Handle were NULL.\r
- @return EFI_ABORTED Could not complete the desired request.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetAcpiTable (\r
- IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,\r
- IN VOID *Table OPTIONAL,\r
- IN BOOLEAN Checksum,\r
- IN EFI_ACPI_TABLE_VERSION Version,\r
- IN OUT UINTN *Handle\r
- )\r
-{\r
- UINTN SavedHandle;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Check for invalid input parameters\r
- //\r
- ASSERT (Handle);\r
-\r
- //\r
- // Initialize locals\r
- //\r
- //\r
- // Determine desired action\r
- //\r
- if (*Handle == 0) {\r
- if (Table == NULL) {\r
- //\r
- // Invalid parameter combination\r
- //\r
- return EFI_INVALID_PARAMETER;\r
- } else {\r
- //\r
- // Add table\r
- //\r
- Status = AddTableToList (AcpiTableInstance, Table, Checksum, Version, Handle);\r
- }\r
- } else {\r
- if (Table != NULL) {\r
- //\r
- // Update table\r
- //\r
- //\r
- // Delete the table list entry\r
- //\r
- Status = RemoveTableFromList (AcpiTableInstance, Version, *Handle);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Should not get an error here ever, but abort if we do.\r
- //\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Set the handle to replace the table at the same handle\r
- //\r
- SavedHandle = AcpiTableInstance->CurrentHandle;\r
- AcpiTableInstance->CurrentHandle = *Handle;\r
-\r
- //\r
- // Add the table\r
- //\r
- Status = AddTableToList (AcpiTableInstance, Table, Checksum, Version, Handle);\r
-\r
- //\r
- // Restore the saved current handle\r
- //\r
- AcpiTableInstance->CurrentHandle = SavedHandle;\r
- } else {\r
- //\r
- // Delete table\r
- //\r
- Status = RemoveTableFromList (AcpiTableInstance, Version, *Handle);\r
- }\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Should not get an error here ever, but abort if we do.\r
- //\r
- return EFI_ABORTED;\r
- }\r
- //\r
- // Done\r
- //\r
- return EFI_SUCCESS;\r
-}\r
-\r
/**\r
This function publishes the specified versions of the ACPI tables by\r
installing EFI configuration table entries for them. Any combination of\r
if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
CurrentRsdtEntry = (UINT32 *) ((UINT8 *) AcpiTableInstance->Rsdt1 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
*CurrentRsdtEntry = (UINT32) (UINTN) AcpiTableInstance->Fadt1;\r
- }\r
- if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
- (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+\r
CurrentRsdtEntry = (UINT32 *) ((UINT8 *) AcpiTableInstance->Rsdt3 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
*CurrentRsdtEntry = (UINT32) (UINTN) AcpiTableInstance->Fadt3;\r
+ }\r
+ if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {\r
CurrentXsdtEntry = (VOID *) ((UINT8 *) AcpiTableInstance->Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
//\r
// Add entry to XSDT, XSDT expects 64 bit pointers, but\r
// Add the RSD_PTR to the system table and store that we have installed the\r
// tables.\r
//\r
- if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) &&\r
- !AcpiTableInstance->TablesInstalled1) {\r
+ if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
Status = gBS->InstallConfigurationTable (&gEfiAcpi10TableGuid, AcpiTableInstance->Rsdp1);\r
if (EFI_ERROR (Status)) {\r
return EFI_ABORTED;\r
}\r
-\r
- AcpiTableInstance->TablesInstalled1 = TRUE;\r
}\r
\r
- if (((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
- (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) &&\r
- !AcpiTableInstance->TablesInstalled3) {\r
+ if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {\r
Status = gBS->InstallConfigurationTable (&gEfiAcpiTableGuid, AcpiTableInstance->Rsdp3);\r
if (EFI_ERROR (Status)) {\r
return EFI_ABORTED;\r
}\r
-\r
- AcpiTableInstance->TablesInstalled3= TRUE;\r
}\r
\r
return EFI_SUCCESS;\r
@param TableKey Reurns a key to refer to the ACPI table.\r
\r
@return EFI_SUCCESS The table was successfully inserted.\r
- @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableKey is NULL, or AcpiTableBufferSize \r
+ @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableKey is NULL, or AcpiTableBufferSize\r
and the size field embedded in the ACPI table pointed to by AcpiTableBuffer\r
are not in sync.\r
@return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.\r
+ @retval EFI_ACCESS_DENIED The table signature matches a table already\r
+ present in the system and platform policy\r
+ does not allow duplicate tables of this type.\r
\r
**/\r
EFI_STATUS\r
EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance;\r
EFI_STATUS Status;\r
VOID *AcpiTableBufferConst;\r
+ EFI_ACPI_TABLE_VERSION Version;\r
\r
//\r
// Check for invalid input parameters\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ Version = PcdGet32 (PcdAcpiExposedTableVersions);\r
+\r
//\r
// Get the instance of the ACPI table protocol\r
//\r
//\r
AcpiTableBufferConst = AllocateCopyPool (AcpiTableBufferSize,AcpiTableBuffer);\r
*TableKey = 0;\r
- Status = SetAcpiTable (\r
+ Status = AddTableToList (\r
AcpiTableInstance,\r
AcpiTableBufferConst,\r
TRUE,\r
- EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0,\r
+ Version,\r
TableKey\r
);\r
if (!EFI_ERROR (Status)) {\r
Status = PublishTables (\r
AcpiTableInstance,\r
- EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0\r
+ Version\r
);\r
}\r
FreePool (AcpiTableBufferConst);\r
- \r
+\r
//\r
// Add a new table successfully, notify registed callback\r
//\r
if (!EFI_ERROR (Status)) {\r
SdtNotifyAcpiList (\r
AcpiTableInstance,\r
- EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0,\r
+ Version,\r
*TableKey\r
);\r
}\r
{\r
EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance;\r
EFI_STATUS Status;\r
+ EFI_ACPI_TABLE_VERSION Version;\r
\r
//\r
// Get the instance of the ACPI table protocol\r
//\r
AcpiTableInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This);\r
\r
+ Version = PcdGet32 (PcdAcpiExposedTableVersions);\r
+\r
//\r
// Uninstall the ACPI table\r
//\r
- Status = SetAcpiTable (\r
+ Status = RemoveTableFromList (\r
AcpiTableInstance,\r
- NULL,\r
- FALSE,\r
- EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0,\r
- &TableKey\r
+ Version,\r
+ TableKey\r
);\r
if (!EFI_ERROR (Status)) {\r
Status = PublishTables (\r
AcpiTableInstance,\r
- EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0\r
+ Version\r
);\r
}\r
\r
EFI_ACPI_TABLE_INSTANCE TempPrivateData;\r
EFI_STATUS Status;\r
UINT64 CurrentData;\r
- \r
- CopyMem (&TempPrivateData, AcpiTableInstance, sizeof (EFI_ACPI_TABLE_INSTANCE)); \r
+\r
+ CopyMem (&TempPrivateData, AcpiTableInstance, sizeof (EFI_ACPI_TABLE_INSTANCE));\r
//\r
// Enlarge the max table number from mEfiAcpiMaxNumTables to mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES\r
//\r
//\r
// Create RSDT, XSDT structures and allocate buffers.\r
//\r
- TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT\r
- NewMaxTableNumber * sizeof (UINT32) +\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT\r
- NewMaxTableNumber * sizeof (UINT32) +\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT\r
+ TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT\r
NewMaxTableNumber * sizeof (UINT64);\r
\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT\r
+ NewMaxTableNumber * sizeof (UINT32) +\r
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT\r
+ NewMaxTableNumber * sizeof (UINT32);\r
+ }\r
+\r
//\r
// Allocate memory in the lower 32 bit of address range for\r
// compatibility with ACPI 1.0 OS.\r
//\r
PageAddress = 0xFFFFFFFF;\r
Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
+ mAcpiTableAllocType,\r
EfiACPIReclaimMemory,\r
EFI_SIZE_TO_PAGES (TotalSize),\r
&PageAddress\r
\r
Pointer = (UINT8 *) (UINTN) PageAddress;\r
ZeroMem (Pointer, TotalSize);\r
- \r
+\r
AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
- Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));\r
- AcpiTableInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
- Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));\r
+ AcpiTableInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
+ Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));\r
+ }\r
AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
\r
//\r
// Update RSDP to point to the new Rsdt and Xsdt address.\r
//\r
- AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt1;\r
- AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt3;\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt1;\r
+ AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt3;\r
+ }\r
CurrentData = (UINT64) (UINTN) AcpiTableInstance->Xsdt;\r
CopyMem (&AcpiTableInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));\r
\r
//\r
- // copy the original Rsdt1, Rsdt3 and Xsdt structure to new buffer \r
+ // copy the original Rsdt1, Rsdt3 and Xsdt structure to new buffer\r
//\r
- CopyMem (AcpiTableInstance->Rsdt1, TempPrivateData.Rsdt1, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32))); \r
- CopyMem (AcpiTableInstance->Rsdt3, TempPrivateData.Rsdt3, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32))); \r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ CopyMem (AcpiTableInstance->Rsdt1, TempPrivateData.Rsdt1, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32)));\r
+ CopyMem (AcpiTableInstance->Rsdt3, TempPrivateData.Rsdt3, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32)));\r
+ }\r
CopyMem (AcpiTableInstance->Xsdt, TempPrivateData.Xsdt, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT64)));\r
- \r
+\r
//\r
// Calculate orignal ACPI table buffer size\r
//\r
- TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT\r
- mEfiAcpiMaxNumTables * sizeof (UINT32) +\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT\r
- mEfiAcpiMaxNumTables * sizeof (UINT32) +\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT\r
+ TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT\r
mEfiAcpiMaxNumTables * sizeof (UINT64);\r
+\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT\r
+ mEfiAcpiMaxNumTables * sizeof (UINT32) +\r
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT\r
+ mEfiAcpiMaxNumTables * sizeof (UINT32);\r
+ }\r
+\r
gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)TempPrivateData.Rsdt1, EFI_SIZE_TO_PAGES (TotalSize));\r
- \r
+\r
//\r
// Update the Max ACPI table number\r
- // \r
+ //\r
mEfiAcpiMaxNumTables = NewMaxTableNumber;\r
return EFI_SUCCESS;\r
}\r
+\r
/**\r
This function adds an ACPI table to the table list. It will detect FACS and\r
allocate the correct type of memory and properly align the table.\r
\r
@return EFI_SUCCESS The function completed successfully.\r
@return EFI_OUT_OF_RESOURCES Could not allocate a required resource.\r
- @return EFI_ABORTED The table is a duplicate of a table that is required\r
- to be unique.\r
+ @retval EFI_ACCESS_DENIED The table signature matches a table already\r
+ present in the system and platform policy\r
+ does not allow duplicate tables of this type.\r
\r
**/\r
EFI_STATUS\r
//\r
// Allocation memory type depends on the type of the table\r
//\r
- if ((CurrentTableSignature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) || \r
+ if ((CurrentTableSignature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||\r
(CurrentTableSignature == EFI_ACPI_4_0_UEFI_ACPI_DATA_TABLE_SIGNATURE)) {\r
//\r
// Allocate memory for the FACS. This structure must be aligned\r
// All other tables are ACPI reclaim memory, no alignment requirements.\r
//\r
Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
+ mAcpiTableAllocType,\r
EfiACPIReclaimMemory,\r
CurrentTableList->NumberOfPages,\r
&CurrentTableList->PageAddress\r
// Check that the table has not been previously added.\r
//\r
if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Fadt1 != NULL) ||\r
- ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 && AcpiTableInstance->Fadt3 != NULL) ||\r
- ((Version & EFI_ACPI_TABLE_VERSION_3_0) != 0 && AcpiTableInstance->Fadt3 != NULL)\r
+ ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0 && AcpiTableInstance->Fadt3 != NULL)\r
) {\r
gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);\r
gBS->FreePool (CurrentTableList);\r
- return EFI_ABORTED;\r
+ return EFI_ACCESS_DENIED;\r
}\r
//\r
// Add the table to the appropriate table version\r
AcpiTableInstance->Rsdt1->OemRevision = AcpiTableInstance->Fadt1->Header.OemRevision;\r
}\r
\r
- if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
- (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+ if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {\r
//\r
// Save a pointer to the table\r
//\r
\r
//\r
// Update pointers in FADT. If tables don't exist this will put NULL pointers there.\r
- // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and \r
+ // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and\r
// vice-versa.\r
//\r
if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {\r
AcpiTableInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiTableInstance->Facs3;\r
+ ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));\r
} else {\r
Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Facs3;\r
CopyMem (\r
&Buffer64,\r
sizeof (UINT64)\r
);\r
+ AcpiTableInstance->Fadt3->FirmwareCtrl = 0;\r
}\r
- AcpiTableInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;\r
- Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;\r
- CopyMem (\r
- &AcpiTableInstance->Fadt3->XDsdt,\r
- &Buffer64,\r
- sizeof (UINT64)\r
- );\r
+ if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {\r
+ AcpiTableInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;\r
+ //\r
+ // Comment block "the caller installs the tables in "DSDT, FADT" order"\r
+ // The below comments are also in "the caller installs the tables in "FADT, DSDT" order" comment block.\r
+ //\r
+ // The ACPI specification, up to and including revision 5.1 Errata A,\r
+ // allows the DSDT and X_DSDT fields to be both set in the FADT.\r
+ // (Obviously, this only makes sense if the DSDT address is representable in 4 bytes.)\r
+ // Starting with 5.1 Errata B, specifically for Mantis 1393 <https://mantis.uefi.org/mantis/view.php?id=1393>,\r
+ // the spec requires at most one of DSDT and X_DSDT fields to be set to a nonzero value,\r
+ // but strangely an exception is 6.0 that has no this requirement.\r
+ //\r
+ // Here we do not make the DSDT and X_DSDT fields mutual exclusion conditionally\r
+ // by checking FADT revision, but always set both DSDT and X_DSDT fields in the FADT\r
+ // to have better compatibility as some OS may have assumption to only consume X_DSDT\r
+ // field even the DSDT address is < 4G.\r
+ //\r
+ Buffer64 = AcpiTableInstance->Fadt3->Dsdt;\r
+ } else {\r
+ AcpiTableInstance->Fadt3->Dsdt = 0;\r
+ Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;\r
+ }\r
+ CopyMem (&AcpiTableInstance->Fadt3->XDsdt, &Buffer64, sizeof (UINT64));\r
\r
//\r
// RSDP OEM information is updated to match the FADT OEM information\r
&AcpiTableInstance->Fadt3->Header.OemId,\r
6\r
);\r
- \r
- //\r
- // RSDT OEM information is updated to match FADT OEM information.\r
- //\r
- CopyMem (\r
- &AcpiTableInstance->Rsdt3->OemId,\r
- &AcpiTableInstance->Fadt3->Header.OemId,\r
- 6\r
- );\r
- CopyMem (\r
- &AcpiTableInstance->Rsdt3->OemTableId,\r
- &AcpiTableInstance->Fadt3->Header.OemTableId,\r
- sizeof (UINT64)\r
- );\r
- AcpiTableInstance->Rsdt3->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;\r
- \r
+\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ //\r
+ // RSDT OEM information is updated to match FADT OEM information.\r
+ //\r
+ CopyMem (\r
+ &AcpiTableInstance->Rsdt3->OemId,\r
+ &AcpiTableInstance->Fadt3->Header.OemId,\r
+ 6\r
+ );\r
+ CopyMem (\r
+ &AcpiTableInstance->Rsdt3->OemTableId,\r
+ &AcpiTableInstance->Fadt3->Header.OemTableId,\r
+ sizeof (UINT64)\r
+ );\r
+ AcpiTableInstance->Rsdt3->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;\r
+ }\r
+\r
//\r
// XSDT OEM information is updated to match FADT OEM information.\r
//\r
sizeof (UINT64)\r
);\r
AcpiTableInstance->Xsdt->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;\r
- } \r
+ }\r
//\r
// Checksum the table\r
//\r
// Check that the table has not been previously added.\r
//\r
if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Facs1 != NULL) ||\r
- ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 && AcpiTableInstance->Facs3 != NULL) ||\r
- ((Version & EFI_ACPI_TABLE_VERSION_3_0) != 0 && AcpiTableInstance->Facs3 != NULL)\r
+ ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0 && AcpiTableInstance->Facs3 != NULL)\r
) {\r
gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);\r
gBS->FreePool (CurrentTableList);\r
- return EFI_ABORTED;\r
+ return EFI_ACCESS_DENIED;\r
}\r
//\r
// FACS is referenced by FADT and is not part of RSDT\r
}\r
}\r
\r
- if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
- (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+ if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {\r
//\r
// Save a pointer to the table\r
//\r
//\r
if (AcpiTableInstance->Fadt3 != NULL) {\r
//\r
- // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and \r
+ // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and\r
// vice-versa.\r
//\r
if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {\r
AcpiTableInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiTableInstance->Facs3;\r
+ ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));\r
} else {\r
Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Facs3;\r
CopyMem (\r
&Buffer64,\r
sizeof (UINT64)\r
);\r
+ AcpiTableInstance->Fadt3->FirmwareCtrl = 0;\r
}\r
\r
//\r
// Check that the table has not been previously added.\r
//\r
if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Dsdt1 != NULL) ||\r
- ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 && AcpiTableInstance->Dsdt3 != NULL) ||\r
- ((Version & EFI_ACPI_TABLE_VERSION_3_0) != 0 && AcpiTableInstance->Dsdt3 != NULL)\r
+ ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0 && AcpiTableInstance->Dsdt3 != NULL)\r
) {\r
gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);\r
gBS->FreePool (CurrentTableList);\r
- return EFI_ABORTED;\r
+ return EFI_ACCESS_DENIED;\r
}\r
//\r
// DSDT is referenced by FADT and is not part of RSDT\r
);\r
}\r
}\r
- \r
- if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
- (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+\r
+ if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {\r
//\r
// Save a pointer to the table\r
//\r
// If FADT already exists, update table pointers.\r
//\r
if (AcpiTableInstance->Fadt3 != NULL) {\r
- AcpiTableInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;\r
- Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;\r
- CopyMem (\r
- &AcpiTableInstance->Fadt3->XDsdt,\r
- &Buffer64,\r
- sizeof (UINT64)\r
- );\r
+ if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {\r
+ AcpiTableInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;\r
+ //\r
+ // Comment block "the caller installs the tables in "FADT, DSDT" order"\r
+ // The below comments are also in "the caller installs the tables in "DSDT, FADT" order" comment block.\r
+ //\r
+ // The ACPI specification, up to and including revision 5.1 Errata A,\r
+ // allows the DSDT and X_DSDT fields to be both set in the FADT.\r
+ // (Obviously, this only makes sense if the DSDT address is representable in 4 bytes.)\r
+ // Starting with 5.1 Errata B, specifically for Mantis 1393 <https://mantis.uefi.org/mantis/view.php?id=1393>,\r
+ // the spec requires at most one of DSDT and X_DSDT fields to be set to a nonzero value,\r
+ // but strangely an exception is 6.0 that has no this requirement.\r
+ //\r
+ // Here we do not make the DSDT and X_DSDT fields mutual exclusion conditionally\r
+ // by checking FADT revision, but always set both DSDT and X_DSDT fields in the FADT\r
+ // to have better compatibility as some OS may have assumption to only consume X_DSDT\r
+ // field even the DSDT address is < 4G.\r
+ //\r
+ Buffer64 = AcpiTableInstance->Fadt3->Dsdt;\r
+ } else {\r
+ AcpiTableInstance->Fadt3->Dsdt = 0;\r
+ Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;\r
+ }\r
+ CopyMem (&AcpiTableInstance->Fadt3->XDsdt, &Buffer64, sizeof (UINT64));\r
\r
//\r
// Checksum FADT table\r
Checksum)\r
);\r
}\r
- } \r
+ }\r
//\r
// Checksum the table\r
//\r
//\r
// Add to ACPI 2.0/3.0 table tree\r
//\r
- if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
- (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
- if (AddToRsdt) {\r
- //\r
- // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer\r
- //\r
- if (AcpiTableInstance->NumberOfTableEntries3 >= mEfiAcpiMaxNumTables) {\r
- Status = ReallocateAcpiTableBuffer (AcpiTableInstance);\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
- //\r
- // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.\r
- // If it becomes necessary to maintain separate table lists, changes will be required.\r
- //\r
- CurrentRsdtEntry = (UINT32 *)\r
+ if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {\r
+ if (AddToRsdt) {\r
+ //\r
+ // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer\r
+ //\r
+ if (AcpiTableInstance->NumberOfTableEntries3 >= mEfiAcpiMaxNumTables) {\r
+ Status = ReallocateAcpiTableBuffer (AcpiTableInstance);\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ //\r
+ // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.\r
+ // If it becomes necessary to maintain separate table lists, changes will be required.\r
+ //\r
+ CurrentRsdtEntry = (UINT32 *)\r
(\r
(UINT8 *) AcpiTableInstance->Rsdt3 +\r
sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
sizeof (UINT32)\r
);\r
\r
- //\r
- // This pointer must not be directly dereferenced as the XSDT entries may not\r
- // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.\r
- //\r
- CurrentXsdtEntry = (VOID *)\r
- (\r
- (UINT8 *) AcpiTableInstance->Xsdt +\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
- AcpiTableInstance->NumberOfTableEntries3 *\r
- sizeof (UINT64)\r
- );\r
+ //\r
+ // Add entry to the RSDT\r
+ //\r
+ *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;\r
\r
- //\r
- // Add entry to the RSDT\r
- //\r
- *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;\r
-\r
- //\r
- // Update RSDT length\r
- //\r
- AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof (UINT32);\r
-\r
- //\r
- // Add entry to XSDT, XSDT expects 64 bit pointers, but\r
- // the table pointers in XSDT are not aligned on 8 byte boundary.\r
- //\r
- Buffer64 = (UINT64) (UINTN) CurrentTableList->Table;\r
- CopyMem (\r
- CurrentXsdtEntry,\r
- &Buffer64,\r
- sizeof (UINT64)\r
- );\r
+ //\r
+ // Update RSDT length\r
+ //\r
+ AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof (UINT32);\r
+ }\r
\r
- //\r
- // Update length\r
- //\r
- AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + sizeof (UINT64);\r
+ //\r
+ // This pointer must not be directly dereferenced as the XSDT entries may not\r
+ // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.\r
+ //\r
+ CurrentXsdtEntry = (VOID *)\r
+ (\r
+ (UINT8 *) AcpiTableInstance->Xsdt +\r
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
+ AcpiTableInstance->NumberOfTableEntries3 *\r
+ sizeof (UINT64)\r
+ );\r
\r
- AcpiTableInstance->NumberOfTableEntries3++;\r
+ //\r
+ // Add entry to XSDT, XSDT expects 64 bit pointers, but\r
+ // the table pointers in XSDT are not aligned on 8 byte boundary.\r
+ //\r
+ Buffer64 = (UINT64) (UINTN) CurrentTableList->Table;\r
+ CopyMem (\r
+ CurrentXsdtEntry,\r
+ &Buffer64,\r
+ sizeof (UINT64)\r
+ );\r
+\r
+ //\r
+ // Update length\r
+ //\r
+ AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + sizeof (UINT64);\r
+\r
+ AcpiTableInstance->NumberOfTableEntries3++;\r
}\r
}\r
\r
\r
@param Handle Table to find.\r
@param TableList Table list to search\r
- @param Table Pointer to table found. \r
+ @param Table Pointer to table found.\r
\r
@return EFI_SUCCESS The function completed successfully.\r
@return EFI_NOT_FOUND No table found matching the handle specified.\r
For Acpi 1.0 tables, pass in the Rsdt.\r
For Acpi 2.0 tables, pass in both Rsdt and Xsdt.\r
\r
- @param Table Pointer to table found. \r
+ @param Table Pointer to table found.\r
@param NumberOfTableEntries Current number of table entries in the RSDT/XSDT\r
@param Rsdt Pointer to the RSDT to remove from\r
@param Xsdt Pointer to the Xsdt to remove from\r
RemoveTableFromRsdt (\r
IN OUT EFI_ACPI_TABLE_LIST * Table,\r
IN OUT UINTN *NumberOfTableEntries,\r
- IN OUT EFI_ACPI_DESCRIPTION_HEADER * Rsdt,\r
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER * Rsdt OPTIONAL,\r
IN OUT EFI_ACPI_DESCRIPTION_HEADER * Xsdt OPTIONAL\r
)\r
{\r
//\r
ASSERT (Table);\r
ASSERT (NumberOfTableEntries);\r
- ASSERT (Rsdt);\r
+ ASSERT (Rsdt || Xsdt);\r
\r
//\r
// Find the table entry in the RSDT and XSDT\r
// At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.\r
// If it becomes necessary to maintain separate table lists, changes will be required.\r
//\r
- CurrentRsdtEntry = (UINT32 *) ((UINT8 *) Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT32));\r
+ if (Rsdt != NULL) {\r
+ CurrentRsdtEntry = (UINT32 *) ((UINT8 *) Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT32));\r
+ } else {\r
+ CurrentRsdtEntry = NULL;\r
+ }\r
if (Xsdt != NULL) {\r
//\r
// This pointer must not be directly dereferenced as the XSDT entries may not\r
//\r
// Check if we have found the corresponding entry in both RSDT and XSDT\r
//\r
- if (*CurrentRsdtEntry == (UINT32) (UINTN) Table->Table &&\r
+ if (((Rsdt == NULL) || *CurrentRsdtEntry == (UINT32) (UINTN) Table->Table) &&\r
((Xsdt == NULL) || CurrentTablePointer64 == (UINT64) (UINTN) Table->Table)\r
) {\r
//\r
// We actually copy all + 1 to copy the initialized value of memory over\r
// the last entry.\r
//\r
- CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - Index) * sizeof (UINT32));\r
- Rsdt->Length = Rsdt->Length - sizeof (UINT32);\r
+ if (Rsdt != NULL) {\r
+ CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - Index) * sizeof (UINT32));\r
+ Rsdt->Length = Rsdt->Length - sizeof (UINT32);\r
+ }\r
if (Xsdt != NULL) {\r
CopyMem (CurrentXsdtEntry, ((UINT64 *) CurrentXsdtEntry) + 1, (*NumberOfTableEntries - Index) * sizeof (UINT64));\r
Xsdt->Length = Xsdt->Length - sizeof (UINT64);\r
//\r
// Checksum the tables\r
//\r
- AcpiPlatformChecksum (\r
- Rsdt,\r
- Rsdt->Length,\r
- OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
- Checksum)\r
- );\r
+ if (Rsdt != NULL) {\r
+ AcpiPlatformChecksum (\r
+ Rsdt,\r
+ Rsdt->Length,\r
+ OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+ Checksum)\r
+ );\r
+ }\r
\r
if (Xsdt != NULL) {\r
AcpiPlatformChecksum (\r
}\r
}\r
\r
- if ((Version & EFI_ACPI_TABLE_VERSION_2_0 & Table->Version) ||\r
- (Version & EFI_ACPI_TABLE_VERSION_3_0 & Table->Version)) {\r
+ if (Version & ACPI_TABLE_VERSION_GTE_2_0 & Table->Version) {\r
//\r
// Remove this version from the table\r
//\r
- if (Version & EFI_ACPI_TABLE_VERSION_2_0 & Table->Version) {\r
- Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_2_0;\r
- } \r
- if (Version & EFI_ACPI_TABLE_VERSION_3_0 & Table->Version) {\r
- Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_3_0;\r
- }\r
- \r
+ Table->Version = Table->Version &~(Version & ACPI_TABLE_VERSION_GTE_2_0);\r
+\r
//\r
// Remove from Rsdt and Xsdt. We don't care about the return value\r
// because it is acceptable for the table to not exist in Rsdt/Xsdt.\r
AcpiTableInstance->Xsdt\r
);\r
}\r
- } \r
+ }\r
//\r
// Free the table, clean up any dependent tables and our private data pointers.\r
//\r
AcpiTableInstance->Fadt1 = NULL;\r
}\r
\r
- if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
- (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+ if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {\r
AcpiTableInstance->Fadt3 = NULL;\r
}\r
break;\r
}\r
}\r
\r
- if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
- (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+ if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {\r
AcpiTableInstance->Facs3 = NULL;\r
\r
//\r
Checksum)\r
);\r
}\r
- } \r
+ }\r
break;\r
\r
case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
}\r
}\r
\r
- \r
- if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
- (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
+\r
+ if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {\r
AcpiTableInstance->Dsdt3 = NULL;\r
\r
//\r
//\r
// RSDP ACPI 1.0 checksum for 1.0 table. This is only the first 20 bytes of the structure\r
//\r
- AcpiPlatformChecksum (\r
- AcpiTableInstance->Rsdp1,\r
- sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),\r
- OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,\r
- Checksum)\r
- );\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ AcpiPlatformChecksum (\r
+ AcpiTableInstance->Rsdp1,\r
+ sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),\r
+ OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,\r
+ Checksum)\r
+ );\r
+ }\r
\r
//\r
// RSDP ACPI 1.0 checksum for 2.0/3.0 table. This is only the first 20 bytes of the structure\r
ExtendedChecksum)\r
);\r
\r
- //\r
- // RSDT checksums\r
- //\r
- AcpiPlatformChecksum (\r
- AcpiTableInstance->Rsdt1,\r
- AcpiTableInstance->Rsdt1->Length,\r
- OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
- Checksum)\r
- );\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ //\r
+ // RSDT checksums\r
+ //\r
+ AcpiPlatformChecksum (\r
+ AcpiTableInstance->Rsdt1,\r
+ AcpiTableInstance->Rsdt1->Length,\r
+ OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+ Checksum)\r
+ );\r
\r
- AcpiPlatformChecksum (\r
- AcpiTableInstance->Rsdt3,\r
- AcpiTableInstance->Rsdt3->Length,\r
- OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
- Checksum)\r
- );\r
+ AcpiPlatformChecksum (\r
+ AcpiTableInstance->Rsdt3,\r
+ AcpiTableInstance->Rsdt3->Length,\r
+ OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
+ Checksum)\r
+ );\r
+ }\r
\r
//\r
// XSDT checksum\r
OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
Checksum)\r
);\r
- \r
+\r
return EFI_SUCCESS;\r
}\r
\r
//\r
ASSERT (AcpiTableInstance);\r
\r
+ //\r
+ // If ACPI v1.0b is among the ACPI versions we aim to support, we have to\r
+ // ensure that all memory allocations are below 4 GB.\r
+ //\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ mAcpiTableAllocType = AllocateMaxAddress;\r
+ } else {\r
+ mAcpiTableAllocType = AllocateAnyPages;\r
+ }\r
+\r
InitializeListHead (&AcpiTableInstance->TableList);\r
AcpiTableInstance->CurrentHandle = 1;\r
\r
//\r
// Create RSDP table\r
//\r
- RsdpTableSize = sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER) +\r
- sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
+ RsdpTableSize = sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ RsdpTableSize += sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
+ }\r
\r
PageAddress = 0xFFFFFFFF;\r
Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
+ mAcpiTableAllocType,\r
EfiACPIReclaimMemory,\r
EFI_SIZE_TO_PAGES (RsdpTableSize),\r
&PageAddress\r
ZeroMem (Pointer, RsdpTableSize);\r
\r
AcpiTableInstance->Rsdp1 = (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;\r
- Pointer += sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ Pointer += sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
+ }\r
AcpiTableInstance->Rsdp3 = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;\r
\r
//\r
// Create RSDT, XSDT structures\r
//\r
- TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT\r
- mEfiAcpiMaxNumTables * sizeof (UINT32) +\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT\r
- mEfiAcpiMaxNumTables * sizeof (UINT32) +\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT\r
+ TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT\r
mEfiAcpiMaxNumTables * sizeof (UINT64);\r
\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT\r
+ mEfiAcpiMaxNumTables * sizeof (UINT32) +\r
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT\r
+ mEfiAcpiMaxNumTables * sizeof (UINT32);\r
+ }\r
+\r
//\r
// Allocate memory in the lower 32 bit of address range for\r
// compatibility with ACPI 1.0 OS.\r
//\r
PageAddress = 0xFFFFFFFF;\r
Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
+ mAcpiTableAllocType,\r
EfiACPIReclaimMemory,\r
EFI_SIZE_TO_PAGES (TotalSize),\r
&PageAddress\r
ZeroMem (Pointer, TotalSize);\r
\r
AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
- Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));\r
- AcpiTableInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
- Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));\r
+ AcpiTableInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
+ Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));\r
+ }\r
AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
\r
//\r
// Initialize RSDP\r
//\r
- CurrentData = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE;\r
- CopyMem (&AcpiTableInstance->Rsdp1->Signature, &CurrentData, sizeof (UINT64));\r
- CopyMem (AcpiTableInstance->Rsdp1->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdp1->OemId));\r
- AcpiTableInstance->Rsdp1->Reserved = EFI_ACPI_RESERVED_BYTE;\r
- AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt1;\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ CurrentData = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE;\r
+ CopyMem (&AcpiTableInstance->Rsdp1->Signature, &CurrentData, sizeof (UINT64));\r
+ CopyMem (AcpiTableInstance->Rsdp1->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdp1->OemId));\r
+ AcpiTableInstance->Rsdp1->Reserved = EFI_ACPI_RESERVED_BYTE;\r
+ AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt1;\r
+ }\r
\r
CurrentData = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE;\r
CopyMem (&AcpiTableInstance->Rsdp3->Signature, &CurrentData, sizeof (UINT64));\r
CopyMem (AcpiTableInstance->Rsdp3->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdp3->OemId));\r
AcpiTableInstance->Rsdp3->Revision = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION;\r
- AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt3;\r
AcpiTableInstance->Rsdp3->Length = sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt3;\r
+ }\r
CurrentData = (UINT64) (UINTN) AcpiTableInstance->Xsdt;\r
CopyMem (&AcpiTableInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));\r
SetMem (AcpiTableInstance->Rsdp3->Reserved, 3, EFI_ACPI_RESERVED_BYTE);\r
\r
- //\r
- // Initialize Rsdt\r
- //\r
- // Note that we "reserve" one entry for the FADT so it can always be\r
- // at the beginning of the list of tables. Some OS don't seem\r
- // to find it correctly if it is too far down the list.\r
- //\r
- AcpiTableInstance->Rsdt1->Signature = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;\r
- AcpiTableInstance->Rsdt1->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);\r
- AcpiTableInstance->Rsdt1->Revision = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;\r
- CopyMem (AcpiTableInstance->Rsdt1->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdt1->OemId));\r
- CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);\r
- CopyMem (&AcpiTableInstance->Rsdt1->OemTableId, &CurrentData, sizeof (UINT64));\r
- AcpiTableInstance->Rsdt1->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);\r
- AcpiTableInstance->Rsdt1->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);\r
- AcpiTableInstance->Rsdt1->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
- //\r
- // We always reserve first one for FADT\r
- //\r
- AcpiTableInstance->NumberOfTableEntries1 = 1;\r
- AcpiTableInstance->Rsdt1->Length = AcpiTableInstance->Rsdt1->Length + sizeof(UINT32);\r
-\r
- AcpiTableInstance->Rsdt3->Signature = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;\r
- AcpiTableInstance->Rsdt3->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);\r
- AcpiTableInstance->Rsdt3->Revision = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;\r
- CopyMem (AcpiTableInstance->Rsdt3->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdt3->OemId));\r
- CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);\r
- CopyMem (&AcpiTableInstance->Rsdt3->OemTableId, &CurrentData, sizeof (UINT64));\r
- AcpiTableInstance->Rsdt3->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);\r
- AcpiTableInstance->Rsdt3->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);\r
- AcpiTableInstance->Rsdt3->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
- //\r
- // We always reserve first one for FADT\r
- //\r
+ if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
+ //\r
+ // Initialize Rsdt\r
+ //\r
+ // Note that we "reserve" one entry for the FADT so it can always be\r
+ // at the beginning of the list of tables. Some OS don't seem\r
+ // to find it correctly if it is too far down the list.\r
+ //\r
+ AcpiTableInstance->Rsdt1->Signature = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;\r
+ AcpiTableInstance->Rsdt1->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);\r
+ AcpiTableInstance->Rsdt1->Revision = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;\r
+ CopyMem (AcpiTableInstance->Rsdt1->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdt1->OemId));\r
+ CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);\r
+ CopyMem (&AcpiTableInstance->Rsdt1->OemTableId, &CurrentData, sizeof (UINT64));\r
+ AcpiTableInstance->Rsdt1->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);\r
+ AcpiTableInstance->Rsdt1->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);\r
+ AcpiTableInstance->Rsdt1->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
+ //\r
+ // We always reserve first one for FADT\r
+ //\r
+ AcpiTableInstance->NumberOfTableEntries1 = 1;\r
+ AcpiTableInstance->Rsdt1->Length = AcpiTableInstance->Rsdt1->Length + sizeof(UINT32);\r
+\r
+ AcpiTableInstance->Rsdt3->Signature = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;\r
+ AcpiTableInstance->Rsdt3->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);\r
+ AcpiTableInstance->Rsdt3->Revision = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;\r
+ CopyMem (AcpiTableInstance->Rsdt3->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdt3->OemId));\r
+ CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);\r
+ CopyMem (&AcpiTableInstance->Rsdt3->OemTableId, &CurrentData, sizeof (UINT64));\r
+ AcpiTableInstance->Rsdt3->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);\r
+ AcpiTableInstance->Rsdt3->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);\r
+ AcpiTableInstance->Rsdt3->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
+ //\r
+ // We always reserve first one for FADT\r
+ //\r
+ AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof(UINT32);\r
+ }\r
AcpiTableInstance->NumberOfTableEntries3 = 1;\r
- AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof(UINT32);\r
\r
//\r
// Initialize Xsdt\r