diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
index 711f364be2..61745bb903 100644
--- a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
+ Copyright (c) 2020 - 2024, Ampere Computing LLC. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -13,8 +13,79 @@
#include
#include
#include
+#include
+#include
+#include
#include
#include
+#include
+
+/**
+ Check if the IPMI clear cmos flag is set or not.
+
+ @retval TRUE The clear cmos is set.
+ @retval FALSE The clear cmos is not set.
+
+**/
+STATIC
+BOOLEAN
+IsIpmiClearCmosSet (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ IPMI_GET_BOOT_OPTIONS_REQUEST BootOptionsRequest;
+ IPMI_GET_BOOT_OPTIONS_RESPONSE *BootOptionsResponse;
+ IPMI_BOOT_OPTIONS_RESPONSE_PARAMETER_5 *BootOptionsParameterData;
+ IPMI_SET_BOOT_OPTIONS_REQUEST *SetBootOptionsRequest;
+ IPMI_SET_BOOT_OPTIONS_RESPONSE SetBootOptionsResponse;
+ BOOLEAN IsClearCmosSet;
+
+ ZeroMem (&BootOptionsRequest, sizeof (IPMI_GET_BOOT_OPTIONS_REQUEST));
+ ZeroMem (&SetBootOptionsResponse, sizeof (IPMI_SET_BOOT_OPTIONS_RESPONSE));
+
+ IsClearCmosSet = FALSE;
+
+ BootOptionsResponse = AllocateZeroPool (sizeof (BootOptionsRequest) + sizeof (BootOptionsParameterData));
+ if (BootOptionsResponse == NULL) {
+ return FALSE;
+ }
+
+ BootOptionsRequest.ParameterSelector.Bits.ParameterSelector = IPMI_BOOT_OPTIONS_PARAMETER_BOOT_FLAGS;
+
+ Status = IpmiGetSystemBootOptions (&BootOptionsRequest, BootOptionsResponse);
+ if (EFI_ERROR (Status)) {
+ FreePool (BootOptionsResponse);
+ return FALSE;
+ }
+
+ BootOptionsParameterData = (IPMI_BOOT_OPTIONS_RESPONSE_PARAMETER_5 *)BootOptionsResponse->ParameterData;
+ if (BootOptionsParameterData->Data2.Bits.CmosClear != 0) {
+ IsClearCmosSet = TRUE;
+ }
+
+ SetBootOptionsRequest = AllocateZeroPool (sizeof (SetBootOptionsRequest) + sizeof (BootOptionsParameterData));
+ if (EFI_ERROR (Status)) {
+ FreePool (BootOptionsResponse);
+ return FALSE;
+ }
+
+ SetBootOptionsRequest->ParameterValid.Bits.ParameterSelector = IPMI_BOOT_OPTIONS_PARAMETER_BOOT_FLAGS;
+ SetBootOptionsRequest->ParameterValid.Bits.MarkParameterInvalid = 0x0;
+
+ BootOptionsParameterData->Data2.Bits.CmosClear = 0;
+ CopyMem (&SetBootOptionsRequest->ParameterData, BootOptionsParameterData, sizeof (IPMI_BOOT_OPTIONS_RESPONSE_PARAMETER_5));
+
+ Status = IpmiSetSystemBootOptions (SetBootOptionsRequest, &SetBootOptionsResponse);
+ if (EFI_ERROR (Status)) {
+ IsClearCmosSet = FALSE;
+ }
+
+ FreePool (BootOptionsResponse);
+ FreePool (SetBootOptionsRequest);
+
+ return IsClearCmosSet;
+}
/**
Entry point function for the PEIM
@@ -39,6 +110,7 @@ FlashPeiEntryPoint (
UINT32 FWNvRamSize;
UINTN NvRamAddress;
UINT32 NvRamSize;
+ BOOLEAN ClearUserConfig;
CopyMem ((VOID *)BuildUuid, PcdGetPtr (PcdPlatformConfigUuid), sizeof (BuildUuid));
@@ -80,9 +152,14 @@ FlashPeiEntryPoint (
return Status;
}
+ ClearUserConfig = IsIpmiClearCmosSet ();
+
if (CompareMem ((VOID *)StoredUuid, (VOID *)BuildUuid, sizeof (BuildUuid)) != 0) {
DEBUG ((DEBUG_INFO, "BUILD UUID Changed, Update Storage with NVRAM FV\n"));
+ ClearUserConfig = TRUE;
+ }
+ if (ClearUserConfig) {
Status = FlashEraseCommand (FWNvRamStartOffset, NvRamSize * 2 + sizeof (BuildUuid));
if (EFI_ERROR (Status)) {
return Status;
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
index 2b329c5d09..1179266726 100644
--- a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
@@ -1,6 +1,6 @@
## @file
#
-# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
+# Copyright (c) 2020 - 2024, Ampere Computing LLC. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -29,9 +29,13 @@
BaseMemoryLib
DebugLib
FlashLib
+ IpmiCommandLib
+ MemoryAllocationLib
MmCommunicationLib
+ NVParamLib
PcdLib
PeimEntryPoint
+ ResetSystemLib
[FixedPcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize