OvmfPkg/PlatformPei: handle non-power-of-two spare size for emu variables
authorLaszlo Ersek <lersek@redhat.com>
Fri, 5 May 2017 00:35:21 +0000 (02:35 +0200)
committerLaszlo Ersek <lersek@redhat.com>
Fri, 5 May 2017 16:02:12 +0000 (18:02 +0200)
In commit b24fca05751f ("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: b24fca05751f8222acf264853709012e0ab7bf49
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
OvmfPkg/PlatformPei/Platform.c

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