OvmfPkg/PlatformPei: handle non-power-of-two spare size for emu variables

In commit b24fca0575 ("OvmfPkg: introduce 4MB flash image (mainly) for
Windows HCK", 2017-04-29), I changed PcdFlashNvStorageFtwSpareSize to
264KB, in the then-new default 4MB build.

While PcdFlashNvStorageFtwSpareSize remains exactly half of the entire
non-volatile store (which is 528KB), 264KB isn't itself a power of two.
This triggers an assertion failure in AllocateAlignedRuntimePages() when
PlatformPei calls it from the ReserveEmuVariableNvStore() function,
passing PcdFlashNvStorageFtwSpareSize as the Alignment parameter:

> ASSERT MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c(196):
> (Alignment & (Alignment - 1)) == 0

Round up the alignment to the next power of two if necessary.

Fixes: b24fca0575
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
Laszlo Ersek 2017-05-05 02:35:21 +02:00
parent 6e49d01cfb
commit 0c79471d6a
1 changed files with 14 additions and 3 deletions

View File

@ -504,6 +504,7 @@ ReserveEmuVariableNvStore (
{ {
EFI_PHYSICAL_ADDRESS VariableStore; EFI_PHYSICAL_ADDRESS VariableStore;
RETURN_STATUS PcdStatus; RETURN_STATUS PcdStatus;
UINT32 Alignment;
// //
// Allocate storage for NV variables early on so it will be // Allocate storage for NV variables early on so it will be
@ -511,16 +512,26 @@ ReserveEmuVariableNvStore (
// across reboots, this allows the NV variable storage to survive // across reboots, this allows the NV variable storage to survive
// a VM reboot. // a VM reboot.
// //
Alignment = PcdGet32 (PcdFlashNvStorageFtwSpareSize);
if ((Alignment & (Alignment - 1)) != 0) {
//
// Round up Alignment to the next power of two.
//
Alignment = GetPowerOfTwo32 (Alignment) << 1;
}
VariableStore = VariableStore =
(EFI_PHYSICAL_ADDRESS)(UINTN) (EFI_PHYSICAL_ADDRESS)(UINTN)
AllocateAlignedRuntimePages ( AllocateAlignedRuntimePages (
EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)), EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)),
PcdGet32 (PcdFlashNvStorageFtwSpareSize) Alignment
); );
DEBUG ((EFI_D_INFO, DEBUG ((EFI_D_INFO,
"Reserved variable store memory: 0x%lX; size: %dkb\n", "Reserved variable store memory: 0x%lX; size: %dkb, "
"alignment: 0x%x\n",
VariableStore, VariableStore,
(2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024 (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024,
Alignment
)); ));
PcdStatus = PcdSet64S (PcdEmuVariableNvStoreReserved, VariableStore); PcdStatus = PcdSet64S (PcdEmuVariableNvStoreReserved, VariableStore);
ASSERT_RETURN_ERROR (PcdStatus); ASSERT_RETURN_ERROR (PcdStatus);