* Sat Feb 03 2024 Jon Maloy <jmaloy@redhat.com> - 20220126gitbb1bba3d77-10

- edk2-OvmfPkg-VirtNorFlashDxe-clone-ArmPlatformPkg-s-NOR-f.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-remove-CheckBlockLocked-feat.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-remove-disk-I-O-protocol-imp.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-drop-block-I-O-protocol-impl.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-avoid-array-mode-switch-afte.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-avoid-switching-between-mode.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-use-EFI_MEMORY_WC-and-drop-A.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-map-flash-memory-as-uncachea.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-stop-accepting-gEfiVariable2.patch [RHEL-17587]
-  edk2-OvmfPkg-VirtNorFlashDxe-sanity-check-variable2.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-add-casts-to-UINTN-and-UINT3.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-clarify-block-write-logic-fi.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-add-a-loop-for-NorFlashWrite.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-allow-larger-writes-without-.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-ValidateFvHeader-unwritten-s.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-move-DoErase-code-block-into.patch [RHEL-17587]
- edk2-ArmVirtPkg-ArmVirtQemu-migrate-to-OVMF-s-VirtNorFlas.patch [RHEL-17587]
- edk2-OvmfPkg-clone-NorFlashPlatformLib-into-VirtNorFlashP.patch [RHEL-17587]
- Resolves: RHEL-17587
  ([rhel8] guest fails to boot due to ASSERT error)
This commit is contained in:
Jon Maloy 2024-02-03 15:24:15 -05:00
parent ad8cc2ba61
commit d6671b1ccc
19 changed files with 5600 additions and 1 deletions

View File

@ -0,0 +1,149 @@
From 9ef10bbe9a03f22aa5c5ff659012794d37ef9839 Mon Sep 17 00:00:00 2001
From: Ard Biesheuvel <ardb@kernel.org>
Date: Mon, 24 Oct 2022 18:41:22 +0200
Subject: [PATCH 17/18] ArmVirtPkg/ArmVirtQemu: migrate to OVMF's
VirtNorFlashDxe
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [19/20] 2160140b0ea566451ab723e941d2ab91e1ad874e
Switch to the virt specific NorFlashDxe driver implementation that was
added recently.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
(cherry picked from commit b92298af8218dd074c231947bc95f2be94af663c)
---
ArmVirtPkg/ArmVirtQemu.dsc | 4 ++--
ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 2 +-
ArmVirtPkg/ArmVirtQemuKernel.dsc | 4 ++--
ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c | 12 ++++++------
.../Library/NorFlashQemuLib/NorFlashQemuLib.inf | 4 ++--
5 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc
index e6fad9f066..2b23becf30 100644
--- a/ArmVirtPkg/ArmVirtQemu.dsc
+++ b/ArmVirtPkg/ArmVirtQemu.dsc
@@ -67,7 +67,7 @@
ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
- NorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
+ VirtNorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
@@ -400,7 +400,7 @@
<LibraryClasses>
NULL|ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.inf
}
- ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
+ OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
#
diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
index f6a538df72..7c655d384d 100644
--- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
+++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
@@ -73,7 +73,7 @@ READ_LOCK_STATUS = TRUE
INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
- INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
+ INF OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
#
diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc
index 656c9d99a3..344e2c4ed9 100644
--- a/ArmVirtPkg/ArmVirtQemuKernel.dsc
+++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc
@@ -65,7 +65,7 @@
ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.inf
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
- NorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
+ VirtNorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
@@ -329,7 +329,7 @@
<LibraryClasses>
NULL|ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.inf
}
- ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
+ OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
#
diff --git a/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c b/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c
index 271d7f0efb..93a2fed40f 100644
--- a/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c
+++ b/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c
@@ -8,8 +8,8 @@
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
-#include <Library/NorFlashPlatformLib.h>
#include <Library/UefiBootServicesTableLib.h>
+#include <Library/VirtNorFlashPlatformLib.h>
#include <Protocol/FdtClient.h>
@@ -18,19 +18,19 @@
#define MAX_FLASH_BANKS 4
EFI_STATUS
-NorFlashPlatformInitialization (
+VirtNorFlashPlatformInitialization (
VOID
)
{
return EFI_SUCCESS;
}
-NOR_FLASH_DESCRIPTION mNorFlashDevices[MAX_FLASH_BANKS];
+STATIC VIRT_NOR_FLASH_DESCRIPTION mNorFlashDevices[MAX_FLASH_BANKS];
EFI_STATUS
-NorFlashPlatformGetDevices (
- OUT NOR_FLASH_DESCRIPTION **NorFlashDescriptions,
- OUT UINT32 *Count
+VirtNorFlashPlatformGetDevices (
+ OUT VIRT_NOR_FLASH_DESCRIPTION **NorFlashDescriptions,
+ OUT UINT32 *Count
)
{
FDT_CLIENT_PROTOCOL *FdtClient;
diff --git a/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf b/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
index 4c3683bf5d..a6b5865be9 100644
--- a/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
+++ b/ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
@@ -14,17 +14,17 @@
FILE_GUID = 339B7829-4C5F-4EFC-B2DD-5050E530DECE
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
- LIBRARY_CLASS = NorFlashPlatformLib
+ LIBRARY_CLASS = VirtNorFlashPlatformLib
[Sources.common]
NorFlashQemuLib.c
[Packages]
MdePkg/MdePkg.dec
- ArmPlatformPkg/ArmPlatformPkg.dec
ArmPkg/ArmPkg.dec
ArmVirtPkg/ArmVirtPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
+ OvmfPkg/OvmfPkg.dec
[LibraryClasses]
BaseLib
--
2.41.0

View File

@ -0,0 +1,47 @@
From f2aeff31924f6d070d7f8b87550dc6d9820531ad Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 16 Jan 2024 18:11:04 +0100
Subject: [PATCH 15/18] OvmfPkg/VirtNorFlashDxe: ValidateFvHeader: unwritten
state is EOL too
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [17/20] 37220c700ea816c815e0612031e10b7d466b71a2
It is possible to find variable entries with State being 0xff, i.e. not
updated since flash block erase. This indicates the variable driver
could not complete the header write while appending a new entry, and
therefore State was not set to VAR_HEADER_VALID_ONLY.
This can only happen at the end of the variable list, so treat this as
additional "end of variable list" condition.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20240116171105.37831-6-kraxel@redhat.com>
(cherry picked from commit 735d0a5e2e25c1577bf9bea7826da937ca38169d)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c
index acc4a413ee..f8e71f88c1 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c
@@ -302,6 +302,11 @@ ValidateFvHeader (
break;
}
+ if (VarHeader->State == 0xff) {
+ DEBUG ((DEBUG_INFO, "%a: end of var list (unwritten state)\n", __func__));
+ break;
+ }
+
VarName = NULL;
switch (VarHeader->State) {
// usage: State = VAR_HEADER_VALID_ONLY
--
2.41.0

View File

@ -0,0 +1,73 @@
From 00d9e2d6cb03afeef5a1110d6f1fae1389a06f7a Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 16 Jan 2024 18:11:02 +0100
Subject: [PATCH 13/18] OvmfPkg/VirtNorFlashDxe: add a loop for
NorFlashWriteBuffer calls.
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [15/20] 72004a196ea61d627ab528573db657dd7db16de2
Replace the two NorFlashWriteBuffer() calls with a loop containing a
single NorFlashWriteBuffer() call.
With the changes in place the code is able to handle updates larger
than two P30_MAX_BUFFER_SIZE_IN_BYTES blocks, even though the patch
does not actually change the size limit.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20240116171105.37831-4-kraxel@redhat.com>
(cherry picked from commit 28ffd726894f11a587a6ac7f71a4c4af341e24d2)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c | 21 ++++++++-------------
1 file changed, 8 insertions(+), 13 deletions(-)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
index 88a4d2c23f..3d1343b381 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
@@ -521,6 +521,7 @@ NorFlashWriteSingleBlock (
UINTN BlockAddress;
UINT8 *OrigData;
UINTN Start, End;
+ UINT32 Index, Count;
DEBUG ((DEBUG_BLKIO, "NorFlashWriteSingleBlock(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer));
@@ -621,23 +622,17 @@ NorFlashWriteSingleBlock (
goto Exit;
}
- Status = NorFlashWriteBuffer (
- Instance,
- BlockAddress + Start,
- P30_MAX_BUFFER_SIZE_IN_BYTES,
- Instance->ShadowBuffer
- );
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
-
- if ((End - Start) > P30_MAX_BUFFER_SIZE_IN_BYTES) {
+ Count = (End - Start) / P30_MAX_BUFFER_SIZE_IN_BYTES;
+ for (Index = 0; Index < Count; Index++) {
Status = NorFlashWriteBuffer (
Instance,
- BlockAddress + Start + P30_MAX_BUFFER_SIZE_IN_BYTES,
+ BlockAddress + Start + Index * P30_MAX_BUFFER_SIZE_IN_BYTES,
P30_MAX_BUFFER_SIZE_IN_BYTES,
- Instance->ShadowBuffer + P30_MAX_BUFFER_SIZE_IN_BYTES
+ Instance->ShadowBuffer + Index * P30_MAX_BUFFER_SIZE_IN_BYTES
);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
}
Exit:
--
2.41.0

View File

@ -0,0 +1,55 @@
From e8150ee7fdf1421d2e2801c901e0196496ef599e Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 16 Jan 2024 18:11:00 +0100
Subject: [PATCH 11/18] OvmfPkg/VirtNorFlashDxe: add casts to UINTN and UINT32
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [13/20] fa695acadb9d693242b5221d2bc1958b929718e7
This is needed to avoid bit operations being applied to signed integers.
Suggested-by: László Érsek <lersek@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20240116171105.37831-2-kraxel@redhat.com>
(cherry picked from commit 0395045ae307c43a41f72ca9a8bf4eb8f16b2fe0)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c | 2 +-
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
index 1afd60ce66..7f4743b003 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
@@ -581,7 +581,7 @@ NorFlashWriteSingleBlock (
// contents, while checking whether the old version had any bits cleared
// that we want to set. In that case, we will need to erase the block first.
for (CurOffset = 0; CurOffset < *NumBytes; CurOffset++) {
- if (~OrigData[CurOffset] & Buffer[CurOffset]) {
+ if (~(UINT32)OrigData[CurOffset] & (UINT32)Buffer[CurOffset]) {
goto DoErase;
}
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h
index b7f5d208b2..455eafacc2 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h
@@ -61,7 +61,7 @@
#define P30_MAX_BUFFER_SIZE_IN_BYTES ((UINTN)128)
#define P30_MAX_BUFFER_SIZE_IN_WORDS (P30_MAX_BUFFER_SIZE_IN_BYTES/((UINTN)4))
#define MAX_BUFFERED_PROG_ITERATIONS 10000000
-#define BOUNDARY_OF_32_WORDS 0x7F
+#define BOUNDARY_OF_32_WORDS ((UINTN)0x7F)
// CFI Addresses
#define P30_CFI_ADDR_QUERY_UNIQUE_QRY 0x10
--
2.41.0

View File

@ -0,0 +1,65 @@
From 0193a89b0db837da31301bc1edb8382927842978 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 16 Jan 2024 18:11:03 +0100
Subject: [PATCH 14/18] OvmfPkg/VirtNorFlashDxe: allow larger writes without
block erase
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [16/20] 27ac63b90eb5e6fdc00cbc5a9105c3178ee559cd
Raise the limit for writes without block erase from two to four
P30_MAX_BUFFER_SIZE_IN_BYTES blocks. With this in place almost all efi
variable updates are handled without block erase. With the old limit
some variable updates (with device paths) took the block erase code
path.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20240116171105.37831-5-kraxel@redhat.com>
(cherry picked from commit b25733c97442513890ae6bb8e10fd340f13844a7)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
index 3d1343b381..3d1d20daa1 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
@@ -550,13 +550,15 @@ NorFlashWriteSingleBlock (
return EFI_BAD_BUFFER_SIZE;
}
- // Pick P30_MAX_BUFFER_SIZE_IN_BYTES (== 128 bytes) as a good start for word
- // operations as opposed to erasing the block and writing the data regardless
- // if an erase is really needed. It looks like most individual NV variable
- // writes are smaller than 128 bytes.
- // To avoid pathological cases were a 2 byte write is disregarded because it
- // occurs right at a 128 byte buffered write alignment boundary, permit up to
- // twice the max buffer size, and perform two writes if needed.
+ // Pick 4 * P30_MAX_BUFFER_SIZE_IN_BYTES (== 512 bytes) as a good
+ // start for word operations as opposed to erasing the block and
+ // writing the data regardless if an erase is really needed.
+ //
+ // Many NV variable updates are small enough for a a single
+ // P30_MAX_BUFFER_SIZE_IN_BYTES block write. In case the update is
+ // larger than a single block, or the update crosses a
+ // P30_MAX_BUFFER_SIZE_IN_BYTES boundary (as shown in the diagram
+ // below), or both, we might have to write two or more blocks.
//
// 0 128 256
// [----------------|----------------]
@@ -578,7 +580,7 @@ NorFlashWriteSingleBlock (
Start = Offset & ~BOUNDARY_OF_32_WORDS;
End = ALIGN_VALUE (Offset + *NumBytes, P30_MAX_BUFFER_SIZE_IN_BYTES);
- if ((End - Start) <= (2 * P30_MAX_BUFFER_SIZE_IN_BYTES)) {
+ if ((End - Start) <= (4 * P30_MAX_BUFFER_SIZE_IN_BYTES)) {
// Check to see if we need to erase before programming the data into NOR.
// If the destination bits are only changing from 1s to 0s we can just write.
// After a block is erased all bits in the block is set to 1.
--
2.41.0

View File

@ -0,0 +1,89 @@
From 20ba071dabad6b0f5663083a017799b7a6e684c5 Mon Sep 17 00:00:00 2001
From: Ard Biesheuvel <ardb@kernel.org>
Date: Mon, 24 Oct 2022 17:34:09 +0200
Subject: [PATCH 05/18] OvmfPkg/VirtNorFlashDxe: avoid array mode switch after
each word write
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [7/20] 274f2ed71a6d5d3f6497129ee3c62f494cc2f067
NorFlashWriteSingleWord() switches into programming mode and back into
array mode for every single word that it writes. Under KVM, this
involves tearing down the read-only memslot, and setting it up again,
which is costly and unnecessary.
Instead, move the array mode switch into the callers, and only make the
switch when the writing is done.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
(cherry picked from commit ca01e6216a8d1a26c69018e216d1dc3f88a819a4)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c | 12 +++---------
OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c | 3 +++
2 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
index f41d9d372f..0a5c5d48c7 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
@@ -205,9 +205,6 @@ NorFlashWriteSingleWord (
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_CLEAR_STATUS_REGISTER);
}
- // Put device back into Read Array mode
- SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
-
return Status;
}
@@ -286,8 +283,7 @@ NorFlashWriteBuffer (
// The buffer was not available for writing
if (WaitForBuffer == 0) {
- Status = EFI_DEVICE_ERROR;
- goto EXIT;
+ return EFI_DEVICE_ERROR;
}
// From now on we work in 32-bit words
@@ -337,10 +333,6 @@ NorFlashWriteBuffer (
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_CLEAR_STATUS_REGISTER);
}
-EXIT:
- // Put device back into Read Array mode
- SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
-
return Status;
}
@@ -739,6 +731,8 @@ NorFlashWriteSingleBlock (
}
TempStatus = NorFlashWriteSingleWord (Instance, WordAddr, WordToWrite);
+ // Put device back into Read Array mode
+ SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
if (EFI_ERROR (TempStatus)) {
return EFI_DEVICE_ERROR;
}
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
index 2ceda22635..f9a41f6aab 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
@@ -280,6 +280,9 @@ NorFlashWriteFullBlock (
}
EXIT:
+ // Put device back into Read Array mode
+ SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
+
if (!EfiAtRuntime ()) {
// Interruptions can resume.
gBS->RestoreTPL (OriginalTPL);
--
2.41.0

View File

@ -0,0 +1,303 @@
From 67e26db39c0ec90c164634251da761f649546529 Mon Sep 17 00:00:00 2001
From: Ard Biesheuvel <ardb@kernel.org>
Date: Mon, 24 Oct 2022 17:58:07 +0200
Subject: [PATCH 06/18] OvmfPkg/VirtNorFlashDxe: avoid switching between modes
in a tight loop
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [8/20] 4923b0fb1586d7955be466b90dce5f790da704ff
Currently, when dealing with small updates that can be written out
directly (i.e., if they only involve clearing bits and not setting bits,
as the latter requires a block level erase), we iterate over the data
one word at a time, read the old value, compare it, write the new value,
and repeat, unless we encountered a value that we cannot write (0->1
transition), in which case we fall back to a block level operation.
This is inefficient for two reasons:
- reading and writing a word at a time involves switching between array
and programming mode for every word of data, which is
disproportionately costly when running under KVM;
- we end up writing some data twice, as we may not notice that a block
erase is needed until after some data has been written to flash.
So replace this sequence with a single read of up to twice the buffered
write maximum size, followed by one or two buffered writes if the data
can be written directly. Otherwise, fall back to the existing block
level sequence, but without writing out part of the data twice.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
(cherry picked from commit 25589c4a76e7e3668fd6f794dd1827e958b6719c)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c | 214 +++++++++----------------
1 file changed, 76 insertions(+), 138 deletions(-)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
index 0a5c5d48c7..0343131a54 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
@@ -576,23 +576,20 @@ NorFlashWriteSingleBlock (
IN UINT8 *Buffer
)
{
- EFI_STATUS TempStatus;
- UINT32 Tmp;
- UINT32 TmpBuf;
- UINT32 WordToWrite;
- UINT32 Mask;
- BOOLEAN DoErase;
- UINTN BytesToWrite;
+ EFI_STATUS Status;
UINTN CurOffset;
- UINTN WordAddr;
UINTN BlockSize;
UINTN BlockAddress;
- UINTN PrevBlockAddress;
-
- PrevBlockAddress = 0;
+ UINT8 *OrigData;
DEBUG ((DEBUG_BLKIO, "NorFlashWriteSingleBlock(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer));
+ // Check we did get some memory. Buffer is BlockSize.
+ if (Instance->ShadowBuffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "FvbWrite: ERROR - Buffer not ready\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
// Cache the block size to avoid de-referencing pointers all the time
BlockSize = Instance->BlockSize;
@@ -612,148 +609,89 @@ NorFlashWriteSingleBlock (
return EFI_BAD_BUFFER_SIZE;
}
- // Pick 128bytes as a good start for word operations as opposed to erasing the
- // block and writing the data regardless if an erase is really needed.
- // It looks like most individual NV variable writes are smaller than 128bytes.
- if (*NumBytes <= 128) {
+ // Pick P30_MAX_BUFFER_SIZE_IN_BYTES (== 128 bytes) as a good start for word
+ // operations as opposed to erasing the block and writing the data regardless
+ // if an erase is really needed. It looks like most individual NV variable
+ // writes are smaller than 128 bytes.
+ // To avoid pathological cases were a 2 byte write is disregarded because it
+ // occurs right at a 128 byte buffered write alignment boundary, permit up to
+ // twice the max buffer size, and perform two writes if needed.
+ if ((*NumBytes + (Offset & BOUNDARY_OF_32_WORDS)) <= (2 * P30_MAX_BUFFER_SIZE_IN_BYTES)) {
// Check to see if we need to erase before programming the data into NOR.
// If the destination bits are only changing from 1s to 0s we can just write.
// After a block is erased all bits in the block is set to 1.
// If any byte requires us to erase we just give up and rewrite all of it.
- DoErase = FALSE;
- BytesToWrite = *NumBytes;
- CurOffset = Offset;
-
- while (BytesToWrite > 0) {
- // Read full word from NOR, splice as required. A word is the smallest
- // unit we can write.
- TempStatus = NorFlashRead (Instance, Lba, CurOffset & ~(0x3), sizeof (Tmp), &Tmp);
- if (EFI_ERROR (TempStatus)) {
- return EFI_DEVICE_ERROR;
- }
- // Physical address of word in NOR to write.
- WordAddr = (CurOffset & ~(0x3)) + GET_NOR_BLOCK_ADDRESS (
- Instance->RegionBaseAddress,
- Lba,
- BlockSize
- );
- // The word of data that is to be written.
- TmpBuf = *((UINT32 *)(Buffer + (*NumBytes - BytesToWrite)));
-
- // First do word aligned chunks.
- if ((CurOffset & 0x3) == 0) {
- if (BytesToWrite >= 4) {
- // Is the destination still in 'erased' state?
- if (~Tmp != 0) {
- // Check to see if we are only changing bits to zero.
- if ((Tmp ^ TmpBuf) & TmpBuf) {
- DoErase = TRUE;
- break;
- }
- }
-
- // Write this word to NOR
- WordToWrite = TmpBuf;
- CurOffset += sizeof (TmpBuf);
- BytesToWrite -= sizeof (TmpBuf);
- } else {
- // BytesToWrite < 4. Do small writes and left-overs
- Mask = ~((~0) << (BytesToWrite * 8));
- // Mask out the bytes we want.
- TmpBuf &= Mask;
- // Is the destination still in 'erased' state?
- if ((Tmp & Mask) != Mask) {
- // Check to see if we are only changing bits to zero.
- if ((Tmp ^ TmpBuf) & TmpBuf) {
- DoErase = TRUE;
- break;
- }
- }
-
- // Merge old and new data. Write merged word to NOR
- WordToWrite = (Tmp & ~Mask) | TmpBuf;
- CurOffset += BytesToWrite;
- BytesToWrite = 0;
- }
- } else {
- // Do multiple words, but starting unaligned.
- if (BytesToWrite > (4 - (CurOffset & 0x3))) {
- Mask = ((~0) << ((CurOffset & 0x3) * 8));
- // Mask out the bytes we want.
- TmpBuf &= Mask;
- // Is the destination still in 'erased' state?
- if ((Tmp & Mask) != Mask) {
- // Check to see if we are only changing bits to zero.
- if ((Tmp ^ TmpBuf) & TmpBuf) {
- DoErase = TRUE;
- break;
- }
- }
-
- // Merge old and new data. Write merged word to NOR
- WordToWrite = (Tmp & ~Mask) | TmpBuf;
- BytesToWrite -= (4 - (CurOffset & 0x3));
- CurOffset += (4 - (CurOffset & 0x3));
- } else {
- // Unaligned and fits in one word.
- Mask = (~((~0) << (BytesToWrite * 8))) << ((CurOffset & 0x3) * 8);
- // Mask out the bytes we want.
- TmpBuf = (TmpBuf << ((CurOffset & 0x3) * 8)) & Mask;
- // Is the destination still in 'erased' state?
- if ((Tmp & Mask) != Mask) {
- // Check to see if we are only changing bits to zero.
- if ((Tmp ^ TmpBuf) & TmpBuf) {
- DoErase = TRUE;
- break;
- }
- }
-
- // Merge old and new data. Write merged word to NOR
- WordToWrite = (Tmp & ~Mask) | TmpBuf;
- CurOffset += BytesToWrite;
- BytesToWrite = 0;
- }
+ // Read the old version of the data into the shadow buffer
+ Status = NorFlashRead (
+ Instance,
+ Lba,
+ Offset & ~BOUNDARY_OF_32_WORDS,
+ (*NumBytes | BOUNDARY_OF_32_WORDS) + 1,
+ Instance->ShadowBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Make OrigData point to the start of the old version of the data inside
+ // the word aligned buffer
+ OrigData = Instance->ShadowBuffer + (Offset & BOUNDARY_OF_32_WORDS);
+
+ // Update the buffer containing the old version of the data with the new
+ // contents, while checking whether the old version had any bits cleared
+ // that we want to set. In that case, we will need to erase the block first.
+ for (CurOffset = 0; CurOffset < *NumBytes; CurOffset++) {
+ if (~OrigData[CurOffset] & Buffer[CurOffset]) {
+ goto DoErase;
}
- //
- // Write the word to NOR.
- //
+ OrigData[CurOffset] = Buffer[CurOffset];
+ }
- BlockAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba, BlockSize);
- if (BlockAddress != PrevBlockAddress) {
- TempStatus = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);
- if (EFI_ERROR (TempStatus)) {
- return EFI_DEVICE_ERROR;
- }
+ //
+ // Write the updated buffer to NOR.
+ //
+ BlockAddress = GET_NOR_BLOCK_ADDRESS (Instance->RegionBaseAddress, Lba, BlockSize);
- PrevBlockAddress = BlockAddress;
- }
+ // Unlock the block if we have to
+ Status = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
- TempStatus = NorFlashWriteSingleWord (Instance, WordAddr, WordToWrite);
- // Put device back into Read Array mode
- SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
- if (EFI_ERROR (TempStatus)) {
- return EFI_DEVICE_ERROR;
- }
+ Status = NorFlashWriteBuffer (
+ Instance,
+ BlockAddress + (Offset & ~BOUNDARY_OF_32_WORDS),
+ P30_MAX_BUFFER_SIZE_IN_BYTES,
+ Instance->ShadowBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
}
- // Exit if we got here and could write all the data. Otherwise do the
- // Erase-Write cycle.
- if (!DoErase) {
- return EFI_SUCCESS;
+ if ((*NumBytes + (Offset & BOUNDARY_OF_32_WORDS)) > P30_MAX_BUFFER_SIZE_IN_BYTES) {
+ BlockAddress += P30_MAX_BUFFER_SIZE_IN_BYTES;
+
+ Status = NorFlashWriteBuffer (
+ Instance,
+ BlockAddress + (Offset & ~BOUNDARY_OF_32_WORDS),
+ P30_MAX_BUFFER_SIZE_IN_BYTES,
+ Instance->ShadowBuffer + P30_MAX_BUFFER_SIZE_IN_BYTES
+ );
}
- }
- // Check we did get some memory. Buffer is BlockSize.
- if (Instance->ShadowBuffer == NULL) {
- DEBUG ((DEBUG_ERROR, "FvbWrite: ERROR - Buffer not ready\n"));
- return EFI_DEVICE_ERROR;
+Exit:
+ // Put device back into Read Array mode
+ SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
+
+ return Status;
}
+DoErase:
// Read NOR Flash data into shadow buffer
- TempStatus = NorFlashReadBlocks (Instance, Lba, BlockSize, Instance->ShadowBuffer);
- if (EFI_ERROR (TempStatus)) {
+ Status = NorFlashReadBlocks (Instance, Lba, BlockSize, Instance->ShadowBuffer);
+ if (EFI_ERROR (Status)) {
// Return one of the pre-approved error statuses
return EFI_DEVICE_ERROR;
}
@@ -762,8 +700,8 @@ NorFlashWriteSingleBlock (
CopyMem ((VOID *)((UINTN)Instance->ShadowBuffer + Offset), Buffer, *NumBytes);
// Write the modified buffer back to the NorFlash
- TempStatus = NorFlashWriteBlocks (Instance, Lba, BlockSize, Instance->ShadowBuffer);
- if (EFI_ERROR (TempStatus)) {
+ Status = NorFlashWriteBlocks (Instance, Lba, BlockSize, Instance->ShadowBuffer);
+ if (EFI_ERROR (Status)) {
// Return one of the pre-approved error statuses
return EFI_DEVICE_ERROR;
}
--
2.41.0

View File

@ -0,0 +1,110 @@
From f136d4895b1477a56b916a76448ba76e67b08163 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 16 Jan 2024 18:11:01 +0100
Subject: [PATCH 12/18] OvmfPkg/VirtNorFlashDxe: clarify block write logic &
fix shadowbuffer reads
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [14/20] 38009625e5f189166f7a93e236576140a7ccb393
Introduce 'Start' and 'End' variables to make it easier to follow the
logic and code flow. Also add a ascii art diagram (based on a
suggestion by Laszlo).
This also fixes the 'Size' calculation for the NorFlashRead() call.
Without this patch the code will read only one instead of two
P30_MAX_BUFFER_SIZE_IN_BYTES blocks in case '*NumBytes' is smaller than
P30_MAX_BUFFER_SIZE_IN_BYTES but 'Offset + *NumBytes' is not, i.e. the
update range crosses a P30_MAX_BUFFER_SIZE_IN_BYTES boundary.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20240116171105.37831-3-kraxel@redhat.com>
(cherry picked from commit 35d8ea8097794b522149688b5cfaf8364bc44d54)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c | 36 ++++++++++++++++++++------
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
index 7f4743b003..88a4d2c23f 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
@@ -520,6 +520,7 @@ NorFlashWriteSingleBlock (
UINTN BlockSize;
UINTN BlockAddress;
UINT8 *OrigData;
+ UINTN Start, End;
DEBUG ((DEBUG_BLKIO, "NorFlashWriteSingleBlock(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer));
@@ -555,7 +556,28 @@ NorFlashWriteSingleBlock (
// To avoid pathological cases were a 2 byte write is disregarded because it
// occurs right at a 128 byte buffered write alignment boundary, permit up to
// twice the max buffer size, and perform two writes if needed.
- if ((*NumBytes + (Offset & BOUNDARY_OF_32_WORDS)) <= (2 * P30_MAX_BUFFER_SIZE_IN_BYTES)) {
+ //
+ // 0 128 256
+ // [----------------|----------------]
+ // ^ ^ ^ ^
+ // | | | |
+ // | | | End, the next "word" boundary beyond
+ // | | | the (logical) update
+ // | | |
+ // | | (Offset & BOUNDARY_OF_32_WORDS) + NumBytes;
+ // | | i.e., the relative offset inside (or just past)
+ // | | the *double-word* such that it is the
+ // | | *exclusive* end of the (logical) update.
+ // | |
+ // | Offset & BOUNDARY_OF_32_WORDS; i.e., Offset within the "word";
+ // | this is where the (logical) update is supposed to start
+ // |
+ // Start = Offset & ~BOUNDARY_OF_32_WORDS; i.e., Offset truncated to "word" boundary
+
+ Start = Offset & ~BOUNDARY_OF_32_WORDS;
+ End = ALIGN_VALUE (Offset + *NumBytes, P30_MAX_BUFFER_SIZE_IN_BYTES);
+
+ if ((End - Start) <= (2 * P30_MAX_BUFFER_SIZE_IN_BYTES)) {
// Check to see if we need to erase before programming the data into NOR.
// If the destination bits are only changing from 1s to 0s we can just write.
// After a block is erased all bits in the block is set to 1.
@@ -565,8 +587,8 @@ NorFlashWriteSingleBlock (
Status = NorFlashRead (
Instance,
Lba,
- Offset & ~BOUNDARY_OF_32_WORDS,
- (*NumBytes | BOUNDARY_OF_32_WORDS) + 1,
+ Start,
+ End - Start,
Instance->ShadowBuffer
);
if (EFI_ERROR (Status)) {
@@ -601,7 +623,7 @@ NorFlashWriteSingleBlock (
Status = NorFlashWriteBuffer (
Instance,
- BlockAddress + (Offset & ~BOUNDARY_OF_32_WORDS),
+ BlockAddress + Start,
P30_MAX_BUFFER_SIZE_IN_BYTES,
Instance->ShadowBuffer
);
@@ -609,12 +631,10 @@ NorFlashWriteSingleBlock (
goto Exit;
}
- if ((*NumBytes + (Offset & BOUNDARY_OF_32_WORDS)) > P30_MAX_BUFFER_SIZE_IN_BYTES) {
- BlockAddress += P30_MAX_BUFFER_SIZE_IN_BYTES;
-
+ if ((End - Start) > P30_MAX_BUFFER_SIZE_IN_BYTES) {
Status = NorFlashWriteBuffer (
Instance,
- BlockAddress + (Offset & ~BOUNDARY_OF_32_WORDS),
+ BlockAddress + Start + P30_MAX_BUFFER_SIZE_IN_BYTES,
P30_MAX_BUFFER_SIZE_IN_BYTES,
Instance->ShadowBuffer + P30_MAX_BUFFER_SIZE_IN_BYTES
);
--
2.41.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,504 @@
From 8cf16599ade30de07c9b51f90d2208046f74fee6 Mon Sep 17 00:00:00 2001
From: Ard Biesheuvel <ardb@kernel.org>
Date: Mon, 24 Oct 2022 17:12:08 +0200
Subject: [PATCH 04/18] OvmfPkg/VirtNorFlashDxe: drop block I/O protocol
implementation
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [6/20] 6843078997a30c2818e0d53a90fb7f6accb89aaf
We never boot from NOR flash, and generally rely on the firmware volume
PI protocols to expose the contents. So drop the block I/O protocol
implementation from VirtNorFlashDxe.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
(cherry picked from commit 83f11f957240ead9b135a778316330762b0a3acb)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c | 49 ++++++------------
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h | 54 ++------------------
OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c | 40 +++------------
OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf | 1 -
OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c | 55 ++++++++-------------
5 files changed, 45 insertions(+), 154 deletions(-)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
index 1094d48f7d..f41d9d372f 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
@@ -366,10 +366,6 @@ NorFlashWriteBlocks (
return EFI_INVALID_PARAMETER;
}
- if (Instance->Media.ReadOnly == TRUE) {
- return EFI_WRITE_PROTECTED;
- }
-
// We must have some bytes to read
DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: BufferSizeInBytes=0x%x\n", BufferSizeInBytes));
if (BufferSizeInBytes == 0) {
@@ -377,22 +373,22 @@ NorFlashWriteBlocks (
}
// The size of the buffer must be a multiple of the block size
- DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: BlockSize in bytes =0x%x\n", Instance->Media.BlockSize));
- if ((BufferSizeInBytes % Instance->Media.BlockSize) != 0) {
+ DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: BlockSize in bytes =0x%x\n", Instance->BlockSize));
+ if ((BufferSizeInBytes % Instance->BlockSize) != 0) {
return EFI_BAD_BUFFER_SIZE;
}
// All blocks must be within the device
- NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->Media.BlockSize;
+ NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->BlockSize;
- DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: NumBlocks=%d, LastBlock=%ld, Lba=%ld.\n", NumBlocks, Instance->Media.LastBlock, Lba));
+ DEBUG ((DEBUG_BLKIO, "NorFlashWriteBlocks: NumBlocks=%d, LastBlock=%ld, Lba=%ld.\n", NumBlocks, Instance->LastBlock, Lba));
- if ((Lba + NumBlocks) > (Instance->Media.LastBlock + 1)) {
+ if ((Lba + NumBlocks) > (Instance->LastBlock + 1)) {
DEBUG ((DEBUG_ERROR, "NorFlashWriteBlocks: ERROR - Write will exceed last block.\n"));
return EFI_INVALID_PARAMETER;
}
- BlockSizeInWords = Instance->Media.BlockSize / 4;
+ BlockSizeInWords = Instance->BlockSize / 4;
// Because the target *Buffer is a pointer to VOID, we must put all the data into a pointer
// to a proper data type, so use *ReadBuffer
@@ -489,8 +485,8 @@ NorFlashReadBlocks (
DEBUG_BLKIO,
"NorFlashReadBlocks: BufferSize=0x%xB BlockSize=0x%xB LastBlock=%ld, Lba=%ld.\n",
BufferSizeInBytes,
- Instance->Media.BlockSize,
- Instance->Media.LastBlock,
+ Instance->BlockSize,
+ Instance->LastBlock,
Lba
));
@@ -505,14 +501,14 @@ NorFlashReadBlocks (
}
// The size of the buffer must be a multiple of the block size
- if ((BufferSizeInBytes % Instance->Media.BlockSize) != 0) {
+ if ((BufferSizeInBytes % Instance->BlockSize) != 0) {
return EFI_BAD_BUFFER_SIZE;
}
// All blocks must be within the device
- NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->Media.BlockSize;
+ NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->BlockSize;
- if ((Lba + NumBlocks) > (Instance->Media.LastBlock + 1)) {
+ if ((Lba + NumBlocks) > (Instance->LastBlock + 1)) {
DEBUG ((DEBUG_ERROR, "NorFlashReadBlocks: ERROR - Read will exceed last block\n"));
return EFI_INVALID_PARAMETER;
}
@@ -521,7 +517,7 @@ NorFlashReadBlocks (
StartAddress = GET_NOR_BLOCK_ADDRESS (
Instance->RegionBaseAddress,
Lba,
- Instance->Media.BlockSize
+ Instance->BlockSize
);
// Put the device into Read Array mode
@@ -554,7 +550,7 @@ NorFlashRead (
return EFI_SUCCESS;
}
- if (((Lba * Instance->Media.BlockSize) + Offset + BufferSizeInBytes) > Instance->Size) {
+ if (((Lba * Instance->BlockSize) + Offset + BufferSizeInBytes) > Instance->Size) {
DEBUG ((DEBUG_ERROR, "NorFlashRead: ERROR - Read will exceed device size.\n"));
return EFI_INVALID_PARAMETER;
}
@@ -563,7 +559,7 @@ NorFlashRead (
StartAddress = GET_NOR_BLOCK_ADDRESS (
Instance->RegionBaseAddress,
Lba,
- Instance->Media.BlockSize
+ Instance->BlockSize
);
// Put the device into Read Array mode
@@ -577,7 +573,7 @@ NorFlashRead (
/*
Write a full or portion of a block. It must not span block boundaries; that is,
- Offset + *NumBytes <= Instance->Media.BlockSize.
+ Offset + *NumBytes <= Instance->BlockSize.
*/
EFI_STATUS
NorFlashWriteSingleBlock (
@@ -605,15 +601,8 @@ NorFlashWriteSingleBlock (
DEBUG ((DEBUG_BLKIO, "NorFlashWriteSingleBlock(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer));
- // Detect WriteDisabled state
- if (Instance->Media.ReadOnly == TRUE) {
- DEBUG ((DEBUG_ERROR, "NorFlashWriteSingleBlock: ERROR - Can not write: Device is in WriteDisabled state.\n"));
- // It is in WriteDisabled state, return an error right away
- return EFI_ACCESS_DENIED;
- }
-
// Cache the block size to avoid de-referencing pointers all the time
- BlockSize = Instance->Media.BlockSize;
+ BlockSize = Instance->BlockSize;
// The write must not span block boundaries.
// We need to check each variable individually because adding two large values together overflows.
@@ -819,12 +808,6 @@ NorFlashVirtualNotifyEvent (
EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->DeviceBaseAddress);
EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->RegionBaseAddress);
- // Convert BlockIo protocol
- EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->BlockIoProtocol.FlushBlocks);
- EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->BlockIoProtocol.ReadBlocks);
- EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->BlockIoProtocol.Reset);
- EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->BlockIoProtocol.WriteBlocks);
-
// Convert Fvb
EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->FvbProtocol.EraseBlocks);
EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->FvbProtocol.GetAttributes);
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h
index 7733ee02ee..b7f5d208b2 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h
@@ -14,7 +14,6 @@
#include <Guid/EventGroup.h>
-#include <Protocol/BlockIo.h>
#include <Protocol/FirmwareVolumeBlock.h>
#include <Library/DebugLib.h>
@@ -108,8 +107,7 @@
#define P30_CMD_READ_CONFIGURATION_REGISTER 0x0003
#define NOR_FLASH_SIGNATURE SIGNATURE_32('n', 'o', 'r', '0')
-#define INSTANCE_FROM_FVB_THIS(a) CR(a, NOR_FLASH_INSTANCE, FvbProtocol, NOR_FLASH_SIGNATURE)
-#define INSTANCE_FROM_BLKIO_THIS(a) CR(a, NOR_FLASH_INSTANCE, BlockIoProtocol, NOR_FLASH_SIGNATURE)
+#define INSTANCE_FROM_FVB_THIS(a) CR(a, NOR_FLASH_INSTANCE, FvbProtocol, NOR_FLASH_SIGNATURE)
typedef struct _NOR_FLASH_INSTANCE NOR_FLASH_INSTANCE;
@@ -129,9 +127,8 @@ struct _NOR_FLASH_INSTANCE {
UINTN RegionBaseAddress;
UINTN Size;
EFI_LBA StartLba;
-
- EFI_BLOCK_IO_PROTOCOL BlockIoProtocol;
- EFI_BLOCK_IO_MEDIA Media;
+ EFI_LBA LastBlock;
+ UINT32 BlockSize;
EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;
VOID *ShadowBuffer;
@@ -155,51 +152,6 @@ NorFlashWriteBuffer (
IN UINT32 *Buffer
);
-//
-// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.Reset
-//
-EFI_STATUS
-EFIAPI
-NorFlashBlockIoReset (
- IN EFI_BLOCK_IO_PROTOCOL *This,
- IN BOOLEAN ExtendedVerification
- );
-
-//
-// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks
-//
-EFI_STATUS
-EFIAPI
-NorFlashBlockIoReadBlocks (
- IN EFI_BLOCK_IO_PROTOCOL *This,
- IN UINT32 MediaId,
- IN EFI_LBA Lba,
- IN UINTN BufferSizeInBytes,
- OUT VOID *Buffer
- );
-
-//
-// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks
-//
-EFI_STATUS
-EFIAPI
-NorFlashBlockIoWriteBlocks (
- IN EFI_BLOCK_IO_PROTOCOL *This,
- IN UINT32 MediaId,
- IN EFI_LBA Lba,
- IN UINTN BufferSizeInBytes,
- IN VOID *Buffer
- );
-
-//
-// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks
-//
-EFI_STATUS
-EFIAPI
-NorFlashBlockIoFlushBlocks (
- IN EFI_BLOCK_IO_PROTOCOL *This
- );
-
//
// NorFlashFvbDxe.c
//
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
index 4875b057d5..2ceda22635 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
@@ -34,29 +34,8 @@ NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {
0, // RegionBaseAddress ... NEED TO BE FILLED
0, // Size ... NEED TO BE FILLED
0, // StartLba
-
- {
- EFI_BLOCK_IO_PROTOCOL_REVISION2, // Revision
- NULL, // Media ... NEED TO BE FILLED
- NorFlashBlockIoReset, // Reset;
- NorFlashBlockIoReadBlocks, // ReadBlocks
- NorFlashBlockIoWriteBlocks, // WriteBlocks
- NorFlashBlockIoFlushBlocks // FlushBlocks
- }, // BlockIoProtocol
-
- {
- 0, // MediaId ... NEED TO BE FILLED
- FALSE, // RemovableMedia
- TRUE, // MediaPresent
- FALSE, // LogicalPartition
- FALSE, // ReadOnly
- FALSE, // WriteCaching;
- 0, // BlockSize ... NEED TO BE FILLED
- 4, // IoAlign
- 0, // LastBlock ... NEED TO BE FILLED
- 0, // LowestAlignedLba
- 1, // LogicalBlocksPerPhysicalBlock
- }, // Media;
+ 0, // LastBlock
+ 0, // BlockSize
{
FvbGetAttributes, // GetAttributes
@@ -115,11 +94,8 @@ NorFlashCreateInstance (
Instance->DeviceBaseAddress = NorFlashDeviceBase;
Instance->RegionBaseAddress = NorFlashRegionBase;
Instance->Size = NorFlashSize;
-
- Instance->BlockIoProtocol.Media = &Instance->Media;
- Instance->Media.MediaId = Index;
- Instance->Media.BlockSize = BlockSize;
- Instance->Media.LastBlock = (NorFlashSize / BlockSize)-1;
+ Instance->BlockSize = BlockSize;
+ Instance->LastBlock = (NorFlashSize / BlockSize) - 1;
CopyGuid (&Instance->DevicePath.Vendor.Guid, &gEfiCallerIdGuid);
Instance->DevicePath.Index = (UINT8)Index;
@@ -136,8 +112,6 @@ NorFlashCreateInstance (
&Instance->Handle,
&gEfiDevicePathProtocolGuid,
&Instance->DevicePath,
- &gEfiBlockIoProtocolGuid,
- &Instance->BlockIoProtocol,
&gEfiFirmwareVolumeBlockProtocolGuid,
&Instance->FvbProtocol,
NULL
@@ -151,8 +125,6 @@ NorFlashCreateInstance (
&Instance->Handle,
&gEfiDevicePathProtocolGuid,
&Instance->DevicePath,
- &gEfiBlockIoProtocolGuid,
- &Instance->BlockIoProtocol,
NULL
);
if (EFI_ERROR (Status)) {
@@ -434,7 +406,7 @@ NorFlashFvbInitialize (
PcdGet64 (PcdFlashNvStorageVariableBase64) : PcdGet32 (PcdFlashNvStorageVariableBase);
// Set the index of the first LBA for the FVB
- Instance->StartLba = (mFlashNvStorageVariableBase - Instance->RegionBaseAddress) / Instance->Media.BlockSize;
+ Instance->StartLba = (mFlashNvStorageVariableBase - Instance->RegionBaseAddress) / Instance->BlockSize;
BootMode = GetBootModeHob ();
if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
@@ -455,7 +427,7 @@ NorFlashFvbInitialize (
));
// Erase all the NorFlash that is reserved for variable storage
- FvbNumLba = (PcdGet32 (PcdFlashNvStorageVariableSize) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) + PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize;
+ FvbNumLba = (PcdGet32 (PcdFlashNvStorageVariableSize) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) + PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / Instance->BlockSize;
Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR);
if (EFI_ERROR (Status)) {
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
index 53e9d58204..2a3d4a218e 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
@@ -19,7 +19,6 @@
[Sources.common]
VirtNorFlash.c
VirtNorFlash.h
- VirtNorFlashBlockIoDxe.c
VirtNorFlashDxe.c
VirtNorFlashFvb.c
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c
index c824e0a0fb..cc5eefaaf3 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c
@@ -89,7 +89,7 @@ InitializeFvAndVariableStoreHeaders (
}
// Check if the size of the area is at least one block size
- if ((NvStorageVariableSize <= 0) || (NvStorageVariableSize / Instance->Media.BlockSize <= 0)) {
+ if ((NvStorageVariableSize <= 0) || (NvStorageVariableSize / Instance->BlockSize <= 0)) {
DEBUG ((
DEBUG_ERROR,
"%a: NvStorageVariableSize is 0x%x, should be atleast one block size\n",
@@ -99,7 +99,7 @@ InitializeFvAndVariableStoreHeaders (
return EFI_INVALID_PARAMETER;
}
- if ((NvStorageFtwWorkingSize <= 0) || (NvStorageFtwWorkingSize / Instance->Media.BlockSize <= 0)) {
+ if ((NvStorageFtwWorkingSize <= 0) || (NvStorageFtwWorkingSize / Instance->BlockSize <= 0)) {
DEBUG ((
DEBUG_ERROR,
"%a: NvStorageFtwWorkingSize is 0x%x, should be atleast one block size\n",
@@ -109,7 +109,7 @@ InitializeFvAndVariableStoreHeaders (
return EFI_INVALID_PARAMETER;
}
- if ((NvStorageFtwSpareSize <= 0) || (NvStorageFtwSpareSize / Instance->Media.BlockSize <= 0)) {
+ if ((NvStorageFtwSpareSize <= 0) || (NvStorageFtwSpareSize / Instance->BlockSize <= 0)) {
DEBUG ((
DEBUG_ERROR,
"%a: NvStorageFtwSpareSize is 0x%x, should be atleast one block size\n",
@@ -120,9 +120,9 @@ InitializeFvAndVariableStoreHeaders (
}
// Ensure the Variable area Base Addresses are aligned on a block size boundaries
- if ((NvStorageVariableBase % Instance->Media.BlockSize != 0) ||
- (NvStorageFtwWorkingBase % Instance->Media.BlockSize != 0) ||
- (NvStorageFtwSpareBase % Instance->Media.BlockSize != 0))
+ if ((NvStorageVariableBase % Instance->BlockSize != 0) ||
+ (NvStorageFtwWorkingBase % Instance->BlockSize != 0) ||
+ (NvStorageFtwSpareBase % Instance->BlockSize != 0))
{
DEBUG ((DEBUG_ERROR, "%a: NvStorage Base addresses must be aligned to block size boundaries", __FUNCTION__));
return EFI_INVALID_PARAMETER;
@@ -149,8 +149,8 @@ InitializeFvAndVariableStoreHeaders (
);
FirmwareVolumeHeader->HeaderLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY);
FirmwareVolumeHeader->Revision = EFI_FVH_REVISION;
- FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->Media.LastBlock + 1;
- FirmwareVolumeHeader->BlockMap[0].Length = Instance->Media.BlockSize;
+ FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->LastBlock + 1;
+ FirmwareVolumeHeader->BlockMap[0].Length = Instance->BlockSize;
FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0;
FirmwareVolumeHeader->BlockMap[1].Length = 0;
FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16 *)FirmwareVolumeHeader, FirmwareVolumeHeader->HeaderLength);
@@ -284,9 +284,6 @@ FvbGetAttributes (
)
{
EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes;
- NOR_FLASH_INSTANCE *Instance;
-
- Instance = INSTANCE_FROM_FVB_THIS (This);
FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2)(
@@ -294,17 +291,12 @@ FvbGetAttributes (
EFI_FVB2_READ_STATUS | // Reads are currently enabled
EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
EFI_FVB2_MEMORY_MAPPED | // It is memory mapped
- EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1')
+ EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1')
+ EFI_FVB2_WRITE_STATUS | // Writes are currently enabled
+ EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled
);
- // Check if it is write protected
- if (Instance->Media.ReadOnly != TRUE) {
- FlashFvbAttributes = FlashFvbAttributes |
- EFI_FVB2_WRITE_STATUS | // Writes are currently enabled
- EFI_FVB2_WRITE_ENABLED_CAP; // Writes may be enabled
- }
-
*Attributes = FlashFvbAttributes;
DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes));
@@ -418,15 +410,15 @@ FvbGetBlockSize (
Instance = INSTANCE_FROM_FVB_THIS (This);
- DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize(Lba=%ld, BlockSize=0x%x, LastBlock=%ld)\n", Lba, Instance->Media.BlockSize, Instance->Media.LastBlock));
+ DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize(Lba=%ld, BlockSize=0x%x, LastBlock=%ld)\n", Lba, Instance->BlockSize, Instance->LastBlock));
- if (Lba > Instance->Media.LastBlock) {
- DEBUG ((DEBUG_ERROR, "FvbGetBlockSize: ERROR - Parameter LBA %ld is beyond the last Lba (%ld).\n", Lba, Instance->Media.LastBlock));
+ if (Lba > Instance->LastBlock) {
+ DEBUG ((DEBUG_ERROR, "FvbGetBlockSize: ERROR - Parameter LBA %ld is beyond the last Lba (%ld).\n", Lba, Instance->LastBlock));
Status = EFI_INVALID_PARAMETER;
} else {
// This is easy because in this platform each NorFlash device has equal sized blocks.
- *BlockSize = (UINTN)Instance->Media.BlockSize;
- *NumberOfBlocks = (UINTN)(Instance->Media.LastBlock - Lba + 1);
+ *BlockSize = (UINTN)Instance->BlockSize;
+ *NumberOfBlocks = (UINTN)(Instance->LastBlock - Lba + 1);
DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize: *BlockSize=0x%x, *NumberOfBlocks=0x%x.\n", *BlockSize, *NumberOfBlocks));
@@ -498,7 +490,7 @@ FvbRead (
TempStatus = EFI_SUCCESS;
// Cache the block size to avoid de-referencing pointers all the time
- BlockSize = Instance->Media.BlockSize;
+ BlockSize = Instance->BlockSize;
DEBUG ((DEBUG_BLKIO, "FvbRead: Check if (Offset=0x%x + NumBytes=0x%x) <= BlockSize=0x%x\n", Offset, *NumBytes, BlockSize));
@@ -669,13 +661,6 @@ FvbEraseBlocks (
Status = EFI_SUCCESS;
- // Detect WriteDisabled state
- if (Instance->Media.ReadOnly == TRUE) {
- // Firmware volume is in WriteDisabled state
- DEBUG ((DEBUG_ERROR, "FvbEraseBlocks: ERROR - Device is in WriteDisabled state.\n"));
- return EFI_ACCESS_DENIED;
- }
-
// Before erasing, check the entire list of parameters to ensure all specified blocks are valid
VA_START (Args, This);
@@ -698,9 +683,9 @@ FvbEraseBlocks (
"FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%Lu - 1 ) > LastBlock=%ld.\n",
Instance->StartLba + StartingLba,
(UINT64)NumOfLba,
- Instance->Media.LastBlock
+ Instance->LastBlock
));
- if ((NumOfLba == 0) || ((Instance->StartLba + StartingLba + NumOfLba - 1) > Instance->Media.LastBlock)) {
+ if ((NumOfLba == 0) || ((Instance->StartLba + StartingLba + NumOfLba - 1) > Instance->LastBlock)) {
VA_END (Args);
DEBUG ((DEBUG_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n"));
Status = EFI_INVALID_PARAMETER;
@@ -733,7 +718,7 @@ FvbEraseBlocks (
BlockAddress = GET_NOR_BLOCK_ADDRESS (
Instance->RegionBaseAddress,
Instance->StartLba + StartingLba,
- Instance->Media.BlockSize
+ Instance->BlockSize
);
// Erase it
--
2.41.0

View File

@ -0,0 +1,67 @@
From 15415de9a228e74ff1847777a29f1531754b03b0 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Wed, 11 Jan 2023 19:00:23 +0100
Subject: [PATCH 08/18] OvmfPkg/VirtNorFlashDxe: map flash memory as
uncacheable
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [10/20] 40ca967bead9ec5c98c528bfe0757f75f3d3352f
Switching from the ArmPlatformPkg/NorFlashDxe driver to the
OvmfPkg/VirtNorFlashDxe driver had the side effect that flash address
space got registered as EFI_MEMORY_WC instead of EFI_MEMORY_UC.
That confuses the linux kernel's numa code, seems this makes kernel
consider the flash being node memory. "lsmem" changes from ...
RANGE SIZE STATE REMOVABLE BLOCK
0x0000000040000000-0x000000013fffffff 4G online yes 8-39
... to ...
RANGE SIZE STATE REMOVABLE BLOCK
0x0000000000000000-0x0000000007ffffff 128M online yes 0
0x0000000040000000-0x000000013fffffff 4G online yes 8-39
... and in the kernel log got new error lines:
NUMA: Warning: invalid memblk node 512 [mem 0x0000000004000000-0x0000000007ffffff]
NUMA: Faking a node at [mem 0x0000000004000000-0x000000013fffffff]
Changing the attributes back to EFI_MEMORY_UC fixes this.
Fixes: b92298af8218 ("ArmVirtPkg/ArmVirtQemu: migrate to OVMF's VirtNorFlashDxe")
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
(cherry picked from commit e5ec3ba409b5baa9cf429cc25fdf3c8d1b8dcef0)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
index ff3121af2a..f9a41f6aab 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
@@ -394,14 +394,14 @@ NorFlashFvbInitialize (
EfiGcdMemoryTypeMemoryMappedIo,
Instance->DeviceBaseAddress,
RuntimeMmioRegionSize,
- EFI_MEMORY_WC | EFI_MEMORY_RUNTIME
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
);
ASSERT_EFI_ERROR (Status);
Status = gDS->SetMemorySpaceAttributes (
Instance->DeviceBaseAddress,
RuntimeMmioRegionSize,
- EFI_MEMORY_WC | EFI_MEMORY_RUNTIME
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
);
ASSERT_EFI_ERROR (Status);
--
2.41.0

View File

@ -0,0 +1,131 @@
From 791c26a4a172b4a609a708db8018411ab653de4a Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 16 Jan 2024 18:11:05 +0100
Subject: [PATCH 16/18] OvmfPkg/VirtNorFlashDxe: move DoErase code block into
new function
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [18/20] 10f4685bfcb0c5423e392b4cf0e8633cd25b46b4
Move the DoErase code block into a separate function, call the function
instead of jumping around with goto.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-Id: <20240116171105.37831-7-kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
(cherry picked from commit b481b00f593ef37695ee14271453320ed02a1256)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c | 76 ++++++++++++++++++--------
1 file changed, 52 insertions(+), 24 deletions(-)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
index 3d1d20daa1..e6aaed27ce 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
@@ -502,6 +502,38 @@ NorFlashRead (
return EFI_SUCCESS;
}
+STATIC
+EFI_STATUS
+NorFlashWriteSingleBlockWithErase (
+ IN NOR_FLASH_INSTANCE *Instance,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+
+ // Read NOR Flash data into shadow buffer
+ Status = NorFlashReadBlocks (Instance, Lba, Instance->BlockSize, Instance->ShadowBuffer);
+ if (EFI_ERROR (Status)) {
+ // Return one of the pre-approved error statuses
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Put the data at the appropriate location inside the buffer area
+ CopyMem ((VOID *)((UINTN)Instance->ShadowBuffer + Offset), Buffer, *NumBytes);
+
+ // Write the modified buffer back to the NorFlash
+ Status = NorFlashWriteBlocks (Instance, Lba, Instance->BlockSize, Instance->ShadowBuffer);
+ if (EFI_ERROR (Status)) {
+ // Return one of the pre-approved error statuses
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
/*
Write a full or portion of a block. It must not span block boundaries; that is,
Offset + *NumBytes <= Instance->BlockSize.
@@ -607,7 +639,14 @@ NorFlashWriteSingleBlock (
// that we want to set. In that case, we will need to erase the block first.
for (CurOffset = 0; CurOffset < *NumBytes; CurOffset++) {
if (~(UINT32)OrigData[CurOffset] & (UINT32)Buffer[CurOffset]) {
- goto DoErase;
+ Status = NorFlashWriteSingleBlockWithErase (
+ Instance,
+ Lba,
+ Offset,
+ NumBytes,
+ Buffer
+ );
+ return Status;
}
OrigData[CurOffset] = Buffer[CurOffset];
@@ -636,33 +675,22 @@ NorFlashWriteSingleBlock (
goto Exit;
}
}
-
-Exit:
- // Put device back into Read Array mode
- SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
-
+ } else {
+ Status = NorFlashWriteSingleBlockWithErase (
+ Instance,
+ Lba,
+ Offset,
+ NumBytes,
+ Buffer
+ );
return Status;
}
-DoErase:
- // Read NOR Flash data into shadow buffer
- Status = NorFlashReadBlocks (Instance, Lba, BlockSize, Instance->ShadowBuffer);
- if (EFI_ERROR (Status)) {
- // Return one of the pre-approved error statuses
- return EFI_DEVICE_ERROR;
- }
-
- // Put the data at the appropriate location inside the buffer area
- CopyMem ((VOID *)((UINTN)Instance->ShadowBuffer + Offset), Buffer, *NumBytes);
-
- // Write the modified buffer back to the NorFlash
- Status = NorFlashWriteBlocks (Instance, Lba, BlockSize, Instance->ShadowBuffer);
- if (EFI_ERROR (Status)) {
- // Return one of the pre-approved error statuses
- return EFI_DEVICE_ERROR;
- }
+Exit:
+ // Put device back into Read Array mode
+ SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
- return EFI_SUCCESS;
+ return Status;
}
EFI_STATUS
--
2.41.0

View File

@ -0,0 +1,94 @@
From 03e0a729a5c3ebcab8806d136cd8908627bd91c9 Mon Sep 17 00:00:00 2001
From: Ard Biesheuvel <ardb@kernel.org>
Date: Mon, 24 Oct 2022 16:45:02 +0200
Subject: [PATCH 02/18] OvmfPkg/VirtNorFlashDxe: remove CheckBlockLocked
feature
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [4/20] 990bdf373801df8107d8a6ec4db3fb93e5a6ad68
We inherited a feature from the ArmPlatformPkg version of this driver
that never gets enabled. Let's remove it.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
(cherry picked from commit 0a64106c566273ff8ef951d56ddfa972fe65bd6c)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c | 35 +++++----------------
OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf | 3 --
2 files changed, 8 insertions(+), 30 deletions(-)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
index 12fa720dad..59a562efdf 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
@@ -65,35 +65,16 @@ NorFlashUnlockSingleBlock (
// Raise the Task Priority Level to TPL_NOTIFY to serialise all its operations
// and to protect shared data structures.
- if (FeaturePcdGet (PcdNorFlashCheckBlockLocked) == TRUE) {
- do {
- // Request a lock setup
- SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_LOCK_BLOCK_SETUP);
+ // Request a lock setup
+ SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_LOCK_BLOCK_SETUP);
- // Request an unlock
- SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_UNLOCK_BLOCK);
+ // Request an unlock
+ SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_UNLOCK_BLOCK);
- // Send command for reading device id
- SEND_NOR_COMMAND (BlockAddress, 2, P30_CMD_READ_DEVICE_ID);
-
- // Read block lock status
- LockStatus = MmioRead32 (CREATE_NOR_ADDRESS (BlockAddress, 2));
-
- // Decode block lock status
- LockStatus = FOLD_32BIT_INTO_16BIT (LockStatus);
- } while ((LockStatus & 0x1) == 1);
- } else {
- // Request a lock setup
- SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_LOCK_BLOCK_SETUP);
-
- // Request an unlock
- SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_UNLOCK_BLOCK);
-
- // Wait until the status register gives us the all clear
- do {
- LockStatus = NorFlashReadStatusRegister (Instance, BlockAddress);
- } while ((LockStatus & P30_SR_BIT_WRITE) != P30_SR_BIT_WRITE);
- }
+ // Wait until the status register gives us the all clear
+ do {
+ LockStatus = NorFlashReadStatusRegister (Instance, BlockAddress);
+ } while ((LockStatus & P30_SR_BIT_WRITE) != P30_SR_BIT_WRITE);
// Put device back into Read Array mode
SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_READ_ARRAY);
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
index 1bf50e4823..53e9d58204 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
@@ -24,7 +24,6 @@
VirtNorFlashFvb.c
[Packages]
- ArmPlatformPkg/ArmPlatformPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
@@ -66,7 +65,5 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
- gArmPlatformTokenSpaceGuid.PcdNorFlashCheckBlockLocked
-
[Depex]
gEfiCpuArchProtocolGuid
--
2.41.0

View File

@ -0,0 +1,386 @@
From 56041232238e4e4d3c8d703b27f51b0bc70fd5c8 Mon Sep 17 00:00:00 2001
From: Ard Biesheuvel <ardb@kernel.org>
Date: Mon, 24 Oct 2022 16:50:05 +0200
Subject: [PATCH 03/18] OvmfPkg/VirtNorFlashDxe: remove disk I/O protocol
implementation
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [5/20] 0551c3f56f43396cfdc380127565e89d69eb29a3
We only use NOR flash for firmware volumes, either for executable images
or for the variable store. So we have no need for exposing disk I/O on
top of the NOR flash partitions so let's remove it.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
(cherry picked from commit 68d234989b2d6bd8f255577e08bf8be0b1d197bb)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c | 129 ------------------
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h | 29 ----
.../VirtNorFlashDxe/VirtNorFlashBlockIoDxe.c | 123 -----------------
OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c | 8 --
4 files changed, 289 deletions(-)
delete mode 100644 OvmfPkg/VirtNorFlashDxe/VirtNorFlashBlockIoDxe.c
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
index 59a562efdf..1094d48f7d 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
@@ -788,135 +788,6 @@ NorFlashWriteSingleBlock (
return EFI_SUCCESS;
}
-/*
- Although DiskIoDxe will automatically install the DiskIO protocol whenever
- we install the BlockIO protocol, its implementation is sub-optimal as it reads
- and writes entire blocks using the BlockIO protocol. In fact we can access
- NOR flash with a finer granularity than that, so we can improve performance
- by directly producing the DiskIO protocol.
-*/
-
-/**
- Read BufferSize bytes from Offset into Buffer.
-
- @param This Protocol instance pointer.
- @param MediaId Id of the media, changes every time the media is replaced.
- @param Offset The starting byte offset to read from
- @param BufferSize Size of Buffer
- @param Buffer Buffer containing read data
-
- @retval EFI_SUCCESS The data was read correctly from the device.
- @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
- @retval EFI_NO_MEDIA There is no media in the device.
- @retval EFI_MEDIA_CHANGED The MediaId does not match the current device.
- @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not
- valid for the device.
-
-**/
-EFI_STATUS
-EFIAPI
-NorFlashDiskIoReadDisk (
- IN EFI_DISK_IO_PROTOCOL *This,
- IN UINT32 MediaId,
- IN UINT64 DiskOffset,
- IN UINTN BufferSize,
- OUT VOID *Buffer
- )
-{
- NOR_FLASH_INSTANCE *Instance;
- UINT32 BlockSize;
- UINT32 BlockOffset;
- EFI_LBA Lba;
-
- Instance = INSTANCE_FROM_DISKIO_THIS (This);
-
- if (MediaId != Instance->Media.MediaId) {
- return EFI_MEDIA_CHANGED;
- }
-
- BlockSize = Instance->Media.BlockSize;
- Lba = (EFI_LBA)DivU64x32Remainder (DiskOffset, BlockSize, &BlockOffset);
-
- return NorFlashRead (Instance, Lba, BlockOffset, BufferSize, Buffer);
-}
-
-/**
- Writes a specified number of bytes to a device.
-
- @param This Indicates a pointer to the calling context.
- @param MediaId ID of the medium to be written.
- @param Offset The starting byte offset on the logical block I/O device to write.
- @param BufferSize The size in bytes of Buffer. The number of bytes to write to the device.
- @param Buffer A pointer to the buffer containing the data to be written.
-
- @retval EFI_SUCCESS The data was written correctly to the device.
- @retval EFI_WRITE_PROTECTED The device can not be written to.
- @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
- @retval EFI_NO_MEDIA There is no media in the device.
- @retval EFI_MEDIA_CHANGED The MediaId does not match the current device.
- @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not
- valid for the device.
-
-**/
-EFI_STATUS
-EFIAPI
-NorFlashDiskIoWriteDisk (
- IN EFI_DISK_IO_PROTOCOL *This,
- IN UINT32 MediaId,
- IN UINT64 DiskOffset,
- IN UINTN BufferSize,
- IN VOID *Buffer
- )
-{
- NOR_FLASH_INSTANCE *Instance;
- UINT32 BlockSize;
- UINT32 BlockOffset;
- EFI_LBA Lba;
- UINTN RemainingBytes;
- UINTN WriteSize;
- EFI_STATUS Status;
-
- Instance = INSTANCE_FROM_DISKIO_THIS (This);
-
- if (MediaId != Instance->Media.MediaId) {
- return EFI_MEDIA_CHANGED;
- }
-
- BlockSize = Instance->Media.BlockSize;
- Lba = (EFI_LBA)DivU64x32Remainder (DiskOffset, BlockSize, &BlockOffset);
-
- RemainingBytes = BufferSize;
-
- // Write either all the remaining bytes, or the number of bytes that bring
- // us up to a block boundary, whichever is less.
- // (DiskOffset | (BlockSize - 1)) + 1) rounds DiskOffset up to the next
- // block boundary (even if it is already on one).
- WriteSize = MIN (RemainingBytes, ((DiskOffset | (BlockSize - 1)) + 1) - DiskOffset);
-
- do {
- if (WriteSize == BlockSize) {
- // Write a full block
- Status = NorFlashWriteFullBlock (Instance, Lba, Buffer, BlockSize / sizeof (UINT32));
- } else {
- // Write a partial block
- Status = NorFlashWriteSingleBlock (Instance, Lba, BlockOffset, &WriteSize, Buffer);
- }
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- // Now continue writing either all the remaining bytes or single blocks.
- RemainingBytes -= WriteSize;
- Buffer = (UINT8 *)Buffer + WriteSize;
- Lba++;
- BlockOffset = 0;
- WriteSize = MIN (RemainingBytes, BlockSize);
- } while (RemainingBytes);
-
- return Status;
-}
-
EFI_STATUS
NorFlashReset (
IN NOR_FLASH_INSTANCE *Instance
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h
index e46522a198..7733ee02ee 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.h
@@ -15,7 +15,6 @@
#include <Guid/EventGroup.h>
#include <Protocol/BlockIo.h>
-#include <Protocol/DiskIo.h>
#include <Protocol/FirmwareVolumeBlock.h>
#include <Library/DebugLib.h>
@@ -111,7 +110,6 @@
#define NOR_FLASH_SIGNATURE SIGNATURE_32('n', 'o', 'r', '0')
#define INSTANCE_FROM_FVB_THIS(a) CR(a, NOR_FLASH_INSTANCE, FvbProtocol, NOR_FLASH_SIGNATURE)
#define INSTANCE_FROM_BLKIO_THIS(a) CR(a, NOR_FLASH_INSTANCE, BlockIoProtocol, NOR_FLASH_SIGNATURE)
-#define INSTANCE_FROM_DISKIO_THIS(a) CR(a, NOR_FLASH_INSTANCE, DiskIoProtocol, NOR_FLASH_SIGNATURE)
typedef struct _NOR_FLASH_INSTANCE NOR_FLASH_INSTANCE;
@@ -134,7 +132,6 @@ struct _NOR_FLASH_INSTANCE {
EFI_BLOCK_IO_PROTOCOL BlockIoProtocol;
EFI_BLOCK_IO_MEDIA Media;
- EFI_DISK_IO_PROTOCOL DiskIoProtocol;
EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;
VOID *ShadowBuffer;
@@ -203,32 +200,6 @@ NorFlashBlockIoFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This
);
-//
-// DiskIO Protocol function EFI_DISK_IO_PROTOCOL.ReadDisk
-//
-EFI_STATUS
-EFIAPI
-NorFlashDiskIoReadDisk (
- IN EFI_DISK_IO_PROTOCOL *This,
- IN UINT32 MediaId,
- IN UINT64 Offset,
- IN UINTN BufferSize,
- OUT VOID *Buffer
- );
-
-//
-// DiskIO Protocol function EFI_DISK_IO_PROTOCOL.WriteDisk
-//
-EFI_STATUS
-EFIAPI
-NorFlashDiskIoWriteDisk (
- IN EFI_DISK_IO_PROTOCOL *This,
- IN UINT32 MediaId,
- IN UINT64 Offset,
- IN UINTN BufferSize,
- IN VOID *Buffer
- );
-
//
// NorFlashFvbDxe.c
//
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashBlockIoDxe.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashBlockIoDxe.c
deleted file mode 100644
index ecf152e355..0000000000
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashBlockIoDxe.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/** @file NorFlashBlockIoDxe.c
-
- Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-
-#include "VirtNorFlash.h"
-
-//
-// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.Reset
-//
-EFI_STATUS
-EFIAPI
-NorFlashBlockIoReset (
- IN EFI_BLOCK_IO_PROTOCOL *This,
- IN BOOLEAN ExtendedVerification
- )
-{
- NOR_FLASH_INSTANCE *Instance;
-
- Instance = INSTANCE_FROM_BLKIO_THIS (This);
-
- DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReset(MediaId=0x%x)\n", This->Media->MediaId));
-
- return NorFlashReset (Instance);
-}
-
-//
-// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks
-//
-EFI_STATUS
-EFIAPI
-NorFlashBlockIoReadBlocks (
- IN EFI_BLOCK_IO_PROTOCOL *This,
- IN UINT32 MediaId,
- IN EFI_LBA Lba,
- IN UINTN BufferSizeInBytes,
- OUT VOID *Buffer
- )
-{
- NOR_FLASH_INSTANCE *Instance;
- EFI_STATUS Status;
- EFI_BLOCK_IO_MEDIA *Media;
-
- if (This == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- Instance = INSTANCE_FROM_BLKIO_THIS (This);
- Media = This->Media;
-
- DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReadBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes (%d kB), BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, BufferSizeInBytes, Buffer));
-
- if (!Media) {
- Status = EFI_INVALID_PARAMETER;
- } else if (!Media->MediaPresent) {
- Status = EFI_NO_MEDIA;
- } else if (Media->MediaId != MediaId) {
- Status = EFI_MEDIA_CHANGED;
- } else if ((Media->IoAlign > 2) && (((UINTN)Buffer & (Media->IoAlign - 1)) != 0)) {
- Status = EFI_INVALID_PARAMETER;
- } else {
- Status = NorFlashReadBlocks (Instance, Lba, BufferSizeInBytes, Buffer);
- }
-
- return Status;
-}
-
-//
-// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks
-//
-EFI_STATUS
-EFIAPI
-NorFlashBlockIoWriteBlocks (
- IN EFI_BLOCK_IO_PROTOCOL *This,
- IN UINT32 MediaId,
- IN EFI_LBA Lba,
- IN UINTN BufferSizeInBytes,
- IN VOID *Buffer
- )
-{
- NOR_FLASH_INSTANCE *Instance;
- EFI_STATUS Status;
-
- Instance = INSTANCE_FROM_BLKIO_THIS (This);
-
- DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoWriteBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes, BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, Buffer));
-
- if ( !This->Media->MediaPresent ) {
- Status = EFI_NO_MEDIA;
- } else if ( This->Media->MediaId != MediaId ) {
- Status = EFI_MEDIA_CHANGED;
- } else if ( This->Media->ReadOnly ) {
- Status = EFI_WRITE_PROTECTED;
- } else {
- Status = NorFlashWriteBlocks (Instance, Lba, BufferSizeInBytes, Buffer);
- }
-
- return Status;
-}
-
-//
-// BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks
-//
-EFI_STATUS
-EFIAPI
-NorFlashBlockIoFlushBlocks (
- IN EFI_BLOCK_IO_PROTOCOL *This
- )
-{
- // No Flush required for the NOR Flash driver
- // because cache operations are not permitted.
-
- DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoFlushBlocks: Function NOT IMPLEMENTED (not required).\n"));
-
- // Nothing to do so just return without error
- return EFI_SUCCESS;
-}
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
index 819425545e..4875b057d5 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
@@ -58,12 +58,6 @@ NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {
1, // LogicalBlocksPerPhysicalBlock
}, // Media;
- {
- EFI_DISK_IO_PROTOCOL_REVISION, // Revision
- NorFlashDiskIoReadDisk, // ReadDisk
- NorFlashDiskIoWriteDisk // WriteDisk
- },
-
{
FvbGetAttributes, // GetAttributes
FvbSetAttributes, // SetAttributes
@@ -159,8 +153,6 @@ NorFlashCreateInstance (
&Instance->DevicePath,
&gEfiBlockIoProtocolGuid,
&Instance->BlockIoProtocol,
- &gEfiDiskIoProtocolGuid,
- &Instance->DiskIoProtocol,
NULL
);
if (EFI_ERROR (Status)) {
--
2.41.0

View File

@ -0,0 +1,216 @@
From c4d2144caff4eddb7021752fce6c2dec6d5e1632 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 9 Jan 2024 12:29:02 +0100
Subject: [PATCH 10/18] OvmfPkg/VirtNorFlashDxe: sanity-check variables
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [12/20] 2ad3957478b82a4ca29249ceb9620f97c591a1fe
Extend the ValidateFvHeader function, additionally to the header checks
walk over the list of variables and sanity check them.
In case we find inconsistencies indicating variable store corruption
return EFI_NOT_FOUND so the variable store will be re-initialized.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-Id: <20240109112902.30002-4-kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
[lersek@redhat.com: fix StartId initialization/assignment coding style]
(cherry picked from commit 4a443f73fd67ca8caaf0a3e1a01f8231b330d2e0)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf | 1 +
OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c | 149 +++++++++++++++++++-
2 files changed, 145 insertions(+), 5 deletions(-)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
index 2a3d4a218e..f549400280 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
@@ -34,6 +34,7 @@
DxeServicesTableLib
HobLib
IoLib
+ SafeIntLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c
index c503272a2b..acc4a413ee 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c
@@ -12,6 +12,7 @@
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
+#include <Library/SafeIntLib.h>
#include <Library/UefiLib.h>
#include <Guid/NvVarStoreFormatted.h>
@@ -185,11 +186,12 @@ ValidateFvHeader (
IN NOR_FLASH_INSTANCE *Instance
)
{
- UINT16 Checksum;
- EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
- VARIABLE_STORE_HEADER *VariableStoreHeader;
- UINTN VariableStoreLength;
- UINTN FvLength;
+ UINT16 Checksum;
+ CONST EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ CONST VARIABLE_STORE_HEADER *VariableStoreHeader;
+ UINTN VarOffset;
+ UINTN VariableStoreLength;
+ UINTN FvLength;
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)Instance->RegionBaseAddress;
@@ -258,6 +260,143 @@ ValidateFvHeader (
return EFI_NOT_FOUND;
}
+ //
+ // check variables
+ //
+ DEBUG ((DEBUG_INFO, "%a: checking variables\n", __func__));
+ VarOffset = sizeof (*VariableStoreHeader);
+ for ( ; ;) {
+ UINTN VarHeaderEnd;
+ UINTN VarNameEnd;
+ UINTN VarEnd;
+ UINTN VarPadding;
+ CONST AUTHENTICATED_VARIABLE_HEADER *VarHeader;
+ CONST CHAR16 *VarName;
+ CONST CHAR8 *VarState;
+ RETURN_STATUS Status;
+
+ Status = SafeUintnAdd (VarOffset, sizeof (*VarHeader), &VarHeaderEnd);
+ if (RETURN_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: integer overflow\n", __func__));
+ return EFI_NOT_FOUND;
+ }
+
+ if (VarHeaderEnd >= VariableStoreHeader->Size) {
+ if (VarOffset <= VariableStoreHeader->Size - sizeof (UINT16)) {
+ CONST UINT16 *StartId;
+
+ StartId = (VOID *)((UINTN)VariableStoreHeader + VarOffset);
+ if (*StartId == 0x55aa) {
+ DEBUG ((DEBUG_ERROR, "%a: startid at invalid location\n", __func__));
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ DEBUG ((DEBUG_INFO, "%a: end of var list (no space left)\n", __func__));
+ break;
+ }
+
+ VarHeader = (VOID *)((UINTN)VariableStoreHeader + VarOffset);
+ if (VarHeader->StartId != 0x55aa) {
+ DEBUG ((DEBUG_INFO, "%a: end of var list (no startid)\n", __func__));
+ break;
+ }
+
+ VarName = NULL;
+ switch (VarHeader->State) {
+ // usage: State = VAR_HEADER_VALID_ONLY
+ case VAR_HEADER_VALID_ONLY:
+ VarState = "header-ok";
+ VarName = L"<unknown>";
+ break;
+
+ // usage: State = VAR_ADDED
+ case VAR_ADDED:
+ VarState = "ok";
+ break;
+
+ // usage: State &= VAR_IN_DELETED_TRANSITION
+ case VAR_ADDED &VAR_IN_DELETED_TRANSITION:
+ VarState = "del-in-transition";
+ break;
+
+ // usage: State &= VAR_DELETED
+ case VAR_ADDED &VAR_DELETED:
+ case VAR_ADDED &VAR_DELETED &VAR_IN_DELETED_TRANSITION:
+ VarState = "deleted";
+ break;
+
+ default:
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: invalid variable state: 0x%x\n",
+ __func__,
+ VarHeader->State
+ ));
+ return EFI_NOT_FOUND;
+ }
+
+ Status = SafeUintnAdd (VarHeaderEnd, VarHeader->NameSize, &VarNameEnd);
+ if (RETURN_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: integer overflow\n", __func__));
+ return EFI_NOT_FOUND;
+ }
+
+ Status = SafeUintnAdd (VarNameEnd, VarHeader->DataSize, &VarEnd);
+ if (RETURN_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: integer overflow\n", __func__));
+ return EFI_NOT_FOUND;
+ }
+
+ if (VarEnd > VariableStoreHeader->Size) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: invalid variable size: 0x%Lx + 0x%Lx + 0x%x + 0x%x > 0x%x\n",
+ __func__,
+ (UINT64)VarOffset,
+ (UINT64)(sizeof (*VarHeader)),
+ VarHeader->NameSize,
+ VarHeader->DataSize,
+ VariableStoreHeader->Size
+ ));
+ return EFI_NOT_FOUND;
+ }
+
+ if (((VarHeader->NameSize & 1) != 0) ||
+ (VarHeader->NameSize < 4))
+ {
+ DEBUG ((DEBUG_ERROR, "%a: invalid name size\n", __func__));
+ return EFI_NOT_FOUND;
+ }
+
+ if (VarName == NULL) {
+ VarName = (VOID *)((UINTN)VariableStoreHeader + VarHeaderEnd);
+ if (VarName[VarHeader->NameSize / 2 - 1] != L'\0') {
+ DEBUG ((DEBUG_ERROR, "%a: name is not null terminated\n", __func__));
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "%a: +0x%04Lx: name=0x%x data=0x%x guid=%g '%s' (%a)\n",
+ __func__,
+ (UINT64)VarOffset,
+ VarHeader->NameSize,
+ VarHeader->DataSize,
+ &VarHeader->VendorGuid,
+ VarName,
+ VarState
+ ));
+
+ VarPadding = (4 - (VarEnd & 3)) & 3;
+ Status = SafeUintnAdd (VarEnd, VarPadding, &VarOffset);
+ if (RETURN_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: integer overflow\n", __func__));
+ return EFI_NOT_FOUND;
+ }
+ }
+
return EFI_SUCCESS;
}
--
2.41.0

View File

@ -0,0 +1,49 @@
From 1444157aad1b98ce9c1193ef109011b084113890 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 9 Jan 2024 12:29:01 +0100
Subject: [PATCH 09/18] OvmfPkg/VirtNorFlashDxe: stop accepting
gEfiVariableGuid
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [11/20] c7b9cd1b716e1b8163b8094fbea8117241901815
Only accept gEfiAuthenticatedVariableGuid when checking the variable
store header in ValidateFvHeader().
The edk2 code base has been switched to use the authenticated varstore
format unconditionally (even in case secure boot is not used or
supported) a few years ago.
Suggested-by: László Érsek <lersek@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20240109112902.30002-3-kraxel@redhat.com>
(cherry picked from commit ae22b2f136bcbd27135a5f4dd76d3a68a172d00e)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c
index cc5eefaaf3..c503272a2b 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c
@@ -239,9 +239,7 @@ ValidateFvHeader (
VariableStoreHeader = (VARIABLE_STORE_HEADER *)((UINTN)FwVolHeader + FwVolHeader->HeaderLength);
// Check the Variable Store Guid
- if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) &&
- !CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid))
- {
+ if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid)) {
DEBUG ((
DEBUG_INFO,
"%a: Variable Store Guid non-compatible\n",
--
2.41.0

View File

@ -0,0 +1,150 @@
From e65da48afdabc9a5cba1c212b4323898b91ef2a4 Mon Sep 17 00:00:00 2001
From: Ard Biesheuvel <ardb@kernel.org>
Date: Mon, 24 Oct 2022 18:16:18 +0200
Subject: [PATCH 07/18] OvmfPkg/VirtNorFlashDxe: use EFI_MEMORY_WC and drop
AlignedCopyMem()
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [9/20] 0c01619eff8282d08e05fae8c37175b944449f59
NOR flash emulation under KVM involves switching between two modes,
where array mode is backed by a read-only memslot, and programming mode
is fully emulated, i.e., the memory region is not backed by anything,
and the faulting accesses are forwarded to the VMM by the hypervisor,
which translates them into NOR flash programming commands.
Normally, we are limited to the use of device attributes when mapping
such regions, given that the programming mode has MMIO semantics.
However, when running under KVM, the chosen memory attributes only take
effect when in array mode, since no memory mapping exists otherwise.
This means we can tune the memory mapping so it behaves a bit more like
a ROM, by switching to EFI_MEMORY_WC attributes. This means we no longer
need a special CopyMem() implementation that avoids unaligned accesses
at all cost.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
(cherry picked from commit 789a723285533f35652ebd6029976e2ddc955655)
---
OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c | 65 +----------------------
OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c | 4 +-
2 files changed, 4 insertions(+), 65 deletions(-)
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
index 0343131a54..1afd60ce66 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlash.c
@@ -401,67 +401,6 @@ NorFlashWriteBlocks (
return Status;
}
-#define BOTH_ALIGNED(a, b, align) ((((UINTN)(a) | (UINTN)(b)) & ((align) - 1)) == 0)
-
-/**
- Copy Length bytes from Source to Destination, using aligned accesses only.
- Note that this implementation uses memcpy() semantics rather then memmove()
- semantics, i.e., SourceBuffer and DestinationBuffer should not overlap.
-
- @param DestinationBuffer The target of the copy request.
- @param SourceBuffer The place to copy from.
- @param Length The number of bytes to copy.
-
- @return Destination
-
-**/
-STATIC
-VOID *
-AlignedCopyMem (
- OUT VOID *DestinationBuffer,
- IN CONST VOID *SourceBuffer,
- IN UINTN Length
- )
-{
- UINT8 *Destination8;
- CONST UINT8 *Source8;
- UINT32 *Destination32;
- CONST UINT32 *Source32;
- UINT64 *Destination64;
- CONST UINT64 *Source64;
-
- if (BOTH_ALIGNED (DestinationBuffer, SourceBuffer, 8) && (Length >= 8)) {
- Destination64 = DestinationBuffer;
- Source64 = SourceBuffer;
- while (Length >= 8) {
- *Destination64++ = *Source64++;
- Length -= 8;
- }
-
- Destination8 = (UINT8 *)Destination64;
- Source8 = (CONST UINT8 *)Source64;
- } else if (BOTH_ALIGNED (DestinationBuffer, SourceBuffer, 4) && (Length >= 4)) {
- Destination32 = DestinationBuffer;
- Source32 = SourceBuffer;
- while (Length >= 4) {
- *Destination32++ = *Source32++;
- Length -= 4;
- }
-
- Destination8 = (UINT8 *)Destination32;
- Source8 = (CONST UINT8 *)Source32;
- } else {
- Destination8 = DestinationBuffer;
- Source8 = SourceBuffer;
- }
-
- while (Length-- != 0) {
- *Destination8++ = *Source8++;
- }
-
- return DestinationBuffer;
-}
-
EFI_STATUS
NorFlashReadBlocks (
IN NOR_FLASH_INSTANCE *Instance,
@@ -516,7 +455,7 @@ NorFlashReadBlocks (
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
// Readout the data
- AlignedCopyMem (Buffer, (VOID *)StartAddress, BufferSizeInBytes);
+ CopyMem (Buffer, (VOID *)StartAddress, BufferSizeInBytes);
return EFI_SUCCESS;
}
@@ -558,7 +497,7 @@ NorFlashRead (
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);
// Readout the data
- AlignedCopyMem (Buffer, (VOID *)(StartAddress + Offset), BufferSizeInBytes);
+ CopyMem (Buffer, (VOID *)(StartAddress + Offset), BufferSizeInBytes);
return EFI_SUCCESS;
}
diff --git a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
index f9a41f6aab..ff3121af2a 100644
--- a/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
+++ b/OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.c
@@ -394,14 +394,14 @@ NorFlashFvbInitialize (
EfiGcdMemoryTypeMemoryMappedIo,
Instance->DeviceBaseAddress,
RuntimeMmioRegionSize,
- EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ EFI_MEMORY_WC | EFI_MEMORY_RUNTIME
);
ASSERT_EFI_ERROR (Status);
Status = gDS->SetMemorySpaceAttributes (
Instance->DeviceBaseAddress,
RuntimeMmioRegionSize,
- EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ EFI_MEMORY_WC | EFI_MEMORY_RUNTIME
);
ASSERT_EFI_ERROR (Status);
--
2.41.0

View File

@ -0,0 +1,80 @@
From 59fb955aa77b75345f7828bf9f83764adf4bed46 Mon Sep 17 00:00:00 2001
From: Ard Biesheuvel <ardb@kernel.org>
Date: Mon, 24 Oct 2022 18:35:10 +0200
Subject: [PATCH 18/18] OvmfPkg: clone NorFlashPlatformLib into
VirtNorFlashPlatformLib
RH-Author: Gerd Hoffmann <None>
RH-MergeRequest: 43: OvmfPkg/VirtNorFlashDxe backport
RH-Jira: RHEL-17587
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Commit: [20/20] 50ea104b99a997d7d08c1fdef617df1d930ffae6
Create a new library class in Ovmf that duplicates the existing
NorFlashPlatformLib, but which will be tied to the VirtNorFlashDxe
driver that will be introduced in a subsequent patch. This allows us to
retire the original from ArmPlatformPkg.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
(cherry picked from commit 16bf588b604a9f190accb71ada715b81756c94e2)
---
.../Include/Library/VirtNorFlashPlatformLib.h | 30 +++++++++++++++++++
OvmfPkg/OvmfPkg.dec | 4 +++
2 files changed, 34 insertions(+)
create mode 100644 OvmfPkg/Include/Library/VirtNorFlashPlatformLib.h
diff --git a/OvmfPkg/Include/Library/VirtNorFlashPlatformLib.h b/OvmfPkg/Include/Library/VirtNorFlashPlatformLib.h
new file mode 100644
index 0000000000..8f5b5e972d
--- /dev/null
+++ b/OvmfPkg/Include/Library/VirtNorFlashPlatformLib.h
@@ -0,0 +1,30 @@
+/** @file
+
+ Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ **/
+
+#ifndef __VIRT_NOR_FLASH_PLATFORM_LIB__
+#define __VIRT_NOR_FLASH_PLATFORM_LIB__
+
+typedef struct {
+ UINTN DeviceBaseAddress; // Start address of the Device Base Address (DBA)
+ UINTN RegionBaseAddress; // Start address of one single region
+ UINTN Size;
+ UINTN BlockSize;
+} VIRT_NOR_FLASH_DESCRIPTION;
+
+EFI_STATUS
+VirtNorFlashPlatformInitialization (
+ VOID
+ );
+
+EFI_STATUS
+VirtNorFlashPlatformGetDevices (
+ OUT VIRT_NOR_FLASH_DESCRIPTION **NorFlashDescriptions,
+ OUT UINT32 *Count
+ );
+
+#endif /* __VIRT_NOR_FLASH_PLATFORM_LIB__ */
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 340d83f794..e65ebd81c8 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -97,6 +97,10 @@
# transports.
VirtioMmioDeviceLib|Include/Library/VirtioMmioDeviceLib.h
+ ## @libraryclass Provides a Nor flash interface.
+ #
+ VirtNorFlashPlatformLib|Include/Library/VirtNorFlashPlatformLib.h
+
## @libraryclass Invoke Xen hypercalls
#
XenHypercallLib|Include/Library/XenHypercallLib.h
--
2.41.0

View File

@ -7,7 +7,7 @@ ExclusiveArch: x86_64 aarch64
Name: edk2
Version: %{GITDATE}git%{GITCOMMIT}
Release: 9%{?dist}
Release: 10%{?dist}
Summary: UEFI firmware for 64-bit virtual machines
Group: Applications/Emulators
License: BSD-2-Clause-Patent and OpenSSL and MIT
@ -64,6 +64,42 @@ Patch30: edk2-UefiCpuPkg-MpInitLib-fix-apic-mode-for-cpu-hotplug.patch
Patch31: edk2-OvmfPkg-VirtNorFlashDxe-stop-accepting-gEfiVariableG.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch32: edk2-OvmfPkg-VirtNorFlashDxe-sanity-check-variables.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch33: edk2-OvmfPkg-VirtNorFlashDxe-clone-ArmPlatformPkg-s-NOR-f.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch34: edk2-OvmfPkg-VirtNorFlashDxe-remove-CheckBlockLocked-feat.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch35: edk2-OvmfPkg-VirtNorFlashDxe-remove-disk-I-O-protocol-imp.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch36: edk2-OvmfPkg-VirtNorFlashDxe-drop-block-I-O-protocol-impl.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch37: edk2-OvmfPkg-VirtNorFlashDxe-avoid-array-mode-switch-afte.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch38: edk2-OvmfPkg-VirtNorFlashDxe-avoid-switching-between-mode.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch39: edk2-OvmfPkg-VirtNorFlashDxe-use-EFI_MEMORY_WC-and-drop-A.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch40: edk2-OvmfPkg-VirtNorFlashDxe-map-flash-memory-as-uncachea.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch41: edk2-OvmfPkg-VirtNorFlashDxe-stop-accepting-gEfiVariable2.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch42: edk2-OvmfPkg-VirtNorFlashDxe-sanity-check-variable2.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch43: edk2-OvmfPkg-VirtNorFlashDxe-add-casts-to-UINTN-and-UINT3.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch44: edk2-OvmfPkg-VirtNorFlashDxe-clarify-block-write-logic-fi.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch45: edk2-OvmfPkg-VirtNorFlashDxe-add-a-loop-for-NorFlashWrite.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch46: edk2-OvmfPkg-VirtNorFlashDxe-allow-larger-writes-without-.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch47: edk2-OvmfPkg-VirtNorFlashDxe-ValidateFvHeader-unwritten-s.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch48: edk2-OvmfPkg-VirtNorFlashDxe-move-DoErase-code-block-into.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch49: edk2-ArmVirtPkg-ArmVirtQemu-migrate-to-OVMF-s-VirtNorFlas.patch
# For RHEL-17587 - [rhel8] guest fails to boot due to ASSERT error
Patch50: edk2-OvmfPkg-clone-NorFlashPlatformLib-into-VirtNorFlashP.patch
# python3-devel and libuuid-devel are required for building tools.
@ -508,6 +544,28 @@ true
%endif
%changelog
* Sat Feb 03 2024 Jon Maloy <jmaloy@redhat.com> - 20220126gitbb1bba3d77-10
- edk2-OvmfPkg-VirtNorFlashDxe-clone-ArmPlatformPkg-s-NOR-f.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-remove-CheckBlockLocked-feat.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-remove-disk-I-O-protocol-imp.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-drop-block-I-O-protocol-impl.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-avoid-array-mode-switch-afte.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-avoid-switching-between-mode.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-use-EFI_MEMORY_WC-and-drop-A.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-map-flash-memory-as-uncachea.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-stop-accepting-gEfiVariable2.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-sanity-check-variable2.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-add-casts-to-UINTN-and-UINT3.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-clarify-block-write-logic-fi.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-add-a-loop-for-NorFlashWrite.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-allow-larger-writes-without-.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-ValidateFvHeader-unwritten-s.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-move-DoErase-code-block-into.patch [RHEL-17587]
- edk2-ArmVirtPkg-ArmVirtQemu-migrate-to-OVMF-s-VirtNorFlas.patch [RHEL-17587]
- edk2-OvmfPkg-clone-NorFlashPlatformLib-into-VirtNorFlashP.patch [RHEL-17587]
- Resolves: RHEL-17587
([rhel8] guest fails to boot due to ASSERT error)
* Wed Jan 24 2024 Jon Maloy <jmaloy@redhat.com> - 20220126gitbb1bba3d77-9
- edk2-OvmfPkg-VirtNorFlashDxe-stop-accepting-gEfiVariableG.patch [RHEL-17587]
- edk2-OvmfPkg-VirtNorFlashDxe-sanity-check-variables.patch [RHEL-17587]