From: "Chiu, Chasel" <chasel.chiu@intel.com>
To: devel@edk2.groups.io
Cc: Chasel Chiu <chasel.chiu@intel.com>,
Ashraf Ali S <ashraf.ali.s@intel.com>,
Isaac Oram <isaac.w.oram@intel.com>,
Rangasai V Chaganty <rangasai.v.chaganty@intel.com>,
Ray Ni <ray.ni@intel.com>,
Michael Kubacki <michael.kubacki@microsoft.com>
Subject: [edk2-platforms: PATCH v3] IntelSiliconPkg/SpiFvbServiceSmm: Rewrite VariableStore header.
Date: Tue, 7 Feb 2023 11:42:58 -0800 [thread overview]
Message-ID: <20230207194258.2598-1-chasel.chiu@intel.com> (raw)
When invalid VariableStore FV header detected, current SpiFvbService
will erase both FV and VariableStore headers from flash, however,
it will only rewrite FV header back and cause invalid VariableStore
header.
This patch adding the support for rewriting both FV header and
VariableStore header when VariableStore corruption happened.
Platform has to set PcdFlashVariableStoreType to inform SpiFvbService
which VariableStoreType should be rewritten.
Cc: Ashraf Ali S <ashraf.ali.s@intel.com>
Cc: Isaac Oram <isaac.w.oram@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Michael Kubacki <michael.kubacki@microsoft.com>
Signed-off-by: Chasel Chiu <chasel.chiu@intel.com>
---
Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceMm.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSmm.inf | 4 ++++
Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec | 8 ++++++++
3 files changed, 71 insertions(+), 5 deletions(-)
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceMm.c b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceMm.c
index 6b4bcdcfe3..6338442e1a 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceMm.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceMm.c
@@ -12,6 +12,7 @@
#include <Library/MmServicesTableLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Protocol/SmmFirmwareVolumeBlock.h>
+#include <Guid/VariableFormat.h>
/**
The function installs EFI_FIRMWARE_VOLUME_BLOCK protocol
@@ -114,6 +115,10 @@ FvbInitialize (
UINT32 BytesWritten;
UINTN BytesErased;
UINT64 NvStorageFvSize;
+ UINT32 ExpectedBytesWritten;
+ VARIABLE_STORE_HEADER *VariableStoreHeader;
+ UINT8 VariableStoreType;
+ UINT8 *NvStoreBuffer;
Status = GetVariableFlashNvStorageInfo (&BaseAddress, &NvStorageFvSize);
if (EFI_ERROR (Status)) {
@@ -186,8 +191,57 @@ FvbInitialize (
}
continue;
}
- BytesWritten = FvHeader->HeaderLength;
- Status = SpiFlashWrite ((UINTN)BaseAddress, &BytesWritten, (UINT8*)FvHeader);
+
+ BytesWritten = FvHeader->HeaderLength;
+ ExpectedBytesWritten = BytesWritten;
+ if (Idx != 0) {
+ Status = SpiFlashWrite ((UINTN)BaseAddress, &BytesWritten, (UINT8 *)FvHeader);
+ } else {
+ //
+ // This is Variable Store, rewrite both EFI_FIRMWARE_VOLUME_HEADER and VARIABLE_STORE_HEADER
+ //
+ NvStoreBuffer = NULL;
+ NvStoreBuffer = AllocateZeroPool (sizeof (VARIABLE_STORE_HEADER) + FvHeader->HeaderLength);
+ if (NvStoreBuffer != NULL) {
+ //
+ // Combine FV header and VariableStore header into the buffer.
+ //
+ CopyMem (NvStoreBuffer, FvHeader, FvHeader->HeaderLength);
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *)(NvStoreBuffer + FvHeader->HeaderLength);
+ VariableStoreType = PcdGet8 (PcdFlashVariableStoreType);
+ switch (VariableStoreType) {
+ case 0:
+ DEBUG ((DEBUG_ERROR, "Type: gEfiVariableGuid\n"));
+ CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid);
+ break;
+ case 1:
+ DEBUG ((DEBUG_ERROR, "Type: gEfiAuthenticatedVariableGuid\n"));
+ CopyGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid);
+ break;
+ default:
+ break;
+ }
+
+ //
+ // Initialize common VariableStore header fields
+ //
+ VariableStoreHeader->Size = PcdGet32 (PcdFlashNvStorageVariableSize) - FvHeader->HeaderLength;
+ VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED;
+ VariableStoreHeader->State = VARIABLE_STORE_HEALTHY;
+ VariableStoreHeader->Reserved = 0;
+ VariableStoreHeader->Reserved1 = 0;
+ //
+ // Write buffer to flash
+ //
+ BytesWritten = FvHeader->HeaderLength + sizeof (VARIABLE_STORE_HEADER);
+ ExpectedBytesWritten = BytesWritten;
+ Status = SpiFlashWrite ((UINTN)BaseAddress, &BytesWritten, NvStoreBuffer);
+ FreePool (NvStoreBuffer);
+ } else {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+ }
+
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "ERROR - SpiFlashWrite Error %r\n", Status));
if (FvHeader != NULL) {
@@ -195,9 +249,9 @@ FvbInitialize (
}
continue;
}
- if (BytesWritten != FvHeader->HeaderLength) {
- DEBUG ((DEBUG_WARN, "ERROR - BytesWritten != HeaderLength\n"));
- DEBUG ((DEBUG_INFO, " BytesWritten = 0x%X\n HeaderLength = 0x%X\n", BytesWritten, FvHeader->HeaderLength));
+ if (BytesWritten != ExpectedBytesWritten) {
+ DEBUG ((DEBUG_WARN, "ERROR - BytesWritten != ExpectedBytesWritten\n"));
+ DEBUG ((DEBUG_INFO, " BytesWritten = 0x%X\n ExpectedBytesWritten = 0x%X\n", BytesWritten, ExpectedBytesWritten));
if (FvHeader != NULL) {
FreePool (FvHeader);
}
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSmm.inf b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSmm.inf
index 0cfa3f909b..0485b73679 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSmm.inf
@@ -45,6 +45,8 @@
[Pcd]
gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase ## CONSUMES
gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## SOMETIMES_CONSUMES
+ gIntelSiliconPkgTokenSpaceGuid.PcdFlashVariableStoreType ## SOMETIMES_CONSUMES
[Sources]
FvbInfo.c
@@ -61,6 +63,8 @@
[Guids]
gEfiFirmwareFileSystem2Guid ## CONSUMES
gEfiSystemNvDataFvGuid ## CONSUMES
+ gEfiVariableGuid ## SOMETIMES_CONSUMES
+ gEfiAuthenticatedVariableGuid ## SOMETIMES_CONSUMES
[Depex]
TRUE
diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
index 485cb3e80a..63dae756ad 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -186,3 +186,11 @@
# @Prompt VTd abort DMA mode support.
gIntelSiliconPkgTokenSpaceGuid.PcdVTdSupportAbortDmaMode|FALSE|BOOLEAN|0x0000000C
+ ## Define Flash Variable Store type.<BR><BR>
+ # When Flash Variable Store corruption happened, the SpiFvbService will recreate Variable Store
+ # with valid header information provided by this PCD value.<BR>
+ # 0: Variable Store is gEfiVariableGuid type.<BR>
+ # 1: Variable Store is gEfiAuthenticatedVariableGuid type.<BR>
+ # Other value: reserved for future use.<BR>
+ # @Prompt Flash Variable Store type.
+ gIntelSiliconPkgTokenSpaceGuid.PcdFlashVariableStoreType|0x00|UINT8|0x0000000E
--
2.35.0.windows.1
next reply other threads:[~2023-02-07 19:43 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-07 19:42 Chiu, Chasel [this message]
2023-02-07 20:22 ` [edk2-devel] [edk2-platforms: PATCH v3] IntelSiliconPkg/SpiFvbServiceSmm: Rewrite VariableStore header Michael Kubacki
2023-02-08 22:24 ` Chiu, Chasel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230207194258.2598-1-chasel.chiu@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox