* 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:
parent
ad8cc2ba61
commit
d6671b1ccc
149
edk2-ArmVirtPkg-ArmVirtQemu-migrate-to-OVMF-s-VirtNorFlas.patch
Normal file
149
edk2-ArmVirtPkg-ArmVirtQemu-migrate-to-OVMF-s-VirtNorFlas.patch
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
303
edk2-OvmfPkg-VirtNorFlashDxe-avoid-switching-between-mode.patch
Normal file
303
edk2-OvmfPkg-VirtNorFlashDxe-avoid-switching-between-mode.patch
Normal 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
|
||||
|
110
edk2-OvmfPkg-VirtNorFlashDxe-clarify-block-write-logic-fi.patch
Normal file
110
edk2-OvmfPkg-VirtNorFlashDxe-clarify-block-write-logic-fi.patch
Normal 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
|
||||
|
2973
edk2-OvmfPkg-VirtNorFlashDxe-clone-ArmPlatformPkg-s-NOR-f.patch
Normal file
2973
edk2-OvmfPkg-VirtNorFlashDxe-clone-ArmPlatformPkg-s-NOR-f.patch
Normal file
File diff suppressed because it is too large
Load Diff
504
edk2-OvmfPkg-VirtNorFlashDxe-drop-block-I-O-protocol-impl.patch
Normal file
504
edk2-OvmfPkg-VirtNorFlashDxe-drop-block-I-O-protocol-impl.patch
Normal 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
|
||||
|
@ -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
|
||||
|
131
edk2-OvmfPkg-VirtNorFlashDxe-move-DoErase-code-block-into.patch
Normal file
131
edk2-OvmfPkg-VirtNorFlashDxe-move-DoErase-code-block-into.patch
Normal 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
|
||||
|
@ -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
|
||||
|
386
edk2-OvmfPkg-VirtNorFlashDxe-remove-disk-I-O-protocol-imp.patch
Normal file
386
edk2-OvmfPkg-VirtNorFlashDxe-remove-disk-I-O-protocol-imp.patch
Normal 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
|
||||
|
216
edk2-OvmfPkg-VirtNorFlashDxe-sanity-check-variable2.patch
Normal file
216
edk2-OvmfPkg-VirtNorFlashDxe-sanity-check-variable2.patch
Normal 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
|
||||
|
@ -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
|
||||
|
150
edk2-OvmfPkg-VirtNorFlashDxe-use-EFI_MEMORY_WC-and-drop-A.patch
Normal file
150
edk2-OvmfPkg-VirtNorFlashDxe-use-EFI_MEMORY_WC-and-drop-A.patch
Normal 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
|
||||
|
@ -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
|
||||
|
60
edk2.spec
60
edk2.spec
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user