public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Laszlo Ersek <lersek@redhat.com>
To: edk2-devel-01 <edk2-devel@lists.01.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Subject: [PATCH 2/5] OvmfPkg/EmuVariableFvbRuntimeDxe: change block size to 4KB
Date: Sat,  6 May 2017 21:30:20 +0200	[thread overview]
Message-ID: <20170506193023.4767-3-lersek@redhat.com> (raw)
In-Reply-To: <20170506193023.4767-1-lersek@redhat.com>

EmuVariableFvbRuntimeDxe currently produces a Firmware Volume Block
protocol that is based on a block map of two blocks, each block having
PcdFlashNvStorageFtwSpareSize for size.

(The total size is 2 * PcdFlashNvStorageFtwSpareSize.)

FaultTolerantWriteDxe in turn expects the block size to be a power of two.

In the 4MB build of OVMF, PcdFlashNvStorageFtwSpareSize is 264KB, which is
not a power of two. In order to equip EmuVariableFvbRuntimeDxe for this
build, shrink the block size to 4KB (EFI_PAGE_SIZE), and grow the block
count from 2 to EFI_SIZE_TO_PAGES(2 * PcdFlashNvStorageFtwSpareSize). The
total size remains

  2 * PcdFlashNvStorageFtwSpareSize
  --------------------------------- * EFI_PAGE_SIZE
            EFI_PAGE_SIZE

Right now EmuVariableFvbRuntimeDxe open-codes the block count of 2 in
various limit checks, so introduce a few new macros:
- EMU_FVB_NUM_TOTAL_BLOCKS, for the LHS of the above product,
- EMU_FVB_NUM_SPARE_BLOCKS for the half of that.

Also rework the FVB protocol members to support an arbitrary count of
blocks.

Keep the invariant intact that the first half of the firmware volume hosts
the variable store and the FTW working block, and that the second half
maps the FTW spare area.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=527
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
 OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.h |  10 +-
 OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.c | 147 +++++++++-----------
 2 files changed, 75 insertions(+), 82 deletions(-)

diff --git a/OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.h b/OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.h
index 4247d21d72f8..beb11e3f9a90 100644
--- a/OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.h
+++ b/OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.h
@@ -58,8 +58,14 @@ typedef struct {
 //
 // Constants
 //
-#define EMU_FVB_BLOCK_SIZE (FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize))
-#define EMU_FVB_SIZE (2 * FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize))
+#define EMU_FVB_BLOCK_SIZE \
+  EFI_PAGE_SIZE
+#define EMU_FVB_NUM_SPARE_BLOCKS \
+  EFI_SIZE_TO_PAGES ((UINTN)FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize))
+#define EMU_FVB_NUM_TOTAL_BLOCKS \
+  (2 * EMU_FVB_NUM_SPARE_BLOCKS)
+#define EMU_FVB_SIZE \
+  (EMU_FVB_NUM_TOTAL_BLOCKS * EMU_FVB_BLOCK_SIZE)
 #define FTW_WRITE_QUEUE_SIZE \
   (FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) - \
    sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER))
diff --git a/OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.c b/OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.c
index 2f89632e5d75..11c8b1b75cb8 100644
--- a/OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.c
+++ b/OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.c
@@ -74,8 +74,8 @@ EFI_FW_VOL_BLOCK_DEVICE mEmuVarsFvb = {
     }
   },
   NULL, // BufferPtr
-  FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize), // BlockSize
-  2 * FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize), // Size
+  EMU_FVB_BLOCK_SIZE, // BlockSize
+  EMU_FVB_SIZE, // Size
   {     // FwVolBlockInstance
     FvbProtocolGetAttributes,
     FvbProtocolSetAttributes,
@@ -185,14 +185,14 @@ FvbProtocolGetBlockSize (
 {
   EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
 
-  if (Lba > 1) {
+  if (Lba >= EMU_FVB_NUM_TOTAL_BLOCKS) {
     return EFI_INVALID_PARAMETER;
   }
 
   FvbDevice = FVB_DEVICE_FROM_THIS (This);
 
   *BlockSize = FvbDevice->BlockSize;
-  *NumberOfBlocks = (UINTN) (2 - (UINTN) Lba);
+  *NumberOfBlocks = (UINTN)(EMU_FVB_NUM_TOTAL_BLOCKS - Lba);
 
   return EFI_SUCCESS;
 }
@@ -322,68 +322,58 @@ FvbProtocolEraseBlocks (
   )
 {
   EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
-  VA_LIST                 args;
+  VA_LIST                 Args;
   EFI_LBA                 StartingLba;
   UINTN                   NumOfLba;
-  UINT8                   Erase;
-  VOID                    *ErasePtr;
+  UINT8                   *ErasePtr;
   UINTN                   EraseSize;
 
   FvbDevice = FVB_DEVICE_FROM_THIS (This);
-  Erase = 0;
-
-  VA_START (args, This);
 
+  //
+  // Check input parameters
+  //
+  VA_START (Args, This);
   do {
-    StartingLba = VA_ARG (args, EFI_LBA);
+    StartingLba = VA_ARG (Args, EFI_LBA);
     if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
       break;
     }
+    NumOfLba = VA_ARG (Args, UINTN);
 
-    NumOfLba = VA_ARG (args, UINT32);
-
-    //
-    // Check input parameters
-    //
-    if ((NumOfLba == 0) || (StartingLba > 1) || ((StartingLba + NumOfLba) > 2)) {
-      VA_END (args);
+    if (StartingLba > EMU_FVB_NUM_TOTAL_BLOCKS ||
+        NumOfLba > EMU_FVB_NUM_TOTAL_BLOCKS - StartingLba) {
+      VA_END (Args);
       return EFI_INVALID_PARAMETER;
     }
-
-    if (StartingLba == 0) {
-      Erase = (UINT8) (Erase | BIT0);
-    }
-    if ((StartingLba + NumOfLba) == 2) {
-      Erase = (UINT8) (Erase | BIT1);
-    }
-
   } while (1);
+  VA_END (Args);
 
-  VA_END (args);
-
-  ErasePtr = (UINT8*) FvbDevice->BufferPtr;
-  EraseSize = 0;
+  //
+  // Erase blocks
+  //
+  VA_START (Args, This);
+  do {
+    StartingLba = VA_ARG (Args, EFI_LBA);
+    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
+      break;
+    }
+    NumOfLba = VA_ARG (Args, UINTN);
 
-  if ((Erase & BIT0) != 0) {
-    EraseSize = EraseSize + FvbDevice->BlockSize;
-  } else {
-    ErasePtr = (VOID*) ((UINT8*)ErasePtr + FvbDevice->BlockSize);
-  }
+    ErasePtr = FvbDevice->BufferPtr;
+    ErasePtr += (UINTN)StartingLba * FvbDevice->BlockSize;
+    EraseSize = NumOfLba * FvbDevice->BlockSize;
 
-  if ((Erase & BIT1) != 0) {
-    EraseSize = EraseSize + FvbDevice->BlockSize;
-  }
+    SetMem (ErasePtr, EraseSize, ERASED_UINT8);
+  } while (1);
+  VA_END (Args);
 
-  if (EraseSize != 0) {
-    SetMem (
-      (VOID*) ErasePtr,
-      EraseSize,
-      ERASED_UINT8
-      );
-    VA_START (args, This);
-    PlatformFvbBlocksErased (This, args);
-    VA_END (args);
-  }
+  //
+  // Call platform hook
+  //
+  VA_START (Args, This);
+  PlatformFvbBlocksErased (This, Args);
+  VA_END (Args);
 
   return EFI_SUCCESS;
 }
@@ -458,31 +448,30 @@ FvbProtocolWrite (
   IN        UINT8                               *Buffer
   )
 {
-
   EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
   UINT8                   *FvbDataPtr;
+  EFI_STATUS              Status;
 
   FvbDevice = FVB_DEVICE_FROM_THIS (This);
 
-  if ((Lba > 1) || (Offset > FvbDevice->BlockSize)) {
+  if (Lba >= EMU_FVB_NUM_TOTAL_BLOCKS ||
+      Offset > FvbDevice->BlockSize) {
     return EFI_INVALID_PARAMETER;
   }
 
-  if ((Offset + *NumBytes) > FvbDevice->BlockSize) {
+  Status = EFI_SUCCESS;
+  if (*NumBytes > FvbDevice->BlockSize - Offset) {
     *NumBytes = FvbDevice->BlockSize - Offset;
+    Status = EFI_BAD_BUFFER_SIZE;
   }
 
-  FvbDataPtr =
-    (UINT8*) FvbDevice->BufferPtr +
-    MultU64x32 (Lba, (UINT32) FvbDevice->BlockSize) +
-    Offset;
+  FvbDataPtr = FvbDevice->BufferPtr;
+  FvbDataPtr += (UINTN)Lba * FvbDevice->BlockSize;
+  FvbDataPtr += Offset;
 
-  if (*NumBytes > 0) {
-    CopyMem (FvbDataPtr, Buffer, *NumBytes);
-    PlatformFvbDataWritten (This, Lba, Offset, *NumBytes, Buffer);
-  }
-
-  return EFI_SUCCESS;
+  CopyMem (FvbDataPtr, Buffer, *NumBytes);
+  PlatformFvbDataWritten (This, Lba, Offset, *NumBytes, Buffer);
+  return Status;
 }
 
 
@@ -545,28 +534,28 @@ FvbProtocolRead (
 {
   EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
   UINT8                   *FvbDataPtr;
+  EFI_STATUS              Status;
 
   FvbDevice = FVB_DEVICE_FROM_THIS (This);
 
-  if ((Lba > 1) || (Offset > FvbDevice->BlockSize)) {
+  if (Lba >= EMU_FVB_NUM_TOTAL_BLOCKS ||
+      Offset > FvbDevice->BlockSize) {
     return EFI_INVALID_PARAMETER;
   }
 
-  if ((Offset + *NumBytes) > FvbDevice->BlockSize) {
+  Status = EFI_SUCCESS;
+  if (*NumBytes > FvbDevice->BlockSize - Offset) {
     *NumBytes = FvbDevice->BlockSize - Offset;
+    Status = EFI_BAD_BUFFER_SIZE;
   }
 
-  FvbDataPtr =
-    (UINT8*) FvbDevice->BufferPtr +
-    MultU64x32 (Lba, (UINT32) FvbDevice->BlockSize) +
-    Offset;
+  FvbDataPtr = FvbDevice->BufferPtr;
+  FvbDataPtr += (UINTN)Lba * FvbDevice->BlockSize;
+  FvbDataPtr += Offset;
 
-  if (*NumBytes > 0) {
-    CopyMem (Buffer, FvbDataPtr, *NumBytes);
-    PlatformFvbDataRead (This, Lba, Offset, *NumBytes, Buffer);
-  }
-
-  return EFI_SUCCESS;
+  CopyMem (Buffer, FvbDataPtr, *NumBytes);
+  PlatformFvbDataRead (This, Lba, Offset, *NumBytes, Buffer);
+  return Status;
 }
 
 
@@ -663,7 +652,7 @@ InitializeFvAndVariableStoreHeaders (
       // EFI_FV_BLOCK_MAP_ENTRY    BlockMap[1];
       {
         {
-          2, // UINT32 NumBlocks;
+          EMU_FVB_NUM_TOTAL_BLOCKS, // UINT32 NumBlocks;
           EMU_FVB_BLOCK_SIZE  // UINT32 Length;
         }
       }
@@ -745,7 +734,7 @@ FvbInitialize (
        (PcdGet32 (PcdVariableStoreSize) +
         PcdGet32 (PcdFlashNvStorageFtwWorkingSize)
        ) >
-       EMU_FVB_BLOCK_SIZE
+       EMU_FVB_NUM_SPARE_BLOCKS * EMU_FVB_BLOCK_SIZE
      ) {
     DEBUG ((EFI_D_ERROR, "EMU Variable invalid PCD sizes\n"));
     return EFI_INVALID_PARAMETER;
@@ -779,10 +768,7 @@ FvbInitialize (
       Initialize = FALSE;
     }
   } else {
-    Ptr = AllocateAlignedRuntimePages (
-            EFI_SIZE_TO_PAGES (EMU_FVB_SIZE),
-            SIZE_64KB
-            );
+    Ptr = AllocateRuntimePages (EFI_SIZE_TO_PAGES (EMU_FVB_SIZE));
   }
 
   mEmuVarsFvb.BufferPtr = Ptr;
@@ -808,7 +794,8 @@ FvbInitialize (
   //
   // Initialize the Fault Tolerant Write spare block
   //
-  SubPtr = (VOID*) ((UINT8*) Ptr + EMU_FVB_BLOCK_SIZE);
+  SubPtr = (VOID*) ((UINT8*) Ptr +
+                    EMU_FVB_NUM_SPARE_BLOCKS * EMU_FVB_BLOCK_SIZE);
   PcdStatus = PcdSet32S (PcdFlashNvStorageFtwSpareBase,
                 (UINT32)(UINTN) SubPtr);
   ASSERT_RETURN_ERROR (PcdStatus);
-- 
2.9.3




  parent reply	other threads:[~2017-05-06 19:30 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-06 19:30 [PATCH 0/5] OvmfPkg: complete the 4MB flash image support ("-bios" / emulated variables) Laszlo Ersek
2017-05-06 19:30 ` [PATCH 1/5] OvmfPkg/EmuVariableFvbRuntimeDxe: strip trailing whitespace Laszlo Ersek
2017-05-12  9:07   ` Gary Lin
2017-05-06 19:30 ` Laszlo Ersek [this message]
2017-05-12  9:07   ` [PATCH 2/5] OvmfPkg/EmuVariableFvbRuntimeDxe: change block size to 4KB Gary Lin
2017-05-15 23:50   ` Jordan Justen
2017-05-06 19:30 ` [PATCH 3/5] OvmfPkg/PlatformPei: align EmuVariableNvStore at any page boundary Laszlo Ersek
2017-05-12  9:08   ` Gary Lin
2017-05-06 19:30 ` [PATCH 4/5] OvmfPkg/README: document 4MB flash layout Laszlo Ersek
2017-05-06 19:30 ` [PATCH 5/5] OvmfPkg: make the 4MB flash size the default (again) Laszlo Ersek
2017-05-08  4:27 ` [PATCH 0/5] OvmfPkg: complete the 4MB flash image support ("-bios" / emulated variables) Gary Lin
2017-05-12  2:02   ` Gary Lin
2017-05-12  8:40     ` Laszlo Ersek
2017-05-16  0:40       ` Jordan Justen
2017-05-16  4:20         ` Gary Lin
2017-05-18 12:36           ` Laszlo Ersek
2017-05-23 14:12             ` Is: Fix for 4MB BIOS payload in hvmloader. Was:Re: " Konrad Rzeszutek Wilk
     [not found]               ` <59246AD9020000780015C380@prv-mh.provo.novell.com>
2017-05-23 16:04                 ` Laszlo Ersek
     [not found]               ` <6af13bb5-0bfb-c9e3-e9fe-d1361d851e7d@arm.com>
2017-05-23 16:20                 ` Laszlo Ersek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170506193023.4767-3-lersek@redhat.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox