public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "duntan" <dun.tan@intel.com>
To: devel@edk2.groups.io
Cc: Ray Ni <ray.ni@intel.com>, Liming Gao <gaoliming@byosoft.com.cn>,
	Jiaxin Wu <jiaxin.wu@intel.com>
Subject: [edk2-devel] [PATCH 5/9] MdeModulePkg:Create gEdkiiVariableRuntimeCacheInfoHobGuid
Date: Fri, 17 May 2024 17:49:13 +0800	[thread overview]
Message-ID: <20240517094917.513-6-dun.tan@intel.com> (raw)
In-Reply-To: <20240517094917.513-1-dun.tan@intel.com>

Install the callback of gEfiPeiMemoryDiscoveredPpiGuid
to create gEdkiiVariableRuntimeCacheInfoHobGuid in
VariablePei module. When PcdEnableVariableRuntimeCache
is TRUE, the callback will be installed to allocate
the needed buffer for different type variable runtime
cache, unblock the buffer and build this HOB. Then the
runtime cache buffer address and size will be saved in
the HOB content.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
---
 MdeModulePkg/Universal/Variable/Pei/Variable.c      | 298 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 MdeModulePkg/Universal/Variable/Pei/Variable.h      |   3 +++
 MdeModulePkg/Universal/Variable/Pei/VariablePei.inf |   8 +++++++-
 3 files changed, 307 insertions(+), 2 deletions(-)

diff --git a/MdeModulePkg/Universal/Variable/Pei/Variable.c b/MdeModulePkg/Universal/Variable/Pei/Variable.c
index 26a4c73b45..15419eb437 100644
--- a/MdeModulePkg/Universal/Variable/Pei/Variable.c
+++ b/MdeModulePkg/Universal/Variable/Pei/Variable.c
@@ -2,7 +2,7 @@
   Implement ReadOnly Variable Services required by PEIM and install
   PEI ReadOnly Varaiable2 PPI. These services operates the non volatile storage space.
 
-Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.<BR>
 Copyright (c) Microsoft Corporation.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -24,6 +24,31 @@ EFI_PEI_PPI_DESCRIPTOR  mPpiListVariable = {
   &mVariablePpi
 };
 
