diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c index eb79dbadbf..ae446270fa 100644 --- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c +++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c @@ -355,28 +355,39 @@ ReallocateAcpiTableBuffer ( NewMaxTableNumber * sizeof (UINT32); } - // - // 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. - // 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 ( - mAcpiTableAllocType, - EfiACPIReclaimMemory, - EFI_SIZE_TO_PAGES (TotalSize), - &PageAddress - ); + if (mAcpiTableAllocType != AllocateAnyPages) { + // + // 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. + // 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 ( + mAcpiTableAllocType, + EfiACPIReclaimMemory, + EFI_SIZE_TO_PAGES (TotalSize), + &PageAddress + ); + } else { + Status = gBS->AllocatePool ( + EfiACPIReclaimMemory, + TotalSize, + (VOID **)&Pointer + ); + } if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } - Pointer = (UINT8 *) (UINTN) PageAddress; + if (mAcpiTableAllocType != AllocateAnyPages) { + Pointer = (UINT8 *)(UINTN)PageAddress; + } + ZeroMem (Pointer, TotalSize); 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))); - // - // Calculate orignal ACPI table buffer size - // - TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT - mEfiAcpiMaxNumTables * sizeof (UINT64); + if (mAcpiTableAllocType != AllocateAnyPages) { + // + // Calculate orignal ACPI table buffer size + // + 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) { - TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT - mEfiAcpiMaxNumTables * sizeof (UINT32) + - sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT - mEfiAcpiMaxNumTables * sizeof (UINT32); + if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) { + TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT + mEfiAcpiMaxNumTables * sizeof (UINT32) + + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT + 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 // @@ -1763,29 +1779,39 @@ AcpiTableAcpiTableConstructor ( mEfiAcpiMaxNumTables * sizeof (UINT32); } - // - // 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. - // 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 ( - mAcpiTableAllocType, - EfiACPIReclaimMemory, - EFI_SIZE_TO_PAGES (TotalSize), - &PageAddress - ); + if (mAcpiTableAllocType != AllocateAnyPages) { + // + // 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. + // 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 ( + mAcpiTableAllocType, + EfiACPIReclaimMemory, + EFI_SIZE_TO_PAGES (TotalSize), + &PageAddress + ); + } else { + Status = gBS->AllocatePool ( + EfiACPIReclaimMemory, + TotalSize, + (VOID **)&Pointer + ); + } if (EFI_ERROR (Status)) { gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)AcpiTableInstance->Rsdp1, EFI_SIZE_TO_PAGES (RsdpTableSize)); return EFI_OUT_OF_RESOURCES; } - Pointer = (UINT8 *) (UINTN) PageAddress; + if (mAcpiTableAllocType != AllocateAnyPages) { + Pointer = (UINT8 *)(UINTN)PageAddress; + } ZeroMem (Pointer, TotalSize); AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;