MdeModulePkg/AcpiTableDxe: use pool allocation for RSDT/XSDT if possible

If no memory allocation limit is in effect for ACPI tables, prefer
pool allocations over page allocations, to avoid wasting memory on
systems where page based allocations are rounded up to 64 KB, such
as AArch64.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
This commit is contained in:
Ard Biesheuvel 2020-10-16 16:53:53 +02:00 committed by mergify[bot]
parent 0e0ae47da6
commit cf299745ae
1 changed files with 72 additions and 46 deletions

View File

@ -355,28 +355,39 @@ ReallocateAcpiTableBuffer (
NewMaxTableNumber * sizeof (UINT32); NewMaxTableNumber * sizeof (UINT32);
} }
// if (mAcpiTableAllocType != AllocateAnyPages) {
// Allocate memory in the lower 32 bit of address range for //
// compatibility with ACPI 1.0 OS. // Allocate memory in the lower 32 bit of address range for
// // compatibility with ACPI 1.0 OS.
// This is done because ACPI 1.0 pointers are 32 bit values. //
// ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses. // This is done because ACPI 1.0 pointers are 32 bit values.
// There is no architectural reason these should be below 4GB, it is purely // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
// for convenience of implementation that we force memory below 4GB. // There is no architectural reason these should be below 4GB, it is purely
// // for convenience of implementation that we force memory below 4GB.
PageAddress = 0xFFFFFFFF; //
Status = gBS->AllocatePages ( PageAddress = 0xFFFFFFFF;
mAcpiTableAllocType, Status = gBS->AllocatePages (
EfiACPIReclaimMemory, mAcpiTableAllocType,
EFI_SIZE_TO_PAGES (TotalSize), EfiACPIReclaimMemory,
&PageAddress EFI_SIZE_TO_PAGES (TotalSize),
); &PageAddress
);
} else {
Status = gBS->AllocatePool (
EfiACPIReclaimMemory,
TotalSize,
(VOID **)&Pointer
);
}
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
Pointer = (UINT8 *) (UINTN) PageAddress; if (mAcpiTableAllocType != AllocateAnyPages) {
Pointer = (UINT8 *)(UINTN)PageAddress;
}
ZeroMem (Pointer, TotalSize); ZeroMem (Pointer, TotalSize);
AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer; AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;
@ -406,21 +417,26 @@ ReallocateAcpiTableBuffer (
} }
CopyMem (AcpiTableInstance->Xsdt, TempPrivateData.Xsdt, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT64))); CopyMem (AcpiTableInstance->Xsdt, TempPrivateData.Xsdt, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT64)));
// if (mAcpiTableAllocType != AllocateAnyPages) {
// Calculate orignal ACPI table buffer size //
// // Calculate orignal ACPI table buffer size
TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT //
mEfiAcpiMaxNumTables * sizeof (UINT64); TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT
mEfiAcpiMaxNumTables * sizeof (UINT64);
if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) { if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT
mEfiAcpiMaxNumTables * sizeof (UINT32) + mEfiAcpiMaxNumTables * sizeof (UINT32) +
sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT
mEfiAcpiMaxNumTables * sizeof (UINT32); mEfiAcpiMaxNumTables * sizeof (UINT32);
}
gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)TempPrivateData.Rsdt1,
EFI_SIZE_TO_PAGES (TotalSize));
} else {
gBS->FreePool (TempPrivateData.Rsdt1);
} }
gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)TempPrivateData.Rsdt1, EFI_SIZE_TO_PAGES (TotalSize));
// //
// Update the Max ACPI table number // Update the Max ACPI table number
// //
@ -1763,29 +1779,39 @@ AcpiTableAcpiTableConstructor (
mEfiAcpiMaxNumTables * sizeof (UINT32); mEfiAcpiMaxNumTables * sizeof (UINT32);
} }
// if (mAcpiTableAllocType != AllocateAnyPages) {
// Allocate memory in the lower 32 bit of address range for //
// compatibility with ACPI 1.0 OS. // Allocate memory in the lower 32 bit of address range for
// // compatibility with ACPI 1.0 OS.
// This is done because ACPI 1.0 pointers are 32 bit values. //
// ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses. // This is done because ACPI 1.0 pointers are 32 bit values.
// There is no architectural reason these should be below 4GB, it is purely // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
// for convenience of implementation that we force memory below 4GB. // There is no architectural reason these should be below 4GB, it is purely
// // for convenience of implementation that we force memory below 4GB.
PageAddress = 0xFFFFFFFF; //
Status = gBS->AllocatePages ( PageAddress = 0xFFFFFFFF;
mAcpiTableAllocType, Status = gBS->AllocatePages (
EfiACPIReclaimMemory, mAcpiTableAllocType,
EFI_SIZE_TO_PAGES (TotalSize), EfiACPIReclaimMemory,
&PageAddress EFI_SIZE_TO_PAGES (TotalSize),
); &PageAddress
);
} else {
Status = gBS->AllocatePool (
EfiACPIReclaimMemory,
TotalSize,
(VOID **)&Pointer
);
}
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)AcpiTableInstance->Rsdp1, EFI_SIZE_TO_PAGES (RsdpTableSize)); gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)AcpiTableInstance->Rsdp1, EFI_SIZE_TO_PAGES (RsdpTableSize));
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
Pointer = (UINT8 *) (UINTN) PageAddress; if (mAcpiTableAllocType != AllocateAnyPages) {
Pointer = (UINT8 *)(UINTN)PageAddress;
}
ZeroMem (Pointer, TotalSize); ZeroMem (Pointer, TotalSize);
AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer; AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;