+/**
+  Build gEdkiiVariableRuntimeCacheInfoHobGuid.
+
+  @param[in] PeiServices          General purpose services available to every PEIM.
+  @param[in] NotifyDescriptor     The notification structure this PEIM registered on install.
+  @param[in] Ppi                  The memory discovered PPI.  Not used.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval others                  Failed to build VariableRuntimeCacheInfo Hob.
+
+**/
+EFI_STATUS
+EFIAPI
+BuildVariableRuntimeCacheInfoHob (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  );
+
+EFI_PEI_NOTIFY_DESCRIPTOR  mPostMemNotifyList = {
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiMemoryDiscoveredPpiGuid,
+  BuildVariableRuntimeCacheInfoHob
+};
+
 /**
   Provide the functionality of the variable services.
 
@@ -41,6 +66,10 @@ PeimInitializeVariableServices (
   IN CONST EFI_PEI_SERVICES     **PeiServices
   )
 {
+  if (FeaturePcdGet (PcdEnableVariableRuntimeCache)) {
+    PeiServicesNotifyPpi (&mPostMemNotifyList);
+  }
+
   return PeiServicesInstallPpi (&mPpiListVariable);
 }
 
@@ -1250,3 +1279,270 @@ PeiGetNextVariableName (
     }
   }
 }
+
+/**
+  Calculate the auth variable storage size converted from normal variable storage.
+
+  @param[in]  StoreInfo         Pointer to the store info
+  @param[in]  NormalHobVarStorage  Pointer to the normal variable storage header
+
+  @retval the auth variable storage size
+**/
+UINTN
+CalculateAuthVarStorageSize (
+  IN  VARIABLE_STORE_INFO    *StoreInfo,
+  IN  VARIABLE_STORE_HEADER  *NormalHobVarStorage
+  )
+{
+  VARIABLE_HEADER  *StartPtr;
+  VARIABLE_HEADER  *EndPtr;
+  UINTN            AuthVarStroageSize;
+
+  AuthVarStroageSize = sizeof (VARIABLE_STORE_HEADER);
+
+  //
+  // Calculate Auth Variable Storage Size
+  //
+  StartPtr = GetStartPointer (NormalHobVarStorage);
+  EndPtr   = GetEndPointer (NormalHobVarStorage);
+  while (StartPtr < EndPtr) {
+    if (StartPtr->State == VAR_ADDED) {
+      AuthVarStroageSize  = HEADER_ALIGN (AuthVarStroageSize);
+      AuthVarStroageSize += sizeof (AUTHENTICATED_VARIABLE_HEADER);
+      AuthVarStroageSize += StartPtr->NameSize + GET_PAD_SIZE (StartPtr->NameSize);
+      AuthVarStroageSize += StartPtr->DataSize + GET_PAD_SIZE (StartPtr->DataSize);
+    }
+
+    StartPtr = GetNextVariablePtr (StoreInfo, StartPtr, StartPtr);
+  }
+
+  return AuthVarStroageSize;
+}
+
+/**
+  Calculate Hob variable cache size.
+
+  @param[in]  NvAuthFlag   If the NV variable store is Auth.
+
+  @retval Maximum of Nv variable cache size.
+
+**/
+UINTN
+CalculateHobVariableCacheSize (
+  IN BOOLEAN  NvAuthFlag
+  )
+{
+  VARIABLE_STORE_INFO    StoreInfo;
+  VARIABLE_STORE_HEADER  *VariableStoreHeader;
+
+  VariableStoreHeader = NULL;
+  GetHobVariableStore (&StoreInfo, &VariableStoreHeader);
+
+  if (VariableStoreHeader == NULL) {
+    return 0;
+  }
+
+  if (NvAuthFlag == StoreInfo.AuthFlag) {
+    return VariableStoreHeader->Size;
+  } else {
+    //
+    // Normal NV variable store + Auth HOB variable store is not supported
+    //
+    ASSERT (NvAuthFlag && (!StoreInfo.AuthFlag));
+
+    //
+    // Need to calculate auth variable storage size converted from normal variable storage
+    //
+    return CalculateAuthVarStorageSize (&StoreInfo, VariableStoreHeader);
+  }
+}
+
+/**
+  Calculate Nv variable cache size.
+
+  @param[out]  NvAuthFlag   If the NV variable store is Auth.
+
+  @retval Maximum of Nv variable cache size.
+
+**/
+UINTN
+CalculateNvVariableCacheSize (
+  OUT BOOLEAN  *NvAuthFlag
+  )
+{
+  EFI_STATUS                            Status;
+  EFI_HOB_GUID_TYPE                     *GuidHob;
+  EFI_FIRMWARE_VOLUME_HEADER            *FvHeader;
+  VARIABLE_STORE_HEADER                 *VariableStoreHeader;
+  EFI_PHYSICAL_ADDRESS                  NvStorageBase;
+  UINT32                                NvStorageSize;
+  UINT64                                NvStorageSize64;
+  FAULT_TOLERANT_WRITE_LAST_WRITE_DATA  *FtwLastWriteData;
+
+  if (PcdGetBool (PcdEmuVariableNvModeEnable)) {
+    return PcdGet32 (PcdVariableStoreSize);
+  }
+
+  Status = GetVariableFlashNvStorageInfo (&NvStorageBase, &NvStorageSize64);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = SafeUint64ToUint32 (NvStorageSize64, &NvStorageSize);
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (NvStorageBase != 0);
+  FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)NvStorageBase;
+
+  //
+  // Check the FTW last write data hob.
+  //
+  GuidHob = GetFirstGuidHob (&gEdkiiFaultTolerantWriteGuid);
+  if (GuidHob != NULL) {
+    FtwLastWriteData = (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *)GET_GUID_HOB_DATA (GuidHob);
+    if (FtwLastWriteData->TargetAddress == NvStorageBase) {
+      //
+      // Let FvHeader point to spare block.
+      //
+      FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FtwLastWriteData->SpareAddress;
+    }
+  }
+
+  VariableStoreHeader = (VARIABLE_STORE_HEADER *)((UINT8 *)FvHeader + FvHeader->HeaderLength);
+  *NvAuthFlag         = (BOOLEAN)(CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid));
+
+  return NvStorageSize - FvHeader->HeaderLength;
+}
+
+/**
+  Build gEdkiiVariableRuntimeCacheInfoHobGuid.
+
+  @param[in] PeiServices          General purpose services available to every PEIM.
+  @param[in] NotifyDescriptor     The notification structure this PEIM registered on install.
+  @param[in] Ppi                  The memory discovered PPI.  Not used.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval others                  Failed to build VariableRuntimeCacheInfo Hob.
+
+**/
+EFI_STATUS
+EFIAPI
+BuildVariableRuntimeCacheInfoHob (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  )
+{
+  VARIABLE_RUNTIME_CACHE_INFO  *VariableRuntimeCacheHob;
+  EFI_STATUS                   Status;
+  VOID                         *Buffer;
+  UINTN                        BufferSize;
+  BOOLEAN                      NvAuthFlag;
+  UINTN                        Pages;
+
+  VariableRuntimeCacheHob = BuildGuidHob (&gEdkiiVariableRuntimeCacheInfoHobGuid, sizeof (VARIABLE_RUNTIME_CACHE_INFO));
+  ASSERT (VariableRuntimeCacheHob != NULL);
+  ZeroMem (VariableRuntimeCacheHob, sizeof (VARIABLE_RUNTIME_CACHE_INFO));
+
+  //
+  // AllocateRuntimePages for CACHE_INFO_FLAG and unblock it.
+  //
+  Pages  = EFI_SIZE_TO_PAGES (sizeof (CACHE_INFO_FLAG));
+  Buffer = AllocateRuntimePages (Pages);
+  ASSERT (Buffer != NULL);
+  Status = MmUnblockMemoryRequest (
+             (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer,
+             Pages
+             );
+  if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  VariableRuntimeCacheHob->CacheInfoFlag = (CACHE_INFO_FLAG *)(UINTN)Buffer;
+  DEBUG ((
+    DEBUG_INFO,
+    "PeiVariable: CACHE_INFO_FLAG Buffer is: 0x%x, number of pages is: 0x%x\n",
+    (UINTN)(VariableRuntimeCacheHob->CacheInfoFlag),
+    Pages
+    ));
+
+  //
+  // AllocateRuntimePages for VolatileCache and unblock it.
+  //
+  BufferSize = PcdGet32 (PcdVariableStoreSize);
+  if (BufferSize > 0) {
+    Pages  = EFI_SIZE_TO_PAGES (BufferSize);
+    Buffer = AllocateRuntimePages (Pages);
+    ASSERT (Buffer != NULL);
+    Status = MmUnblockMemoryRequest (
+               (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer,
+               Pages
+               );
+    if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    VariableRuntimeCacheHob->RuntimeVolatileCacheBuffer = (UINTN)Buffer;
+    VariableRuntimeCacheHob->RuntimeVolatileCachePages  = Pages;
+  }
+
+  DEBUG ((
+    DEBUG_INFO,
+    "PeiVariable: Volatile cache Buffer is: 0x%x, number of pages is: 0x%x\n",
+    VariableRuntimeCacheHob->RuntimeVolatileCacheBuffer,
+    VariableRuntimeCacheHob->RuntimeVolatileCachePages
+    ));
+
+  //
+  // AllocateRuntimePages for NVCache and unblock it.
+  //
+  BufferSize = CalculateNvVariableCacheSize (&NvAuthFlag);
+  if (BufferSize > 0) {
+    Pages  = EFI_SIZE_TO_PAGES (BufferSize);
+    Buffer = AllocateRuntimePages (Pages);
+    ASSERT (Buffer != NULL);
+    Status = MmUnblockMemoryRequest (
+               (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer,
+               Pages
+               );
+    if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    VariableRuntimeCacheHob->RuntimeNvCacheBuffer = (UINTN)Buffer;
+    VariableRuntimeCacheHob->RuntimeNvCachePages  = Pages;
+  }
+
+  DEBUG ((
+    DEBUG_INFO,
+    "PeiVariable: NV cache Buffer is: 0x%x, number of pages is: 0x%x\n",
+    VariableRuntimeCacheHob->RuntimeNvCacheBuffer,
+    VariableRuntimeCacheHob->RuntimeNvCachePages
+    ));
+
+  //
+  // AllocateRuntimePages for HobCache and unblock it.
+  //
+  BufferSize = CalculateHobVariableCacheSize (NvAuthFlag);
+  if (BufferSize > 0) {
+    Pages  = EFI_SIZE_TO_PAGES (BufferSize);
+    Buffer = AllocateRuntimePages (Pages);
+    ASSERT (Buffer != NULL);
+    Status = MmUnblockMemoryRequest (
+               (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer,
+               Pages
+               );
+    if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    VariableRuntimeCacheHob->RuntimeHobCacheBuffer = (UINTN)Buffer;
+    VariableRuntimeCacheHob->RuntimeHobCachePages  = Pages;
+  }
+
+  DEBUG ((
+    DEBUG_INFO,
+    "PeiVariable: HOB cache Buffer is: 0x%x, number of pages is: 0x%x\n",
+    VariableRuntimeCacheHob->RuntimeHobCacheBuffer,
+    VariableRuntimeCacheHob->RuntimeHobCachePages
+    ));
+
+  return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Universal/Variable/Pei/Variable.h b/MdeModulePkg/Universal/Variable/Pei/Variable.h
index 51effbf799..aa0d79f166 100644
--- a/MdeModulePkg/Universal/Variable/Pei/Variable.h
+++ b/MdeModulePkg/Universal/Variable/Pei/Variable.h
@@ -22,11 +22,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/PeiServicesLib.h>
 #include <Library/SafeIntLib.h>
 #include <Library/VariableFlashInfoLib.h>
+#include <Library/MmUnblockMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
 
 #include <Guid/VariableFormat.h>
 #include <Guid/VariableIndexTable.h>
 #include <Guid/SystemNvDataGuid.h>
 #include <Guid/FaultTolerantWrite.h>
+#include <Guid/VariableRuntimeCacheInfo.h>
 
 typedef enum {
   VariableStoreTypeHob,
diff --git a/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf b/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
index 7264a24bdf..f2dc7c042c 100644
--- a/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+++ b/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
@@ -3,7 +3,7 @@
 #
 #  This module implements ReadOnly Variable Services required by PEIM and installs PEI ReadOnly Varaiable2 PPI.
 #
-#  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.<BR>
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 ##
@@ -41,6 +41,8 @@
   PeiServicesLib
   SafeIntLib
   VariableFlashInfoLib
+  MmUnblockMemoryLib
+  MemoryAllocationLib
 
 [Guids]
   ## CONSUMES             ## GUID # Variable store header
@@ -56,12 +58,16 @@
   ## SOMETIMES_CONSUMES   ## HOB
   ## CONSUMES             ## GUID # Dependence
   gEdkiiFaultTolerantWriteGuid
+  gEdkiiVariableRuntimeCacheInfoHobGuid
 
 [Ppis]
   gEfiPeiReadOnlyVariable2PpiGuid   ## PRODUCES
+  gEfiPeiMemoryDiscoveredPpiGuid    ## CONSUMES
 
 [Pcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable         ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize               ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache      ## CONSUMES
 
 [Depex]
   gEdkiiFaultTolerantWriteGuid
-- 
2.31.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119022): https://edk2.groups.io/g/devel/message/119022
Mute This Topic: https://groups.io/mt/106150802/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  parent reply	other threads:[~2024-05-17  9:49 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-17  9:49 [edk2-devel] [PATCH 0/9] Allocate and unblock variable runtime cache buffer in PEI duntan
2024-05-17  9:49 ` [edk2-devel] [PATCH 1/9] MdeModulePkg:Add new gEdkiiVariableRuntimeCacheInfoHobGuid duntan
2024-05-17 11:49   ` Ni, Ray
2024-05-17  9:49 ` [edk2-devel] [PATCH 2/9] ArmVirtPkg: Add MmUnblockMemoryLib in DSC duntan
2024-05-17 11:50   ` Ni, Ray
2024-05-17  9:49 ` [edk2-devel] [PATCH 3/9] EmulatorPkg: " duntan
2024-05-17 11:54   ` Ni, Ray
2024-05-17  9:49 ` [edk2-devel] [PATCH 4/9] OvmfPkg: " duntan
2024-05-17 11:55   ` Ni, Ray
2024-05-17  9:49 ` duntan [this message]
2024-05-17 12:02   ` [edk2-devel] [PATCH 5/9] MdeModulePkg:Create gEdkiiVariableRuntimeCacheInfoHobGuid Ni, Ray
2024-05-17  9:49 ` [edk2-devel] [PATCH 6/9] MdeModulePkg:Remove unnecessary global variable duntan
2024-05-17 12:07   ` Ni, Ray
2024-05-17  9:49 ` [edk2-devel] [PATCH 7/9] MdeModulePkg:Consume gEdkiiVariableRuntimeCacheInfoHobGuid duntan
2024-05-17 12:09   ` Ni, Ray
2024-05-17 17:09     ` Kun Qin via groups.io
2024-05-20  7:07       ` Ni, Ray
2024-05-22  1:30         ` Kenneth Lautner
2024-05-17 12:17   ` Ni, Ray
2024-05-17  9:49 ` [edk2-devel] [PATCH 8/9] MdeModulePkg: Refine InitVariableCache() duntan
2024-05-17  9:49 ` [edk2-devel] [PATCH 9/9] MdeModulePkg:Add global variable mVariableRtCacheInfo duntan
2024-05-17 12:30   ` Ni, Ray
2024-05-20  1:01 ` [edk2-devel] [PATCH 0/9] Allocate and unblock variable runtime cache buffer in PEI Nhi Pham via groups.io
2024-05-20  6:54   ` Ni, Ray
2024-05-20  1:40 ` 回复: " gaoliming via groups.io
2024-05-20  7:12   ` duntan
2024-05-20 18:16 ` Sean
2024-05-21  9:25   ` duntan

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=20240517094917.513-6-dun.tan@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