[PATCH v3 23/28] AmpereAltraPkg: Add configuration screen for memory


Nhi Pham
 

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

Provide memory screen with below info:
* Memory total capacity
* Memory RAS and Performance Configuration
* Per DIMM Information

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
Platform/Ampere/JadePkg/Jade.dsc | 1 +
Platform/Ampere/JadePkg/Jade.fdf | 1 +
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf | 59 +
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h | 170 +++
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenNVDataStruct.h | 47 +
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenVfr.vfr | 62 +
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c | 394 ++++++
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c | 1325 ++++++++++++++++++++
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni | 9 +
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni | 9 +
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni | 64 +
11 files changed, 2141 insertions(+)

diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index f723be6997e6..5fc83745cdbc 100644
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -197,3 +197,4 @@ [Components.common]
# HII
#
Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
+ Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index c54b46f95ad5..6fe023025034 100644
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -355,5 +355,6 @@ [FV.FvMain]
# HII
#
INF Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
+ INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf

!include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
new file mode 100644
index 000000000000..fbb2ac9dad21
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
@@ -0,0 +1,59 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = MemInfoDxe
+ MODULE_UNI_FILE = MemInfoDxe.uni
+ FILE_GUID = D9EFCEFE-189B-4599-BB07-04F0A8DF5C2F
+ MODULE_TYPE = DXE_DRIVER
+ ENTRY_POINT = MemInfoScreenInitialize
+
+[Sources]
+ MemInfoNvramLib.c
+ MemInfoScreen.c
+ MemInfoScreen.h
+ MemInfoScreenStrings.uni
+ MemInfoScreenNVDataStruct.h
+ MemInfoScreenVfr.vfr
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+ Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+ AmpereCpuLib
+ BaseLib
+ DevicePathLib
+ HiiLib
+ HobLib
+ MemoryAllocationLib
+ NVParamLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Guids]
+ gEfiIfrTianoGuid ## PRODUCES ## UNDEFINED
+ gPlatformManagerFormsetGuid
+ gPlatformHobGuid
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## CONSUMES
+ gEfiHiiConfigRoutingProtocolGuid ## CONSUMES
+ gEfiHiiConfigAccessProtocolGuid ## PRODUCES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ MemInfoDxeExtra.uni
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h
new file mode 100644
index 000000000000..4b4b498062c8
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h
@@ -0,0 +1,170 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MEM_INFO_SCREEN_H_
+#define MEM_INFO_SCREEN_H_
+
+#include <Uefi.h>
+
+#include <Guid/MdeModuleHii.h>
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <PlatformInfoHob.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/HiiConfigKeyword.h>
+#include <Protocol/HiiConfigRouting.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
+
+#include "MemInfoScreenNVDataStruct.h"
+
+//
+// This is the generated IFR binary data for each formset defined in VFR.
+// This data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 MemInfoScreenVfrBin[];
+
+//
+// This is the generated String package data for all .UNI files.
+// This data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 MemInfoDxeStrings[];
+
+enum DDR_ECC_MODE {
+ ECC_DISABLE = 0,
+ ECC_SECDED,
+ SYMBOL_ECC
+};
+
+enum DDR_ERROR_CTRL_MODE_DE {
+ ERRCTLR_DE_DISABLE = 0,
+ ERRCTLR_DE_ENABLE,
+};
+
+enum DDR_ERROR_CTRL_MODE_FI {
+ ERRCTLR_FI_DISABLE = 0,
+ ERRCTLR_FI_ENABLE,
+};
+
+#define MEM_INFO_DDR_SPEED_SEL_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, DDRSpeedSel)
+#define MEM_INFO_ECC_MODE_SEL_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, EccMode)
+#define MEM_INFO_ERR_CTRL_DE_MODE_SEL_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, ErrCtrl_DE)
+#define MEM_INFO_ERR_CTRL_FI_MODE_SEL_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, ErrCtrl_FI)
+#define MEM_INFO_ERR_SLAVE_32BIT_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, Slave32bit)
+#define MEM_INFO_DDR_SCRUB_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, ScrubPatrol)
+#define MEM_INFO_DDR_DEMAND_SCRUB_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, DemandScrub)
+#define MEM_INFO_DDR_WRITE_CRC_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, WriteCrc)
+#define MEM_INFO_FGR_MODE_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, FGRMode)
+#define MEM_INFO_REFRESH2X_MODE_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, Refresh2x)
+#define MEM_INFO_NVDIMM_MODE_SEL_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, NvdimmModeSel)
+
+#define MEM_INFO_SCREEN_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('M', 'E', 'M', 'i')
+
+#define MEM_INFO_DDR_SPEED_SEL_QUESTION_ID 0x8001
+#define MEM_INFO_FORM_PERFORMANCE_QUESTION_ID 0x8002
+#define MEM_INFO_FORM_PERFORMANCE_ECC_QUESTION_ID 0x8003
+#define MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_DE_QUESTION_ID 0x8004
+#define MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_FI_QUESTION_ID 0x8005
+#define MEM_INFO_DDR_SLAVE_32BIT_QUESTION_ID 0x8006
+#define MEM_INFO_DDR_SCRUB_PATROL_QUESTION_ID 0x8007
+#define MEM_INFO_DDR_DEMAND_SCRUB_QUESTION_ID 0x8008
+#define MEM_INFO_DDR_WRITE_CRC_QUESTION_ID 0x8009
+#define MEM_INFO_FGR_MODE_QUESTION_ID 0x800A
+#define MEM_INFO_REFRESH2X_MODE_QUESTION_ID 0x800B
+#define MEM_INFO_FORM_NVDIMM_QUESTION_ID 0x800C
+#define MEM_INFO_FORM_NVDIMM_MODE_SEL_QUESTION_ID 0x800D
+
+#define MAX_NUMBER_OF_HOURS_IN_A_DAY 24
+
+#define DDR_DEFAULT_SCRUB_PATROL_DURATION 24
+#define DDR_DEFAULT_DEMAND_SCRUB 1
+#define DDR_DEFAULT_WRITE_CRC 0
+#define DDR_DEFAULT_FGR_MODE 0
+#define DDR_DEFAULT_REFRESH2X_MODE 0
+#define DDR_DEFAULT_NVDIMM_MODE_SEL 3
+
+#define DDR_FGR_MODE_GET(Value) ((Value) & 0x3) /* Bit 0, 1 */
+#define DDR_FGR_MODE_SET(Dst, Src) do { Dst = (((Dst) & ~0x3) | ((Src) & 0x3)); } while (0)
+
+#define DDR_REFRESH_2X_GET(Value) ((Value) & 0x10000) >> 16 /* Bit 16 only */
+#define DDR_REFRESH_2X_SET(Dst, Src) do { Dst = (((Dst) & ~0x10000) | ((Src) & 0x1) << 16); } while (0)
+
+#define DDR_NVDIMM_MODE_SEL_MASK 0x7FFFFFFF
+#define DDR_NVDIMM_MODE_SEL_VALID_BIT BIT31
+
+typedef struct {
+ UINTN Signature;
+
+ EFI_HANDLE DriverHandle;
+ EFI_HII_HANDLE HiiHandle;
+ MEM_INFO_VARSTORE_DATA VarStoreConfig;
+
+ //
+ // Consumed protocol
+ //
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
+ EFI_HII_STRING_PROTOCOL *HiiString;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+ EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
+ EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
+
+ //
+ // Produced protocol
+ //
+ EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+} MEM_INFO_SCREEN_PRIVATE_DATA;
+
+#define MEM_INFO_SCREEN_PRIVATE_FROM_THIS(a) CR (a, MEM_INFO_SCREEN_PRIVATE_DATA, ConfigAccess, MEM_INFO_SCREEN_PRIVATE_DATA_SIGNATURE)
+
+#pragma pack(1)
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+EFI_STATUS
+MemInfoScreenInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+EFI_STATUS
+MemInfoScreenUnload (
+ IN EFI_HANDLE ImageHandle
+ );
+
+EFI_STATUS
+MemInfoNvparamGet (
+ OUT MEM_INFO_VARSTORE_DATA *VarStoreConfig
+ );
+
+EFI_STATUS
+MemInfoNvparamSet (
+ IN MEM_INFO_VARSTORE_DATA *VarStoreConfig
+ );
+
+#endif /* MEM_INFO_SCREEN_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenNVDataStruct.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenNVDataStruct.h
new file mode 100644
index 000000000000..75960c367880
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenNVDataStruct.h
@@ -0,0 +1,47 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MEM_INFO_SCREEN_NV_DATA_STRUCT_H_
+#define MEM_INFO_SCREEN_NV_DATA_STRUCT_H_
+
+#define MEM_INFO_VARSTORE_NAME L"MemInfoIfrNVData"
+#define MEM_INFO_VARSTORE_ID 0x1234
+#define MEM_INFO_FORM_ID 0x1235
+#define MEM_INFO_FORM_PERFORMANCE_ID 0x1236
+#define MEM_INFO_FORM_NVDIMM_ID 0x1237
+#define MEM_INFO_FORM_SET_GUID { 0xd58338ee, 0xe9f7, 0x4d8d, { 0xa7, 0x08, 0xdf, 0xb2, 0xc6, 0x66, 0x1d, 0x61 } }
+#define MEM_INFO_FORM_SET_PERFORMANCE_GUID { 0x4a072c78, 0x42f9, 0x11ea, { 0xb7, 0x7f, 0x2e, 0x28, 0xce, 0x88, 0x12, 0x62 } }
+
+#pragma pack(1)
+
+//
+// NV data structure definition
+//
+typedef struct {
+ UINT32 DDRSpeedSel;
+ UINT32 EccMode;
+ UINT32 ErrCtrl_DE;
+ UINT32 ErrCtrl_FI;
+ UINT32 Slave32bit;
+ UINT32 ScrubPatrol;
+ UINT32 DemandScrub;
+ UINT32 WriteCrc;
+ UINT32 FGRMode;
+ UINT32 Refresh2x;
+ UINT32 NvdimmModeSel;
+} MEM_INFO_VARSTORE_DATA;
+
+//
+// Labels definition
+//
+#define LABEL_UPDATE 0x2223
+#define LABEL_END 0x2224
+
+#pragma pack()
+
+#endif
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenVfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenVfr.vfr
new file mode 100644
index 000000000000..e3d7aa0c44bd
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenVfr.vfr
@@ -0,0 +1,62 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Guid/PlatformManagerHii.h>
+#include "MemInfoScreenNVDataStruct.h"
+
+formset
+ guid = MEM_INFO_FORM_SET_GUID,
+ title = STRING_TOKEN(STR_MEM_INFO_FORM),
+ help = STRING_TOKEN(STR_MEM_INFO_FORM_HELP),
+ classguid = gPlatformManagerFormsetGuid,
+
+ //
+ // Define a variable Storage
+ //
+ varstore MEM_INFO_VARSTORE_DATA,
+ varid = MEM_INFO_VARSTORE_ID,
+ name = MemInfoIfrNVData,
+ guid = MEM_INFO_FORM_SET_GUID;
+
+ form
+ formid = MEM_INFO_FORM_ID,
+ title = STRING_TOKEN(STR_MEM_INFO_FORM);
+
+ subtitle text = STRING_TOKEN(STR_MEM_INFO_FORM);
+
+ label LABEL_UPDATE;
+ // dynamic content here
+ label LABEL_END;
+
+ endform;
+
+ form
+ formid = MEM_INFO_FORM_PERFORMANCE_ID,
+ title = STRING_TOKEN(STR_MEM_INFO_PERFORMANCE_FORM);
+
+ subtitle text = STRING_TOKEN(STR_MEM_INFO_PERFORMANCE_FORM);
+
+ label LABEL_UPDATE;
+ // dynamic content here
+ label LABEL_END;
+
+ endform;
+
+ form
+ formid = MEM_INFO_FORM_NVDIMM_ID,
+ title = STRING_TOKEN(STR_MEM_INFO_NVDIMM_FORM);
+
+ subtitle text = STRING_TOKEN(STR_MEM_INFO_NVDIMM_FORM);
+
+ label LABEL_UPDATE;
+ // dynamic content here
+ label LABEL_END;
+
+ endform;
+
+endformset;
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c
new file mode 100644
index 000000000000..c83f489f4078
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c
@@ -0,0 +1,394 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/NVParamLib.h>
+
+#include "MemInfoScreen.h"
+#include "NVParamDef.h"
+
+#define DDR_NVPARAM_ERRCTRL_DE_FIELD_SHIFT 0
+#define DDR_NVPARAM_ERRCTRL_DE_FIELD_MASK 0x1
+
+#define DDR_NVPARAM_ERRCTRL_FI_FIELD_SHIFT 1
+#define DDR_NVPARAM_ERRCTRL_FI_FIELD_MASK 0x2
+
+/**
+ This is function collects meminfo from NVParam
+
+ @param Data The buffer to return the contents.
+
+ @retval EFI_SUCCESS Get response data successfully.
+ @retval Other value Failed to get meminfo from NVParam
+**/
+EFI_STATUS
+MemInfoNvparamGet (
+ OUT MEM_INFO_VARSTORE_DATA *VarStoreConfig
+ )
+{
+ UINT32 Value;
+ EFI_STATUS Status;
+
+ ASSERT (VarStoreConfig != NULL);
+
+ Status = NVParamGet (
+ NV_SI_DDR_SPEED,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->DDRSpeedSel = 0; /* Default auto mode */
+ } else {
+ VarStoreConfig->DDRSpeedSel = Value;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_ECC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->EccMode = ECC_SECDED; /* Default enable */
+ } else {
+ VarStoreConfig->EccMode = Value;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_ERRCTRL,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->ErrCtrl_DE = ERRCTLR_DE_ENABLE;
+ VarStoreConfig->ErrCtrl_FI = ERRCTLR_FI_ENABLE;
+ } else {
+ VarStoreConfig->ErrCtrl_DE = (Value & DDR_NVPARAM_ERRCTRL_DE_FIELD_MASK) >> DDR_NVPARAM_ERRCTRL_DE_FIELD_SHIFT;
+ VarStoreConfig->ErrCtrl_FI = (Value & DDR_NVPARAM_ERRCTRL_FI_FIELD_MASK) >> DDR_NVPARAM_ERRCTRL_FI_FIELD_SHIFT;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_SLAVE_32BIT_MEM_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->Slave32bit = 0; /* Default disabled */
+ } else {
+ VarStoreConfig->Slave32bit = Value;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_SCRUB_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->ScrubPatrol = DDR_DEFAULT_SCRUB_PATROL_DURATION;
+ } else {
+ VarStoreConfig->ScrubPatrol = Value;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_WR_BACK_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->DemandScrub = DDR_DEFAULT_DEMAND_SCRUB;
+ } else {
+ VarStoreConfig->DemandScrub = Value;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_CRC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->WriteCrc = DDR_DEFAULT_WRITE_CRC;
+ } else {
+ VarStoreConfig->WriteCrc = Value;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_REFRESH_GRANULARITY,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->FGRMode = DDR_DEFAULT_FGR_MODE;
+ VarStoreConfig->Refresh2x = DDR_DEFAULT_REFRESH2X_MODE;
+ } else {
+ VarStoreConfig->FGRMode = DDR_FGR_MODE_GET (Value);
+ VarStoreConfig->Refresh2x = DDR_REFRESH_2X_GET (Value);
+ }
+
+ Status = NVParamGet (
+ NV_SI_NVDIMM_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->NvdimmModeSel = DDR_DEFAULT_NVDIMM_MODE_SEL;
+ } else {
+ VarStoreConfig->NvdimmModeSel = Value & DDR_NVDIMM_MODE_SEL_MASK; /* Mask out valid bit */
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is function stores meminfo to corresponding NVParam
+
+ @param VarStoreConfig The contents for the variable.
+
+ @retval EFI_SUCCESS Set data successfully.
+ @retval Other value Failed to set meminfo to NVParam
+
+**/
+EFI_STATUS
+MemInfoNvparamSet (
+ IN MEM_INFO_VARSTORE_DATA *VarStoreConfig
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Value, TmpValue, Value2, Update;
+
+ ASSERT (VarStoreConfig != NULL);
+
+ /* Set DDR speed */
+ Status = NVParamGet (
+ NV_SI_DDR_SPEED,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != VarStoreConfig->DDRSpeedSel) {
+ Status = NVParamSet (
+ NV_SI_DDR_SPEED,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ VarStoreConfig->DDRSpeedSel
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Set ECC mode */
+ Status = NVParamGet (
+ NV_SI_DDR_ECC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != VarStoreConfig->EccMode) {
+ Status = NVParamSet (
+ NV_SI_DDR_ECC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ VarStoreConfig->EccMode
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Set ErrCtrl */
+ TmpValue = (VarStoreConfig->ErrCtrl_DE << DDR_NVPARAM_ERRCTRL_DE_FIELD_SHIFT) |
+ (VarStoreConfig->ErrCtrl_FI << DDR_NVPARAM_ERRCTRL_FI_FIELD_SHIFT);
+ Status = NVParamGet (
+ NV_SI_DDR_ERRCTRL,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != TmpValue ) {
+ Status = NVParamSet (
+ NV_SI_DDR_ERRCTRL,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ TmpValue
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Set slave's 32bit region */
+ TmpValue = VarStoreConfig->Slave32bit;
+ Status = NVParamGet (
+ NV_SI_DDR_SLAVE_32BIT_MEM_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != TmpValue ) {
+ if (TmpValue == 0) {
+ /* Default is disabled so just clear nvparam */
+ Status = NVParamClr (
+ NV_SI_DDR_SLAVE_32BIT_MEM_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC
+ );
+ } else {
+ Status = NVParamSet (
+ NV_SI_DDR_SLAVE_32BIT_MEM_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ TmpValue
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Set Scrub patrol */
+ TmpValue = VarStoreConfig->ScrubPatrol;
+ Status = NVParamGet (
+ NV_SI_DDR_SCRUB_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != TmpValue ) {
+ if (TmpValue == DDR_DEFAULT_SCRUB_PATROL_DURATION) {
+ Status = NVParamClr (
+ NV_SI_DDR_SCRUB_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC
+ );
+ } else {
+ Status = NVParamSet (
+ NV_SI_DDR_SCRUB_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ TmpValue
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Demand Scrub */
+ TmpValue = VarStoreConfig->DemandScrub;
+ Status = NVParamGet (
+ NV_SI_DDR_WR_BACK_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != TmpValue ) {
+ if (TmpValue == DDR_DEFAULT_DEMAND_SCRUB) {
+ Status = NVParamClr (
+ NV_SI_DDR_WR_BACK_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC
+ );
+ } else {
+ Status = NVParamSet (
+ NV_SI_DDR_WR_BACK_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ TmpValue
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Write CRC */
+ TmpValue = VarStoreConfig->WriteCrc;
+ Status = NVParamGet (
+ NV_SI_DDR_CRC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != TmpValue ) {
+ if (TmpValue == DDR_DEFAULT_WRITE_CRC) {
+ Status = NVParamClr (
+ NV_SI_DDR_CRC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC
+ );
+ } else {
+ Status = NVParamSet (
+ NV_SI_DDR_CRC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ TmpValue
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Write FGR/Refresh2X */
+ Value = 0;
+ Update = 0;
+ TmpValue = VarStoreConfig->FGRMode;
+ Status = NVParamGet (
+ NV_SI_DDR_REFRESH_GRANULARITY,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ Value2 = DDR_FGR_MODE_GET (Value);
+ if ((EFI_ERROR (Status) && TmpValue != DDR_DEFAULT_FGR_MODE)
+ || Value2 != TmpValue)
+ {
+ DDR_FGR_MODE_SET (Value, TmpValue);
+ Update = 1;
+ }
+
+ Value2 = DDR_REFRESH_2X_GET (Value);
+ TmpValue = VarStoreConfig->Refresh2x;
+ if ((EFI_ERROR (Status) && TmpValue != DDR_DEFAULT_REFRESH2X_MODE)
+ || Value2 != TmpValue)
+ {
+ DDR_REFRESH_2X_SET (Value, TmpValue);
+ Update = 1;
+ }
+
+ if (Update == 1) {
+ Status = NVParamSet (
+ NV_SI_DDR_REFRESH_GRANULARITY,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ Value
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Write NVDIMM-N Mode selection */
+ Value = 0;
+ TmpValue = VarStoreConfig->NvdimmModeSel;
+ Status = NVParamGet (
+ NV_SI_NVDIMM_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ Value2 = Value & DDR_NVDIMM_MODE_SEL_MASK; /* Mask out valid bit */
+ if (EFI_ERROR (Status) || Value2 != TmpValue ) {
+ if (TmpValue == DDR_DEFAULT_NVDIMM_MODE_SEL) {
+ Status = NVParamClr (
+ NV_SI_NVDIMM_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC
+ );
+ } else {
+ Value = TmpValue | DDR_NVDIMM_MODE_SEL_VALID_BIT; /* Add valid bit */
+ Status = NVParamSet (
+ NV_SI_NVDIMM_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ Value
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c
new file mode 100644
index 000000000000..3a1a5840db9d
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c
@@ -0,0 +1,1325 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MemInfoScreen.h"
+
+#define MAX_STRING_SIZE 64
+#define GB_SCALE_FACTOR (1024*1024*1024)
+#define MB_SCALE_FACTOR (1024*1024)
+
+EFI_GUID gMemInfoFormSetGuid = MEM_INFO_FORM_SET_GUID;
+
+HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ MEM_INFO_FORM_SET_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8)(END_DEVICE_PATH_LENGTH),
+ (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+EFI_HANDLE DriverHandle = NULL;
+MEM_INFO_SCREEN_PRIVATE_DATA *mPrivateData = NULL;
+
+/**
+ This function allows a caller to extract the current configuration for one
+ or more named elements from the target driver.
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Request A null-terminated Unicode string in
+ <ConfigRequest> format.
+ @param Progress On return, points to a character in the Request
+ string. Points to the string's null terminator if
+ request was successful. Points to the most recent
+ '&' before the first failing name/value pair (or
+ the beginning of the string if the failure is in
+ the first name/value pair) if the request was not
+ successful.
+ @param Results A null-terminated Unicode string in
+ <ConfigAltResp> format which has all values filled
+ in for the names in the Request string. String to
+ be allocated by the called function.
+ @retval EFI_SUCCESS The Results is filled with the requested values.
+ @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
+ driver.
+**/
+EFI_STATUS
+EFIAPI
+ExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+ EFI_STRING ConfigRequest;
+ EFI_STRING ConfigRequestHdr;
+ UINTN Size;
+ CHAR16 *StrPointer;
+ BOOLEAN AllocatedRequest;
+
+ if (Progress == NULL || Results == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Initialize the local variables.
+ //
+ ConfigRequestHdr = NULL;
+ ConfigRequest = NULL;
+ Size = 0;
+ *Progress = Request;
+ AllocatedRequest = FALSE;
+
+ PrivateData = MEM_INFO_SCREEN_PRIVATE_FROM_THIS (This);
+ HiiConfigRouting = PrivateData->HiiConfigRouting;
+
+ //
+ // Get Buffer Storage data from EFI variable.
+ // Try to get the current setting from variable.
+ //
+ BufferSize = sizeof (MEM_INFO_VARSTORE_DATA);
+ Status = MemInfoNvparamGet (&PrivateData->VarStoreConfig);
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (Request == NULL) {
+ //
+ // Request is set to NULL, construct full request string.
+ //
+
+ //
+ // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+ // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
+ //
+ ConfigRequestHdr = HiiConstructConfigHdr (&gMemInfoFormSetGuid, MEM_INFO_VARSTORE_NAME, PrivateData->DriverHandle);
+ Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+ ConfigRequest = AllocateZeroPool (Size);
+ ASSERT (ConfigRequest != NULL);
+ AllocatedRequest = TRUE;
+ UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+ FreePool (ConfigRequestHdr);
+ ConfigRequestHdr = NULL;
+ } else {
+ //
+ // Check routing data in <ConfigHdr>.
+ // Note: if only one Storage is used, then this checking could be skipped.
+ //
+ if (!HiiIsConfigHdrMatch (Request, &gMemInfoFormSetGuid, NULL)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Set Request to the unified request string.
+ //
+ ConfigRequest = Request;
+
+ //
+ // Check whether Request includes Request Element.
+ //
+ if (StrStr (Request, L"OFFSET") == NULL) {
+ //
+ // Check Request Element does exist in Request String
+ //
+ StrPointer = StrStr (Request, L"PATH");
+ if (StrPointer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (StrStr (StrPointer, L"&") == NULL) {
+ Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
+ ConfigRequest = AllocateZeroPool (Size);
+ ASSERT (ConfigRequest != NULL);
+ AllocatedRequest = TRUE;
+ UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize);
+ }
+ }
+ }
+
+ //
+ // Check if requesting Name/Value storage
+ //
+ if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
+ //
+ // Don't have any Name/Value storage names
+ //
+ Status = EFI_SUCCESS;
+ } else {
+ //
+ // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+ //
+ Status = HiiConfigRouting->BlockToConfig (
+ HiiConfigRouting,
+ ConfigRequest,
+ (UINT8 *)&PrivateData->VarStoreConfig,
+ BufferSize,
+ Results,
+ Progress
+ );
+ }
+
+ //
+ // Free the allocated config request string.
+ //
+ if (AllocatedRequest) {
+ FreePool (ConfigRequest);
+ }
+
+ if (ConfigRequestHdr != NULL) {
+ FreePool (ConfigRequestHdr);
+ }
+ //
+ // Set Progress string to the original request string.
+ //
+ if (Request == NULL) {
+ *Progress = NULL;
+ } else if (StrStr (Request, L"OFFSET") == NULL) {
+ *Progress = Request + StrLen (Request);
+ }
+
+ return Status;
+}
+
+/**
+ This function processes the results of changes in configuration.
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Configuration A null-terminated Unicode string in <ConfigResp>
+ format.
+ @param Progress A pointer to a string filled in with the offset of
+ the most recent '&' before the first failing
+ name/value pair (or the beginning of the string if
+ the failure is in the first name/value pair) or
+ the terminating NULL if all was successful.
+ @retval EFI_SUCCESS The Results is processed successfully.
+ @retval EFI_INVALID_PARAMETER Configuration is NULL.
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
+ driver.
+**/
+EFI_STATUS
+EFIAPI
+RouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+ if (Configuration == NULL || Progress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = MEM_INFO_SCREEN_PRIVATE_FROM_THIS (This);
+ HiiConfigRouting = PrivateData->HiiConfigRouting;
+ *Progress = Configuration;
+
+ //
+ // Check routing data in <ConfigHdr>.
+ // Note: if only one Storage is used, then this checking could be skipped.
+ //
+ if (!HiiIsConfigHdrMatch (Configuration, &gMemInfoFormSetGuid, NULL)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Get Buffer Storage data from NVParam
+ //
+ Status = MemInfoNvparamGet (&PrivateData->VarStoreConfig);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Check if configuring Name/Value storage
+ //
+ if (StrStr (Configuration, L"OFFSET") == NULL) {
+ //
+ // Don't have any Name/Value storage names
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
+ //
+ BufferSize = sizeof (MEM_INFO_VARSTORE_DATA);
+ Status = HiiConfigRouting->ConfigToBlock (
+ HiiConfigRouting,
+ Configuration,
+ (UINT8 *)&PrivateData->VarStoreConfig,
+ &BufferSize,
+ Progress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Store Buffer Storage back to NVParam
+ //
+ Status = MemInfoNvparamSet (&PrivateData->VarStoreConfig);
+
+ return Status;
+}
+
+/**
+ This function processes the results of changes in configuration.
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Action Specifies the type of action taken by the browser.
+ @param QuestionId A unique value which is sent to the original
+ exporting driver so that it can identify the type
+ of data to expect.
+ @param Type The type of value for the question.
+ @param Value A pointer to the data being sent to the original
+ exporting driver.
+ @param ActionRequest On return, points to the action requested by the
+ callback function.
+ @retval EFI_SUCCESS The callback successfully handled the action.
+ @retval EFI_INVALID_PARAMETER Configuration is NULL.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the
+ callback.
+**/
+EFI_STATUS
+EFIAPI
+DriverCallback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ )
+{
+ if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN)
+ && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))
+ || (ActionRequest == NULL))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (Action) {
+ case EFI_BROWSER_ACTION_FORM_OPEN:
+ case EFI_BROWSER_ACTION_FORM_CLOSE:
+ break;
+
+ case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
+ case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
+ {
+ switch (QuestionId) {
+ case MEM_INFO_DDR_SPEED_SEL_QUESTION_ID:
+ //
+ // DDR speed selection default to auto
+ //
+ Value->u32 = 0;
+ break;
+
+ case MEM_INFO_FORM_PERFORMANCE_ECC_QUESTION_ID:
+ //
+ // ECC mode default to be enabled
+ //
+ Value->u32 = ECC_SECDED;
+ break;
+
+ case MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_DE_QUESTION_ID:
+ //
+ // ErrCtrl_DE default to be enabled
+ //
+ Value->u32 = ERRCTLR_DE_ENABLE;
+ break;
+
+ case MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_FI_QUESTION_ID:
+ //
+ // ErrCtrl_FI default to be enabled
+ //
+ Value->u32 = ERRCTLR_FI_ENABLE;
+ break;
+
+ case MEM_INFO_DDR_SLAVE_32BIT_QUESTION_ID:
+ //
+ // Slave's 32bit region to be disabled
+ //
+ Value->u32 = 0;
+ break;
+
+ case MEM_INFO_DDR_SCRUB_PATROL_QUESTION_ID:
+ Value->u32 = DDR_DEFAULT_SCRUB_PATROL_DURATION;
+ break;
+
+ case MEM_INFO_DDR_DEMAND_SCRUB_QUESTION_ID:
+ Value->u32 = DDR_DEFAULT_DEMAND_SCRUB;
+ break;
+
+ case MEM_INFO_DDR_WRITE_CRC_QUESTION_ID:
+ Value->u32 = DDR_DEFAULT_WRITE_CRC;
+ break;
+
+ case MEM_INFO_FGR_MODE_QUESTION_ID:
+ Value->u32 = DDR_DEFAULT_FGR_MODE;
+ break;
+
+ case MEM_INFO_REFRESH2X_MODE_QUESTION_ID:
+ Value->u32 = DDR_DEFAULT_REFRESH2X_MODE;
+ break;
+
+ case MEM_INFO_FORM_NVDIMM_MODE_SEL_QUESTION_ID:
+ Value->u32 = DDR_DEFAULT_NVDIMM_MODE_SEL;
+ break;
+ }
+ }
+ break;
+
+ case EFI_BROWSER_ACTION_RETRIEVE:
+ case EFI_BROWSER_ACTION_CHANGING:
+ case EFI_BROWSER_ACTION_SUBMITTED:
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MemInfoMainScreen (
+ PLATFORM_INFO_HOB *PlatformHob
+ )
+{
+ MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData = mPrivateData;
+ EFI_STATUS Status;
+ VOID *StartOpCodeHandle;
+ VOID *OptionsOpCodeHandle;
+ VOID *OptionsOpCodeHandle1;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ EFI_STRING_ID StringId;
+ VOID *EndOpCodeHandle;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ CHAR16 Str[MAX_STRING_SIZE], Str1[MAX_STRING_SIZE];
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;
+ PLATFORM_DIMM_INFO *DimmInfo;
+ UINT64 Size;
+ UINTN Count;
+
+ //
+ // Get Buffer Storage data from EFI variable
+ //
+ Status = MemInfoNvparamGet (&PrivateData->VarStoreConfig);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = EFI_SUCCESS;
+
+ /* Update Total memory */
+ UnicodeSPrint (Str, sizeof (Str), L"%d GB", PlatformHob->DramInfo.TotalSize / GB_SCALE_FACTOR);
+ HiiSetString (
+ PrivateData->HiiHandle,
+ STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM_VALUE),
+ Str,
+ NULL
+ );
+
+ /* Update effective memory */
+ Size = 0;
+ ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+ while (ResHob != NULL) {
+ if ((ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)) {
+ Size += ResHob->ResourceLength;
+ }
+ ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
+ }
+ UnicodeSPrint (Str, sizeof (Str), L"%d GB", Size / GB_SCALE_FACTOR);
+ HiiSetString (
+ PrivateData->HiiHandle,
+ STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM_VALUE),
+ Str,
+ NULL
+ );
+
+ /* Update current DDR speed */
+ UnicodeSPrint (Str, sizeof (Str), L"%d MHz", PlatformHob->DramInfo.MaxSpeed);
+ HiiSetString (
+ PrivateData->HiiHandle,
+ STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED_VALUE),
+ Str,
+ NULL
+ );
+
+ //
+ // Initialize the container for dynamic opcodes
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (StartOpCodeHandle != NULL);
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (EndOpCodeHandle != NULL);
+
+ //
+ // Create Option OpCode to display speed configuration
+ //
+ OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (OptionsOpCodeHandle != NULL);
+
+ //
+ // Create Option OpCode to display FGR mode configuration
+ //
+ OptionsOpCodeHandle1 = HiiAllocateOpCodeHandle ();
+ ASSERT (OptionsOpCodeHandle1 != NULL);
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LABEL_UPDATE;
+
+ //
+ // Create Hii Extend Label OpCode as the end opcode
+ //
+ EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ //
+ // Create a total mem title
+ //
+ HiiCreateTextOpCode (
+ StartOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM),
+ STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM),
+ STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM_VALUE)
+ );
+
+ //
+ // Create a effective mem title
+ //
+ HiiCreateTextOpCode (
+ StartOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM),
+ STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM),
+ STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM_VALUE)
+ );
+
+ //
+ // Create a current speed title
+ //
+ HiiCreateTextOpCode (
+ StartOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED),
+ STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED),
+ STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED_VALUE)
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE0),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 0
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE1),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2133
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE2),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2400
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE3),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2666
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE4),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2933
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE5),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 3200
+ );
+
+ HiiCreateOneOfOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_DDR_SPEED_SEL_QUESTION_ID, // Question ID (or call it "key")
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_DDR_SPEED_SEL_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+ EFI_IFR_NUMERIC_SIZE_4, // Data type of Question Value
+ OptionsOpCodeHandle, // Option Opcode list
+ NULL // Default Opcode is NULl
+ );
+
+ if (IsSlaveSocketActive ()) {
+ /* Display enable slave's 32bit region */
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_DDR_SLAVE_32BIT_QUESTION_ID, // Question ID
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_ERR_SLAVE_32BIT_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_32GB_SLAVE_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_32GB_SLAVE_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+ 0,
+ NULL
+ );
+ }
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle1,
+ STRING_TOKEN (STR_MEM_INFO_FGR_MODE_VALUE0),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 0
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle1,
+ STRING_TOKEN (STR_MEM_INFO_FGR_MODE_VALUE1),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 1
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle1,
+ STRING_TOKEN (STR_MEM_INFO_FGR_MODE_VALUE2),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2
+ );
+
+ HiiCreateOneOfOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FGR_MODE_QUESTION_ID, // Question ID (or call it "key")
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_FGR_MODE_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_FGR_MODE_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_FGR_MODE_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+ EFI_IFR_NUMERIC_SIZE_4, // Data type of Question Value
+ OptionsOpCodeHandle1, // Option Opcode list
+ NULL // Default Opcode is NULl
+ );
+
+ //
+ // Create a Goto OpCode to ras memory configuration
+ //
+ HiiCreateGotoOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FORM_PERFORMANCE_ID, // Target Form ID
+ STRING_TOKEN (STR_MEM_INFO_PERFORMANCE_FORM), // Prompt text
+ STRING_TOKEN (STR_MEM_INFO_PERFORMANCE_FORM_HELP), // Help text
+ 0, // Question flag
+ MEM_INFO_FORM_PERFORMANCE_QUESTION_ID // Question ID
+ );
+
+ //
+ // Create a Goto OpCode to nvdimm-n configuration
+ //
+ HiiCreateGotoOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FORM_NVDIMM_ID, // Target Form ID
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_FORM), // Prompt text
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_FORM_HELP), // Help text
+ 0, // Question flag
+ MEM_INFO_FORM_NVDIMM_QUESTION_ID // Question ID
+ );
+
+ //
+ // Display DIMM list info
+ //
+ HiiCreateSubTitleOpCode (
+ StartOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_DIMM_INFO),
+ 0,
+ 0,
+ 0
+ );
+
+ for (Count = 0; Count < PlatformHob->DimmList.BoardDimmSlots; Count++) {
+ DimmInfo = &PlatformHob->DimmList.Dimm[Count].Info;
+ switch (DimmInfo->DimmType) {
+ case UDIMM:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"UDIMM");
+ break;
+
+ case RDIMM:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"RDIMM");
+ break;
+
+ case SODIMM:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"SODIMM");
+ break;
+
+ case LRDIMM:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"LRDIMM");
+ break;
+
+ case RSODIMM:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"RSODIMM");
+ break;
+
+ case NVRDIMM:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"NV-RDIMM");
+ break;
+
+ default:
+ UnicodeSPrint (Str, sizeof (Str), L"Unknown Type");
+ }
+ if (DimmInfo->DimmStatus == DIMM_INSTALLED_OPERATIONAL) {
+ UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: %d GB %s Installed&Operational", Count + 1, DimmInfo->DimmSize, Str);
+ } else if (DimmInfo->DimmStatus == DIMM_NOT_INSTALLED) {
+ UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: Not Installed", Count + 1, PlatformHob->DimmList.Dimm[Count].NodeId);
+ } else if (DimmInfo->DimmStatus == DIMM_INSTALLED_NONOPERATIONAL) {
+ UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: Installed&Non-Operational", Count + 1, PlatformHob->DimmList.Dimm[Count].NodeId);
+ } else {
+ UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: Installed&Failed", Count + 1, PlatformHob->DimmList.Dimm[Count].NodeId);
+ }
+
+ StringId = HiiSetString (PrivateData->HiiHandle, 0, Str1, NULL);
+
+ HiiCreateSubTitleOpCode (
+ StartOpCodeHandle,
+ StringId,
+ 0,
+ 0,
+ 0
+ );
+ }
+
+ HiiUpdateForm (
+ PrivateData->HiiHandle, // HII handle
+ &gMemInfoFormSetGuid, // Formset GUID
+ MEM_INFO_FORM_ID, // Form ID
+ StartOpCodeHandle, // Label for where to insert opcodes
+ EndOpCodeHandle // Insert data
+ );
+
+ HiiFreeOpCodeHandle (StartOpCodeHandle);
+ HiiFreeOpCodeHandle (EndOpCodeHandle);
+ HiiFreeOpCodeHandle (OptionsOpCodeHandle);
+
+ return Status;
+}
+
+EFI_STATUS
+MemInfoMainPerformanceScreen (
+ PLATFORM_INFO_HOB *PlatformHob
+ )
+{
+ EFI_STATUS Status;
+ MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData = mPrivateData;
+ VOID *StartOpCodeHandle;
+ VOID *OptionsEccOpCodeHandle, *OptionsScrubOpCodeHandle;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ VOID *EndOpCodeHandle;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ EFI_STRING_ID StringId;
+ CHAR16 Str[MAX_STRING_SIZE];
+ UINTN Idx;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Initialize the container for dynamic opcodes
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (StartOpCodeHandle != NULL);
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (EndOpCodeHandle != NULL);
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LABEL_UPDATE;
+
+ //
+ // Create Hii Extend Label OpCode as the end opcode
+ //
+ EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ /* Display ECC mode selection */
+ OptionsEccOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (OptionsEccOpCodeHandle != NULL);
+
+ UnicodeSPrint (Str, sizeof (Str), L"Disabled");
+ StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsEccOpCodeHandle,
+ StringId,
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 0
+ );
+
+ UnicodeSPrint (Str, sizeof (Str), L"SECDED");
+ StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsEccOpCodeHandle,
+ StringId,
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 1
+ );
+
+ UnicodeSPrint (Str, sizeof (Str), L"Symbol");
+ StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsEccOpCodeHandle,
+ StringId,
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2
+ );
+
+ HiiCreateOneOfOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FORM_PERFORMANCE_ECC_QUESTION_ID, // Question ID (or call it "key")
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_ECC_MODE_SEL_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_ECC_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_ECC_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+ EFI_IFR_NUMERIC_SIZE_4, // Data type of Question Value
+ OptionsEccOpCodeHandle, // Option Opcode list
+ NULL // Default Opcode is NULl
+ );
+
+ /*
+ * Display ErrCtrl options
+ */
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_DE_QUESTION_ID, // Question ID
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_ERR_CTRL_DE_MODE_SEL_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_DE_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_DE_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+ 0,
+ NULL
+ );
+
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_FI_QUESTION_ID, // Question ID
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_ERR_CTRL_FI_MODE_SEL_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_FI_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_FI_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+ 0,
+ NULL
+ );
+
+ /* Display Scrub Patrol selection */
+ OptionsScrubOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (OptionsScrubOpCodeHandle != NULL);
+
+ UnicodeSPrint (Str, sizeof (Str), L"Disabled");
+ StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsScrubOpCodeHandle,
+ StringId,
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 0
+ );
+
+ for (Idx = 1; Idx <= MAX_NUMBER_OF_HOURS_IN_A_DAY; Idx++) {
+ UnicodeSPrint (Str, sizeof (Str), L"%d", Idx);
+ StringId = HiiSetString (
+ PrivateData->HiiHandle,
+ 0,
+ Str,
+ NULL
+ );
+ HiiCreateOneOfOptionOpCode (
+ OptionsScrubOpCodeHandle,
+ StringId,
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ Idx
+ );
+ }
+
+ HiiCreateOneOfOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_DDR_SCRUB_PATROL_QUESTION_ID, // Question ID (or call it "key")
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_DDR_SCRUB_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_SCRUB), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_SCRUB_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+ EFI_IFR_NUMERIC_SIZE_4, // Data type of Question Value
+ OptionsScrubOpCodeHandle, // Option Opcode list
+ NULL // Default Opcode is NULl
+ );
+
+ /*
+ * Display Demand Scrub options
+ */
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_DDR_DEMAND_SCRUB_QUESTION_ID, // Question ID
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_DDR_DEMAND_SCRUB_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_DEMAND_SCRUB_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_DEMAND_SCRUB_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+ 0,
+ NULL
+ );
+
+ /*
+ * Display Write CRC options
+ */
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_DDR_WRITE_CRC_QUESTION_ID, // Question ID
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_DDR_WRITE_CRC_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_WRITE_CRC_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_WRITE_CRC_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+ 0,
+ NULL
+ );
+
+ /*
+ * Display CVE-2020-10255 options
+ */
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_REFRESH2X_MODE_QUESTION_ID, // Question ID
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_REFRESH2X_MODE_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_REFRESH2X_MODE_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_REFRESH2X_MODE_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+ 0,
+ NULL
+ );
+
+ HiiUpdateForm (
+ PrivateData->HiiHandle, // HII handle
+ &gMemInfoFormSetGuid, // Formset GUID
+ MEM_INFO_FORM_PERFORMANCE_ID, // Form ID
+ StartOpCodeHandle, // Label for where to insert opcodes
+ EndOpCodeHandle // Insert data
+ );
+
+ HiiFreeOpCodeHandle (StartOpCodeHandle);
+ HiiFreeOpCodeHandle (EndOpCodeHandle);
+ HiiFreeOpCodeHandle (OptionsEccOpCodeHandle);
+ HiiFreeOpCodeHandle (OptionsScrubOpCodeHandle);
+
+ return Status;
+}
+
+EFI_STATUS
+MemInfoMainNvdimmScreen (
+ PLATFORM_INFO_HOB *PlatformHob
+ )
+{
+ EFI_STATUS Status;
+ MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData;
+ VOID *StartOpCodeHandle;
+ VOID *OptionsOpCodeHandle;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ VOID *EndOpCodeHandle;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ CHAR16 Str[MAX_STRING_SIZE];
+
+ Status = EFI_SUCCESS;
+ PrivateData = mPrivateData;
+
+ if (PlatformHob == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Initialize the container for dynamic opcodes
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (StartOpCodeHandle != NULL);
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (EndOpCodeHandle != NULL);
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ StartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LABEL_UPDATE;
+
+ //
+ // Create Hii Extend Label OpCode as the end opcode
+ //
+ EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ EndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ //
+ // Update Current NVDIMM-N Mode title Socket0
+ //
+ switch (PlatformHob->DramInfo.NvdimmMode[0]) {
+ case 0:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-NVDIMM");
+ break;
+
+ case 1:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-Hashed");
+ break;
+
+ case 2:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Hashed");
+ break;
+
+ default:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Unknown");
+ break;
+ }
+
+ HiiSetString (
+ PrivateData->HiiHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0_VALUE),
+ Str,
+ NULL
+ );
+
+ HiiCreateTextOpCode (
+ StartOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0),
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0),
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0_VALUE)
+ );
+
+ //
+ // Update Current NVDIMM-N Mode title Socket1
+ //
+ if (IsSlaveSocketActive ()) {
+ switch (PlatformHob->DramInfo.NvdimmMode[1]) {
+ case 0:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-NVDIMM");
+ break;
+
+ case 1:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-Hashed");
+ break;
+
+ case 2:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Hashed");
+ break;
+
+ default:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Unknown");
+ break;
+ }
+
+ HiiSetString (
+ PrivateData->HiiHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1_VALUE),
+ Str,
+ NULL
+ );
+
+ HiiCreateTextOpCode (
+ StartOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1),
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1),
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1_VALUE)
+ );
+ }
+ //
+ // Create Option OpCode to NVDIMM-N Mode Selection
+ //
+ OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (OptionsOpCodeHandle != NULL);
+
+ //
+ // Create OpCode to NVDIMM-N Mode Selection
+ //
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE0),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 0
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE1),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 1
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE2),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE3),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 3
+ );
+
+ HiiCreateOneOfOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FORM_NVDIMM_MODE_SEL_QUESTION_ID, // Question ID (or call it "key")
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_NVDIMM_MODE_SEL_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+ EFI_IFR_NUMERIC_SIZE_4, // Data type of Question Value
+ OptionsOpCodeHandle, // Option Opcode list
+ NULL // Default Opcode is NULl
+ );
+
+ HiiUpdateForm (
+ PrivateData->HiiHandle, // HII handle
+ &gMemInfoFormSetGuid, // Formset GUID
+ MEM_INFO_FORM_NVDIMM_ID, // Form ID
+ StartOpCodeHandle, // Label for where to insert opcodes
+ EndOpCodeHandle // Insert data
+ );
+
+ HiiFreeOpCodeHandle (StartOpCodeHandle);
+ HiiFreeOpCodeHandle (EndOpCodeHandle);
+ HiiFreeOpCodeHandle (OptionsOpCodeHandle);
+
+ return Status;
+}
+
+/**
+ This function sets up the first elements of the form.
+ @param PrivateData Private data.
+ @retval EFI_SUCCESS The form is set up successfully.
+**/
+EFI_STATUS
+MemInfoScreenSetup (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ VOID *Hob;
+ PLATFORM_INFO_HOB *PlatformHob;
+
+ /* Get the Platform HOB */
+ Hob = GetFirstGuidHob (&gPlatformHobGuid);
+ if (Hob == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+ PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+ Status = MemInfoMainScreen (PlatformHob);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = MemInfoMainPerformanceScreen (PlatformHob);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = MemInfoMainNvdimmScreen (PlatformHob);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MemInfoScreenInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+ BOOLEAN ActionFlag;
+ EFI_STRING ConfigRequestHdr;
+
+ //
+ // Initialize driver private data
+ //
+ mPrivateData = AllocateZeroPool (sizeof (MEM_INFO_SCREEN_PRIVATE_DATA));
+ if (mPrivateData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mPrivateData->Signature = MEM_INFO_SCREEN_PRIVATE_DATA_SIGNATURE;
+
+ mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
+ mPrivateData->ConfigAccess.RouteConfig = RouteConfig;
+ mPrivateData->ConfigAccess.Callback = DriverCallback;
+
+ //
+ // Locate ConfigRouting protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ mPrivateData->HiiConfigRouting = HiiConfigRouting;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &mPrivateData->ConfigAccess,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ mPrivateData->DriverHandle = DriverHandle;
+
+ //
+ // Publish our HII data
+ //
+ HiiHandle = HiiAddPackages (
+ &gMemInfoFormSetGuid,
+ DriverHandle,
+ MemInfoDxeStrings,
+ MemInfoScreenVfrBin,
+ NULL
+ );
+ if (HiiHandle == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mPrivateData->HiiHandle = HiiHandle;
+
+ //
+ // Try to read NV config EFI variable first
+ //
+ ConfigRequestHdr = HiiConstructConfigHdr (
+ &gMemInfoFormSetGuid,
+ MEM_INFO_VARSTORE_NAME,
+ DriverHandle
+ );
+ ASSERT (ConfigRequestHdr != NULL);
+
+ //
+ // Validate Current Setting
+ //
+ ActionFlag = HiiValidateSettings (ConfigRequestHdr);
+ if (!ActionFlag) {
+ MemInfoScreenUnload (ImageHandle);
+ return EFI_INVALID_PARAMETER;
+ }
+ FreePool (ConfigRequestHdr);
+
+ Status = MemInfoScreenSetup ();
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MemInfoScreenUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ ASSERT (mPrivateData != NULL);
+
+ if (DriverHandle != NULL) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &mPrivateData->ConfigAccess,
+ NULL
+ );
+ DriverHandle = NULL;
+ }
+
+ if (mPrivateData->HiiHandle != NULL) {
+ HiiRemovePackages (mPrivateData->HiiHandle);
+ }
+
+ FreePool (mPrivateData);
+ mPrivateData = NULL;
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni
new file mode 100644
index 000000000000..a8c7cb99d6a7
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni
@@ -0,0 +1,9 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#string STR_MODULE_ABSTRACT #language en-US "An Altra DDR screen setup driver"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This driver exposes a screen setup for DDR information and configuration."
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni
new file mode 100644
index 000000000000..f44f210594be
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni
@@ -0,0 +1,9 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Ampere Altra MemInfo DXE Driver"
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni
new file mode 100644
index 000000000000..d170f9ee7313
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni
@@ -0,0 +1,64 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#langdef en-US "English" // English
+
+#string STR_MEM_INFO_FORM #language en-US "Memory Configuration"
+#string STR_MEM_INFO_FORM_HELP #language en-US "Memory Configuration"
+#string STR_MEM_INFO_TOTAL_MEM #language en-US "Total Memory"
+#string STR_MEM_INFO_TOTAL_MEM_VALUE #language en-US "0 GB"
+#string STR_MEM_INFO_EFFECT_MEM #language en-US "Effective Memory"
+#string STR_MEM_INFO_EFFECT_MEM_VALUE #language en-US "0 MB"
+#string STR_MEM_INFO_CURRENT_SPEED #language en-US "Memory Speed"
+#string STR_MEM_INFO_CURRENT_SPEED_VALUE #language en-US "0 MHz"
+#string STR_MEM_INFO_SPEED_SELECT_PROMPT #language en-US "Memory Operating Speed Selection"
+#string STR_MEM_INFO_SPEED_SELECT_HELP #language en-US "Force specific Memory Operating Speed or use Auto setting."
+#string STR_MEM_INFO_SPEED_SELECT_VALUE0 #language en-US "Auto"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE1 #language en-US "2133"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE2 #language en-US "2400"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE3 #language en-US "2666"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE4 #language en-US "2933"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE5 #language en-US "3200"
+#string STR_MEM_INFO_DIMM_INFO #language en-US "DIMM Information"
+
+#string STR_MEM_INFO_PERFORMANCE_FORM #language en-US "Memory RAS and Performance Configuration"
+#string STR_MEM_INFO_PERFORMANCE_FORM_HELP #language en-US "Displays and provides options to change the memory RAS and performance Settings"
+#string STR_MEM_INFO_ENABLE_ECC_PROMPT #language en-US "ECC mode"
+#string STR_MEM_INFO_ENABLE_ECC_HELP #language en-US "ECC mode: Disabled, SECDED or Symbol"
+#string STR_MEM_INFO_ENABLE_ERRCTRL_DE_PROMPT #language en-US "Defer uncorrectable read errors"
+#string STR_MEM_INFO_ENABLE_ERRCTRL_DE_HELP #language en-US "When enabled the DMC defers uncorrectable read errors to the consumer by sending an OK response and setting the TXDAT poison flag on the CHI-B interconnect. If this bit is clear the DMC defaults to non-deferred behavior when encountering an unrecoverable error"
+#string STR_MEM_INFO_ENABLE_ERRCTRL_FI_PROMPT #language en-US "Fault handling interrupt"
+#string STR_MEM_INFO_ENABLE_ERRCTRL_FI_HELP #language en-US "Enables fault handling interrupt. The fault handling interrupt is raised to give notice that ECC fault has been recorded"
+#string STR_MEM_INFO_ENABLE_SCRUB #language en-US "Scrub Patrol duration (hour)"
+#string STR_MEM_INFO_ENABLE_SCRUB_HELP #language en-US "Select duration (hour) for Scrub Patrol"
+#string STR_MEM_INFO_ENABLE_DEMAND_SCRUB_PROMPT #language en-US "Demand scrub"
+#string STR_MEM_INFO_ENABLE_DEMAND_SCRUB_HELP #language en-US "Enable/Disable the ability to write corrected data back to the memory once a correctable error is detected"
+#string STR_MEM_INFO_ENABLE_WRITE_CRC_PROMPT #language en-US "Write CRC"
+#string STR_MEM_INFO_ENABLE_WRITE_CRC_HELP #language en-US "Enable/Disable Cyclic Redundancy Check (CRC) functionality on write data. Be noted that enabling CRC will degrade Write bandwidth"
+
+
+#string STR_MEM_INFO_ENABLE_32GB_SLAVE_PROMPT #language en-US "Enable Slave 32bit memory region"
+#string STR_MEM_INFO_ENABLE_32GB_SLAVE_HELP #language en-US "Enables 32bit memory region (2GB) for slave socket"
+#string STR_MEM_INFO_FGR_MODE_PROMPT #language en-US "Fine Granularity Refresh (FGR)"
+#string STR_MEM_INFO_FGR_MODE_VALUE0 #language en-US "1x"
+#string STR_MEM_INFO_FGR_MODE_VALUE1 #language en-US "2x"
+#string STR_MEM_INFO_FGR_MODE_VALUE2 #language en-US "4x"
+#string STR_MEM_INFO_FGR_MODE_HELP #language en-US "Select DDR Fine Granularity Refresh (FGR) mode 1x/2x/4x"
+#string STR_MEM_INFO_REFRESH2X_MODE_PROMPT #language en-US "CVE-2020-10255 mitigation"
+#string STR_MEM_INFO_REFRESH2X_MODE_HELP #language en-US "Enable mitigation for CVE-2020-10255, TRRespass"
+
+#string STR_MEM_INFO_NVDIMM_FORM #language en-US "NVDIMM-N Configuration"
+#string STR_MEM_INFO_NVDIMM_FORM_HELP #language en-US "Displays and provides options to change the NVDIMM-N Settings"
+#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK0 #language en-US "Socket0 Configured Mode"
+#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK1 #language en-US "Socket1 Configured Mode"
+#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK0_VALUE #language en-US "Non-NVDIMM"
+#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK1_VALUE #language en-US "Non-NVDIMM"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_PROMPT #language en-US "Mode Selection"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE0 #language en-US "Non-NVDIMM"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE1 #language en-US "Non-Hashed"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE2 #language en-US "Hashed"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE3 #language en-US "Auto"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_HELP #language en-US "Select NVDIMM-N Mode (Non-NVDIMM/Non-Hashed/Hashed/Auto)"
--
2.17.1


Leif Lindholm
 

On Wed, Sep 15, 2021 at 22:55:22 +0700, Nhi Pham wrote:
From: Vu Nguyen <vunguyen@os.amperecomputing.com>

Provide memory screen with below info:
* Memory total capacity
* Memory RAS and Performance Configuration
* Per DIMM Information

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
Platform/Ampere/JadePkg/Jade.dsc | 1 +
Platform/Ampere/JadePkg/Jade.fdf | 1 +
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf | 59 +
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h | 170 +++
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenNVDataStruct.h | 47 +
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenVfr.vfr | 62 +
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c | 394 ++++++
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c | 1325 ++++++++++++++++++++
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni | 9 +
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni | 9 +
Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni | 64 +
11 files changed, 2141 insertions(+)

diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index f723be6997e6..5fc83745cdbc 100644
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -197,3 +197,4 @@ [Components.common]
# HII
#
Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
+ Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index c54b46f95ad5..6fe023025034 100644
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -355,5 +355,6 @@ [FV.FvMain]
# HII
#
INF Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
+ INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf

!include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
new file mode 100644
index 000000000000..fbb2ac9dad21
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
@@ -0,0 +1,59 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = MemInfoDxe
+ MODULE_UNI_FILE = MemInfoDxe.uni
+ FILE_GUID = D9EFCEFE-189B-4599-BB07-04F0A8DF5C2F
+ MODULE_TYPE = DXE_DRIVER
+ ENTRY_POINT = MemInfoScreenInitialize
+
+[Sources]
+ MemInfoNvramLib.c
+ MemInfoScreen.c
+ MemInfoScreen.h
+ MemInfoScreenStrings.uni
+ MemInfoScreenNVDataStruct.h
+ MemInfoScreenVfr.vfr
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+ Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+ AmpereCpuLib
+ BaseLib
+ DevicePathLib
+ HiiLib
+ HobLib
+ MemoryAllocationLib
+ NVParamLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Guids]
+ gEfiIfrTianoGuid ## PRODUCES ## UNDEFINED
+ gPlatformManagerFormsetGuid
+ gPlatformHobGuid
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## CONSUMES
+ gEfiHiiConfigRoutingProtocolGuid ## CONSUMES
+ gEfiHiiConfigAccessProtocolGuid ## PRODUCES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ MemInfoDxeExtra.uni
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h
new file mode 100644
index 000000000000..4b4b498062c8
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h
@@ -0,0 +1,170 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MEM_INFO_SCREEN_H_
+#define MEM_INFO_SCREEN_H_
+
+#include <Uefi.h>
+
+#include <Guid/MdeModuleHii.h>
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <PlatformInfoHob.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/HiiConfigKeyword.h>
+#include <Protocol/HiiConfigRouting.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
Header file should only include headers they use themselves.

+
+#include "MemInfoScreenNVDataStruct.h"
+
+//
+// This is the generated IFR binary data for each formset defined in VFR.
+// This data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 MemInfoScreenVfrBin[];
+
+//
+// This is the generated String package data for all .UNI files.
+// This data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 MemInfoDxeStrings[];
+
+enum DDR_ECC_MODE {
Enum style, as commented for a couple of earlier patches.

+ ECC_DISABLE = 0,
+ ECC_SECDED,
+ SYMBOL_ECC
+};
+
+enum DDR_ERROR_CTRL_MODE_DE {
+ ERRCTLR_DE_DISABLE = 0,
+ ERRCTLR_DE_ENABLE,
+};
+
+enum DDR_ERROR_CTRL_MODE_FI {
+ ERRCTLR_FI_DISABLE = 0,
+ ERRCTLR_FI_ENABLE,
+};
+
+#define MEM_INFO_DDR_SPEED_SEL_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, DDRSpeedSel)
+#define MEM_INFO_ECC_MODE_SEL_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, EccMode)
+#define MEM_INFO_ERR_CTRL_DE_MODE_SEL_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, ErrCtrl_DE)
+#define MEM_INFO_ERR_CTRL_FI_MODE_SEL_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, ErrCtrl_FI)
+#define MEM_INFO_ERR_SLAVE_32BIT_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, Slave32bit)
+#define MEM_INFO_DDR_SCRUB_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, ScrubPatrol)
+#define MEM_INFO_DDR_DEMAND_SCRUB_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, DemandScrub)
+#define MEM_INFO_DDR_WRITE_CRC_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, WriteCrc)
+#define MEM_INFO_FGR_MODE_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, FGRMode)
+#define MEM_INFO_REFRESH2X_MODE_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, Refresh2x)
+#define MEM_INFO_NVDIMM_MODE_SEL_OFFSET OFFSET_OF (MEM_INFO_VARSTORE_DATA, NvdimmModeSel)
+
+#define MEM_INFO_SCREEN_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('M', 'E', 'M', 'i')
+
+#define MEM_INFO_DDR_SPEED_SEL_QUESTION_ID 0x8001
+#define MEM_INFO_FORM_PERFORMANCE_QUESTION_ID 0x8002
+#define MEM_INFO_FORM_PERFORMANCE_ECC_QUESTION_ID 0x8003
+#define MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_DE_QUESTION_ID 0x8004
+#define MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_FI_QUESTION_ID 0x8005
+#define MEM_INFO_DDR_SLAVE_32BIT_QUESTION_ID 0x8006
+#define MEM_INFO_DDR_SCRUB_PATROL_QUESTION_ID 0x8007
+#define MEM_INFO_DDR_DEMAND_SCRUB_QUESTION_ID 0x8008
+#define MEM_INFO_DDR_WRITE_CRC_QUESTION_ID 0x8009
+#define MEM_INFO_FGR_MODE_QUESTION_ID 0x800A
+#define MEM_INFO_REFRESH2X_MODE_QUESTION_ID 0x800B
+#define MEM_INFO_FORM_NVDIMM_QUESTION_ID 0x800C
+#define MEM_INFO_FORM_NVDIMM_MODE_SEL_QUESTION_ID 0x800D
+
+#define MAX_NUMBER_OF_HOURS_IN_A_DAY 24
+
+#define DDR_DEFAULT_SCRUB_PATROL_DURATION 24
+#define DDR_DEFAULT_DEMAND_SCRUB 1
+#define DDR_DEFAULT_WRITE_CRC 0
+#define DDR_DEFAULT_FGR_MODE 0
+#define DDR_DEFAULT_REFRESH2X_MODE 0
+#define DDR_DEFAULT_NVDIMM_MODE_SEL 3
+
+#define DDR_FGR_MODE_GET(Value) ((Value) & 0x3) /* Bit 0, 1 */
+#define DDR_FGR_MODE_SET(Dst, Src) do { Dst = (((Dst) & ~0x3) | ((Src) & 0x3)); } while (0)
+
+#define DDR_REFRESH_2X_GET(Value) ((Value) & 0x10000) >> 16 /* Bit 16 only */
+#define DDR_REFRESH_2X_SET(Dst, Src) do { Dst = (((Dst) & ~0x10000) | ((Src) & 0x1) << 16); } while (0)
+
+#define DDR_NVDIMM_MODE_SEL_MASK 0x7FFFFFFF
+#define DDR_NVDIMM_MODE_SEL_VALID_BIT BIT31
+
+typedef struct {
+ UINTN Signature;
+
+ EFI_HANDLE DriverHandle;
+ EFI_HII_HANDLE HiiHandle;
+ MEM_INFO_VARSTORE_DATA VarStoreConfig;
+
+ //
+ // Consumed protocol
+ //
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
+ EFI_HII_STRING_PROTOCOL *HiiString;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+ EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
+ EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
+
+ //
+ // Produced protocol
+ //
+ EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+} MEM_INFO_SCREEN_PRIVATE_DATA;
+
+#define MEM_INFO_SCREEN_PRIVATE_FROM_THIS(a) CR (a, MEM_INFO_SCREEN_PRIVATE_DATA, ConfigAccess, MEM_INFO_SCREEN_PRIVATE_DATA_SIGNATURE)
+
+#pragma pack(1)
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+EFI_STATUS
+MemInfoScreenInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+EFI_STATUS
+MemInfoScreenUnload (
+ IN EFI_HANDLE ImageHandle
+ );
+
+EFI_STATUS
+MemInfoNvparamGet (
+ OUT MEM_INFO_VARSTORE_DATA *VarStoreConfig
+ );
+
+EFI_STATUS
+MemInfoNvparamSet (
+ IN MEM_INFO_VARSTORE_DATA *VarStoreConfig
+ );
+
+#endif /* MEM_INFO_SCREEN_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenNVDataStruct.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenNVDataStruct.h
new file mode 100644
index 000000000000..75960c367880
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenNVDataStruct.h
@@ -0,0 +1,47 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MEM_INFO_SCREEN_NV_DATA_STRUCT_H_
+#define MEM_INFO_SCREEN_NV_DATA_STRUCT_H_
+
+#define MEM_INFO_VARSTORE_NAME L"MemInfoIfrNVData"
+#define MEM_INFO_VARSTORE_ID 0x1234
+#define MEM_INFO_FORM_ID 0x1235
+#define MEM_INFO_FORM_PERFORMANCE_ID 0x1236
+#define MEM_INFO_FORM_NVDIMM_ID 0x1237
+#define MEM_INFO_FORM_SET_GUID { 0xd58338ee, 0xe9f7, 0x4d8d, { 0xa7, 0x08, 0xdf, 0xb2, 0xc6, 0x66, 0x1d, 0x61 } }
+#define MEM_INFO_FORM_SET_PERFORMANCE_GUID { 0x4a072c78, 0x42f9, 0x11ea, { 0xb7, 0x7f, 0x2e, 0x28, 0xce, 0x88, 0x12, 0x62 } }
+
+#pragma pack(1)
+
+//
+// NV data structure definition
+//
+typedef struct {
+ UINT32 DDRSpeedSel;
+ UINT32 EccMode;
+ UINT32 ErrCtrl_DE;
+ UINT32 ErrCtrl_FI;
+ UINT32 Slave32bit;
+ UINT32 ScrubPatrol;
+ UINT32 DemandScrub;
+ UINT32 WriteCrc;
+ UINT32 FGRMode;
+ UINT32 Refresh2x;
+ UINT32 NvdimmModeSel;
+} MEM_INFO_VARSTORE_DATA;
+
+//
+// Labels definition
+//
+#define LABEL_UPDATE 0x2223
+#define LABEL_END 0x2224
+
+#pragma pack()
+
+#endif
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenVfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenVfr.vfr
new file mode 100644
index 000000000000..e3d7aa0c44bd
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenVfr.vfr
@@ -0,0 +1,62 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Guid/PlatformManagerHii.h>
+#include "MemInfoScreenNVDataStruct.h"
+
+formset
+ guid = MEM_INFO_FORM_SET_GUID,
+ title = STRING_TOKEN(STR_MEM_INFO_FORM),
+ help = STRING_TOKEN(STR_MEM_INFO_FORM_HELP),
+ classguid = gPlatformManagerFormsetGuid,
+
+ //
+ // Define a variable Storage
+ //
+ varstore MEM_INFO_VARSTORE_DATA,
+ varid = MEM_INFO_VARSTORE_ID,
+ name = MemInfoIfrNVData,
+ guid = MEM_INFO_FORM_SET_GUID;
+
+ form
+ formid = MEM_INFO_FORM_ID,
+ title = STRING_TOKEN(STR_MEM_INFO_FORM);
+
+ subtitle text = STRING_TOKEN(STR_MEM_INFO_FORM);
+
+ label LABEL_UPDATE;
+ // dynamic content here
+ label LABEL_END;
+
+ endform;
+
+ form
+ formid = MEM_INFO_FORM_PERFORMANCE_ID,
+ title = STRING_TOKEN(STR_MEM_INFO_PERFORMANCE_FORM);
+
+ subtitle text = STRING_TOKEN(STR_MEM_INFO_PERFORMANCE_FORM);
+
+ label LABEL_UPDATE;
+ // dynamic content here
+ label LABEL_END;
+
+ endform;
+
+ form
+ formid = MEM_INFO_FORM_NVDIMM_ID,
+ title = STRING_TOKEN(STR_MEM_INFO_NVDIMM_FORM);
+
+ subtitle text = STRING_TOKEN(STR_MEM_INFO_NVDIMM_FORM);
+
+ label LABEL_UPDATE;
+ // dynamic content here
+ label LABEL_END;
+
+ endform;
+
+endformset;
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c
new file mode 100644
index 000000000000..c83f489f4078
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c
@@ -0,0 +1,394 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/NVParamLib.h>
+
+#include "MemInfoScreen.h"
+#include "NVParamDef.h"
+
+#define DDR_NVPARAM_ERRCTRL_DE_FIELD_SHIFT 0
+#define DDR_NVPARAM_ERRCTRL_DE_FIELD_MASK 0x1
+
+#define DDR_NVPARAM_ERRCTRL_FI_FIELD_SHIFT 1
+#define DDR_NVPARAM_ERRCTRL_FI_FIELD_MASK 0x2
+
+/**
+ This is function collects meminfo from NVParam
+
+ @param Data The buffer to return the contents.
+
+ @retval EFI_SUCCESS Get response data successfully.
+ @retval Other value Failed to get meminfo from NVParam
+**/
+EFI_STATUS
+MemInfoNvparamGet (
+ OUT MEM_INFO_VARSTORE_DATA *VarStoreConfig
+ )
+{
+ UINT32 Value;
+ EFI_STATUS Status;
+
+ ASSERT (VarStoreConfig != NULL);
+
+ Status = NVParamGet (
+ NV_SI_DDR_SPEED,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->DDRSpeedSel = 0; /* Default auto mode */
+ } else {
+ VarStoreConfig->DDRSpeedSel = Value;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_ECC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->EccMode = ECC_SECDED; /* Default enable */
+ } else {
+ VarStoreConfig->EccMode = Value;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_ERRCTRL,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->ErrCtrl_DE = ERRCTLR_DE_ENABLE;
+ VarStoreConfig->ErrCtrl_FI = ERRCTLR_FI_ENABLE;
+ } else {
+ VarStoreConfig->ErrCtrl_DE = (Value & DDR_NVPARAM_ERRCTRL_DE_FIELD_MASK) >> DDR_NVPARAM_ERRCTRL_DE_FIELD_SHIFT;
+ VarStoreConfig->ErrCtrl_FI = (Value & DDR_NVPARAM_ERRCTRL_FI_FIELD_MASK) >> DDR_NVPARAM_ERRCTRL_FI_FIELD_SHIFT;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_SLAVE_32BIT_MEM_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->Slave32bit = 0; /* Default disabled */
+ } else {
+ VarStoreConfig->Slave32bit = Value;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_SCRUB_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->ScrubPatrol = DDR_DEFAULT_SCRUB_PATROL_DURATION;
+ } else {
+ VarStoreConfig->ScrubPatrol = Value;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_WR_BACK_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->DemandScrub = DDR_DEFAULT_DEMAND_SCRUB;
+ } else {
+ VarStoreConfig->DemandScrub = Value;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_CRC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->WriteCrc = DDR_DEFAULT_WRITE_CRC;
+ } else {
+ VarStoreConfig->WriteCrc = Value;
+ }
+
+ Status = NVParamGet (
+ NV_SI_DDR_REFRESH_GRANULARITY,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->FGRMode = DDR_DEFAULT_FGR_MODE;
+ VarStoreConfig->Refresh2x = DDR_DEFAULT_REFRESH2X_MODE;
+ } else {
+ VarStoreConfig->FGRMode = DDR_FGR_MODE_GET (Value);
+ VarStoreConfig->Refresh2x = DDR_REFRESH_2X_GET (Value);
+ }
+
+ Status = NVParamGet (
+ NV_SI_NVDIMM_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->NvdimmModeSel = DDR_DEFAULT_NVDIMM_MODE_SEL;
+ } else {
+ VarStoreConfig->NvdimmModeSel = Value & DDR_NVDIMM_MODE_SEL_MASK; /* Mask out valid bit */
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is function stores meminfo to corresponding NVParam
+
+ @param VarStoreConfig The contents for the variable.
+
+ @retval EFI_SUCCESS Set data successfully.
+ @retval Other value Failed to set meminfo to NVParam
+
+**/
+EFI_STATUS
+MemInfoNvparamSet (
+ IN MEM_INFO_VARSTORE_DATA *VarStoreConfig
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Value, TmpValue, Value2, Update;
+
+ ASSERT (VarStoreConfig != NULL);
+
+ /* Set DDR speed */
+ Status = NVParamGet (
+ NV_SI_DDR_SPEED,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != VarStoreConfig->DDRSpeedSel) {
+ Status = NVParamSet (
+ NV_SI_DDR_SPEED,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ VarStoreConfig->DDRSpeedSel
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Set ECC mode */
+ Status = NVParamGet (
+ NV_SI_DDR_ECC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != VarStoreConfig->EccMode) {
+ Status = NVParamSet (
+ NV_SI_DDR_ECC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ VarStoreConfig->EccMode
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Set ErrCtrl */
+ TmpValue = (VarStoreConfig->ErrCtrl_DE << DDR_NVPARAM_ERRCTRL_DE_FIELD_SHIFT) |
+ (VarStoreConfig->ErrCtrl_FI << DDR_NVPARAM_ERRCTRL_FI_FIELD_SHIFT);
+ Status = NVParamGet (
+ NV_SI_DDR_ERRCTRL,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != TmpValue ) {
+ Status = NVParamSet (
+ NV_SI_DDR_ERRCTRL,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ TmpValue
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Set slave's 32bit region */
+ TmpValue = VarStoreConfig->Slave32bit;
+ Status = NVParamGet (
+ NV_SI_DDR_SLAVE_32BIT_MEM_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != TmpValue ) {
+ if (TmpValue == 0) {
+ /* Default is disabled so just clear nvparam */
+ Status = NVParamClr (
+ NV_SI_DDR_SLAVE_32BIT_MEM_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC
+ );
+ } else {
+ Status = NVParamSet (
+ NV_SI_DDR_SLAVE_32BIT_MEM_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ TmpValue
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Set Scrub patrol */
+ TmpValue = VarStoreConfig->ScrubPatrol;
+ Status = NVParamGet (
+ NV_SI_DDR_SCRUB_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != TmpValue ) {
+ if (TmpValue == DDR_DEFAULT_SCRUB_PATROL_DURATION) {
+ Status = NVParamClr (
+ NV_SI_DDR_SCRUB_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC
+ );
+ } else {
+ Status = NVParamSet (
+ NV_SI_DDR_SCRUB_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ TmpValue
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Demand Scrub */
+ TmpValue = VarStoreConfig->DemandScrub;
+ Status = NVParamGet (
+ NV_SI_DDR_WR_BACK_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != TmpValue ) {
+ if (TmpValue == DDR_DEFAULT_DEMAND_SCRUB) {
+ Status = NVParamClr (
+ NV_SI_DDR_WR_BACK_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC
+ );
+ } else {
+ Status = NVParamSet (
+ NV_SI_DDR_WR_BACK_EN,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ TmpValue
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Write CRC */
+ TmpValue = VarStoreConfig->WriteCrc;
+ Status = NVParamGet (
+ NV_SI_DDR_CRC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status) || Value != TmpValue ) {
+ if (TmpValue == DDR_DEFAULT_WRITE_CRC) {
+ Status = NVParamClr (
+ NV_SI_DDR_CRC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC
+ );
+ } else {
+ Status = NVParamSet (
+ NV_SI_DDR_CRC_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ TmpValue
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Write FGR/Refresh2X */
+ Value = 0;
+ Update = 0;
+ TmpValue = VarStoreConfig->FGRMode;
+ Status = NVParamGet (
+ NV_SI_DDR_REFRESH_GRANULARITY,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ Value2 = DDR_FGR_MODE_GET (Value);
+ if ((EFI_ERROR (Status) && TmpValue != DDR_DEFAULT_FGR_MODE)
+ || Value2 != TmpValue)
+ {
+ DDR_FGR_MODE_SET (Value, TmpValue);
+ Update = 1;
+ }
+
+ Value2 = DDR_REFRESH_2X_GET (Value);
+ TmpValue = VarStoreConfig->Refresh2x;
+ if ((EFI_ERROR (Status) && TmpValue != DDR_DEFAULT_REFRESH2X_MODE)
+ || Value2 != TmpValue)
+ {
+ DDR_REFRESH_2X_SET (Value, TmpValue);
+ Update = 1;
+ }
+
+ if (Update == 1) {
+ Status = NVParamSet (
+ NV_SI_DDR_REFRESH_GRANULARITY,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ Value
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ /* Write NVDIMM-N Mode selection */
+ Value = 0;
+ TmpValue = VarStoreConfig->NvdimmModeSel;
+ Status = NVParamGet (
+ NV_SI_NVDIMM_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ Value2 = Value & DDR_NVDIMM_MODE_SEL_MASK; /* Mask out valid bit */
+ if (EFI_ERROR (Status) || Value2 != TmpValue ) {
+ if (TmpValue == DDR_DEFAULT_NVDIMM_MODE_SEL) {
+ Status = NVParamClr (
+ NV_SI_NVDIMM_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC
+ );
+ } else {
+ Value = TmpValue | DDR_NVDIMM_MODE_SEL_VALID_BIT; /* Add valid bit */
+ Status = NVParamSet (
+ NV_SI_NVDIMM_MODE,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ Value
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c
new file mode 100644
index 000000000000..3a1a5840db9d
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c
@@ -0,0 +1,1325 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MemInfoScreen.h"
+
+#define MAX_STRING_SIZE 64
+#define GB_SCALE_FACTOR (1024*1024*1024)
+#define MB_SCALE_FACTOR (1024*1024)
+
+EFI_GUID gMemInfoFormSetGuid = MEM_INFO_FORM_SET_GUID;
+
+HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ MEM_INFO_FORM_SET_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8)(END_DEVICE_PATH_LENGTH),
+ (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+EFI_HANDLE DriverHandle = NULL;
+MEM_INFO_SCREEN_PRIVATE_DATA *mPrivateData = NULL;
+
+/**
+ This function allows a caller to extract the current configuration for one
+ or more named elements from the target driver.
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Request A null-terminated Unicode string in
+ <ConfigRequest> format.
+ @param Progress On return, points to a character in the Request
+ string. Points to the string's null terminator if
+ request was successful. Points to the most recent
+ '&' before the first failing name/value pair (or
+ the beginning of the string if the failure is in
+ the first name/value pair) if the request was not
+ successful.
+ @param Results A null-terminated Unicode string in
+ <ConfigAltResp> format which has all values filled
+ in for the names in the Request string. String to
+ be allocated by the called function.
+ @retval EFI_SUCCESS The Results is filled with the requested values.
+ @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
+ driver.
+**/
+EFI_STATUS
+EFIAPI
+ExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+ EFI_STRING ConfigRequest;
+ EFI_STRING ConfigRequestHdr;
+ UINTN Size;
+ CHAR16 *StrPointer;
+ BOOLEAN AllocatedRequest;
+
+ if (Progress == NULL || Results == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Initialize the local variables.
+ //
+ ConfigRequestHdr = NULL;
+ ConfigRequest = NULL;
+ Size = 0;
+ *Progress = Request;
+ AllocatedRequest = FALSE;
+
+ PrivateData = MEM_INFO_SCREEN_PRIVATE_FROM_THIS (This);
+ HiiConfigRouting = PrivateData->HiiConfigRouting;
+
+ //
+ // Get Buffer Storage data from EFI variable.
+ // Try to get the current setting from variable.
+ //
+ BufferSize = sizeof (MEM_INFO_VARSTORE_DATA);
+ Status = MemInfoNvparamGet (&PrivateData->VarStoreConfig);
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (Request == NULL) {
+ //
+ // Request is set to NULL, construct full request string.
+ //
+
+ //
+ // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+ // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
+ //
+ ConfigRequestHdr = HiiConstructConfigHdr (&gMemInfoFormSetGuid, MEM_INFO_VARSTORE_NAME, PrivateData->DriverHandle);
+ Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+ ConfigRequest = AllocateZeroPool (Size);
+ ASSERT (ConfigRequest != NULL);
+ AllocatedRequest = TRUE;
+ UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+ FreePool (ConfigRequestHdr);
+ ConfigRequestHdr = NULL;
+ } else {
+ //
+ // Check routing data in <ConfigHdr>.
+ // Note: if only one Storage is used, then this checking could be skipped.
+ //
+ if (!HiiIsConfigHdrMatch (Request, &gMemInfoFormSetGuid, NULL)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Set Request to the unified request string.
+ //
+ ConfigRequest = Request;
+
+ //
+ // Check whether Request includes Request Element.
+ //
+ if (StrStr (Request, L"OFFSET") == NULL) {
+ //
+ // Check Request Element does exist in Request String
+ //
+ StrPointer = StrStr (Request, L"PATH");
+ if (StrPointer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (StrStr (StrPointer, L"&") == NULL) {
+ Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
+ ConfigRequest = AllocateZeroPool (Size);
+ ASSERT (ConfigRequest != NULL);
+ AllocatedRequest = TRUE;
+ UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize);
+ }
+ }
+ }
+
+ //
+ // Check if requesting Name/Value storage
+ //
+ if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
+ //
+ // Don't have any Name/Value storage names
+ //
+ Status = EFI_SUCCESS;
+ } else {
+ //
+ // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+ //
+ Status = HiiConfigRouting->BlockToConfig (
+ HiiConfigRouting,
+ ConfigRequest,
+ (UINT8 *)&PrivateData->VarStoreConfig,
+ BufferSize,
+ Results,
+ Progress
+ );
+ }
+
+ //
+ // Free the allocated config request string.
+ //
+ if (AllocatedRequest) {
+ FreePool (ConfigRequest);
+ }
+
+ if (ConfigRequestHdr != NULL) {
+ FreePool (ConfigRequestHdr);
+ }
+ //
+ // Set Progress string to the original request string.
+ //
+ if (Request == NULL) {
+ *Progress = NULL;
+ } else if (StrStr (Request, L"OFFSET") == NULL) {
+ *Progress = Request + StrLen (Request);
+ }
+
+ return Status;
+}
+
+/**
+ This function processes the results of changes in configuration.
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Configuration A null-terminated Unicode string in <ConfigResp>
+ format.
+ @param Progress A pointer to a string filled in with the offset of
+ the most recent '&' before the first failing
+ name/value pair (or the beginning of the string if
+ the failure is in the first name/value pair) or
+ the terminating NULL if all was successful.
+ @retval EFI_SUCCESS The Results is processed successfully.
+ @retval EFI_INVALID_PARAMETER Configuration is NULL.
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
+ driver.
+**/
+EFI_STATUS
+EFIAPI
+RouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+ if (Configuration == NULL || Progress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = MEM_INFO_SCREEN_PRIVATE_FROM_THIS (This);
+ HiiConfigRouting = PrivateData->HiiConfigRouting;
+ *Progress = Configuration;
+
+ //
+ // Check routing data in <ConfigHdr>.
+ // Note: if only one Storage is used, then this checking could be skipped.
+ //
+ if (!HiiIsConfigHdrMatch (Configuration, &gMemInfoFormSetGuid, NULL)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Get Buffer Storage data from NVParam
+ //
+ Status = MemInfoNvparamGet (&PrivateData->VarStoreConfig);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Check if configuring Name/Value storage
+ //
+ if (StrStr (Configuration, L"OFFSET") == NULL) {
+ //
+ // Don't have any Name/Value storage names
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
+ //
+ BufferSize = sizeof (MEM_INFO_VARSTORE_DATA);
+ Status = HiiConfigRouting->ConfigToBlock (
+ HiiConfigRouting,
+ Configuration,
+ (UINT8 *)&PrivateData->VarStoreConfig,
+ &BufferSize,
+ Progress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Store Buffer Storage back to NVParam
+ //
+ Status = MemInfoNvparamSet (&PrivateData->VarStoreConfig);
+
+ return Status;
+}
+
+/**
+ This function processes the results of changes in configuration.
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Action Specifies the type of action taken by the browser.
+ @param QuestionId A unique value which is sent to the original
+ exporting driver so that it can identify the type
+ of data to expect.
+ @param Type The type of value for the question.
+ @param Value A pointer to the data being sent to the original
+ exporting driver.
+ @param ActionRequest On return, points to the action requested by the
+ callback function.
+ @retval EFI_SUCCESS The callback successfully handled the action.
+ @retval EFI_INVALID_PARAMETER Configuration is NULL.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the
+ callback.
+**/
+EFI_STATUS
+EFIAPI
+DriverCallback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ )
+{
+ if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN)
+ && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))
+ || (ActionRequest == NULL))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (Action) {
+ case EFI_BROWSER_ACTION_FORM_OPEN:
+ case EFI_BROWSER_ACTION_FORM_CLOSE:
+ break;
+
+ case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
+ case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
+ {
+ switch (QuestionId) {
+ case MEM_INFO_DDR_SPEED_SEL_QUESTION_ID:
+ //
+ // DDR speed selection default to auto
+ //
+ Value->u32 = 0;
+ break;
+
+ case MEM_INFO_FORM_PERFORMANCE_ECC_QUESTION_ID:
+ //
+ // ECC mode default to be enabled
+ //
+ Value->u32 = ECC_SECDED;
+ break;
+
+ case MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_DE_QUESTION_ID:
+ //
+ // ErrCtrl_DE default to be enabled
+ //
+ Value->u32 = ERRCTLR_DE_ENABLE;
+ break;
+
+ case MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_FI_QUESTION_ID:
+ //
+ // ErrCtrl_FI default to be enabled
+ //
+ Value->u32 = ERRCTLR_FI_ENABLE;
+ break;
+
+ case MEM_INFO_DDR_SLAVE_32BIT_QUESTION_ID:
+ //
+ // Slave's 32bit region to be disabled
+ //
+ Value->u32 = 0;
+ break;
+
+ case MEM_INFO_DDR_SCRUB_PATROL_QUESTION_ID:
+ Value->u32 = DDR_DEFAULT_SCRUB_PATROL_DURATION;
+ break;
+
+ case MEM_INFO_DDR_DEMAND_SCRUB_QUESTION_ID:
+ Value->u32 = DDR_DEFAULT_DEMAND_SCRUB;
+ break;
+
+ case MEM_INFO_DDR_WRITE_CRC_QUESTION_ID:
+ Value->u32 = DDR_DEFAULT_WRITE_CRC;
+ break;
+
+ case MEM_INFO_FGR_MODE_QUESTION_ID:
+ Value->u32 = DDR_DEFAULT_FGR_MODE;
+ break;
+
+ case MEM_INFO_REFRESH2X_MODE_QUESTION_ID:
+ Value->u32 = DDR_DEFAULT_REFRESH2X_MODE;
+ break;
+
+ case MEM_INFO_FORM_NVDIMM_MODE_SEL_QUESTION_ID:
+ Value->u32 = DDR_DEFAULT_NVDIMM_MODE_SEL;
+ break;
+ }
+ }
+ break;
+
+ case EFI_BROWSER_ACTION_RETRIEVE:
+ case EFI_BROWSER_ACTION_CHANGING:
+ case EFI_BROWSER_ACTION_SUBMITTED:
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MemInfoMainScreen (
+ PLATFORM_INFO_HOB *PlatformHob
+ )
+{
+ MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData = mPrivateData;
+ EFI_STATUS Status;
+ VOID *StartOpCodeHandle;
+ VOID *OptionsOpCodeHandle;
+ VOID *OptionsOpCodeHandle1;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ EFI_STRING_ID StringId;
+ VOID *EndOpCodeHandle;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ CHAR16 Str[MAX_STRING_SIZE], Str1[MAX_STRING_SIZE];
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;
+ PLATFORM_DIMM_INFO *DimmInfo;
+ UINT64 Size;
+ UINTN Count;
A lot of variables for a single function.

/
Leif

+
+ //
+ // Get Buffer Storage data from EFI variable
+ //
+ Status = MemInfoNvparamGet (&PrivateData->VarStoreConfig);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = EFI_SUCCESS;
+
+ /* Update Total memory */
+ UnicodeSPrint (Str, sizeof (Str), L"%d GB", PlatformHob->DramInfo.TotalSize / GB_SCALE_FACTOR);
+ HiiSetString (
+ PrivateData->HiiHandle,
+ STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM_VALUE),
+ Str,
+ NULL
+ );
+
+ /* Update effective memory */
+ Size = 0;
+ ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+ while (ResHob != NULL) {
+ if ((ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)) {
+ Size += ResHob->ResourceLength;
+ }
+ ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
+ }
+ UnicodeSPrint (Str, sizeof (Str), L"%d GB", Size / GB_SCALE_FACTOR);
+ HiiSetString (
+ PrivateData->HiiHandle,
+ STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM_VALUE),
+ Str,
+ NULL
+ );
+
+ /* Update current DDR speed */
+ UnicodeSPrint (Str, sizeof (Str), L"%d MHz", PlatformHob->DramInfo.MaxSpeed);
+ HiiSetString (
+ PrivateData->HiiHandle,
+ STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED_VALUE),
+ Str,
+ NULL
+ );
+
+ //
+ // Initialize the container for dynamic opcodes
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (StartOpCodeHandle != NULL);
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (EndOpCodeHandle != NULL);
+
+ //
+ // Create Option OpCode to display speed configuration
+ //
+ OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (OptionsOpCodeHandle != NULL);
+
+ //
+ // Create Option OpCode to display FGR mode configuration
+ //
+ OptionsOpCodeHandle1 = HiiAllocateOpCodeHandle ();
+ ASSERT (OptionsOpCodeHandle1 != NULL);
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LABEL_UPDATE;
+
+ //
+ // Create Hii Extend Label OpCode as the end opcode
+ //
+ EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ //
+ // Create a total mem title
+ //
+ HiiCreateTextOpCode (
+ StartOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM),
+ STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM),
+ STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM_VALUE)
+ );
+
+ //
+ // Create a effective mem title
+ //
+ HiiCreateTextOpCode (
+ StartOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM),
+ STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM),
+ STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM_VALUE)
+ );
+
+ //
+ // Create a current speed title
+ //
+ HiiCreateTextOpCode (
+ StartOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED),
+ STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED),
+ STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED_VALUE)
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE0),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 0
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE1),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2133
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE2),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2400
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE3),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2666
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE4),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2933
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE5),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 3200
+ );
+
+ HiiCreateOneOfOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_DDR_SPEED_SEL_QUESTION_ID, // Question ID (or call it "key")
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_DDR_SPEED_SEL_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+ EFI_IFR_NUMERIC_SIZE_4, // Data type of Question Value
+ OptionsOpCodeHandle, // Option Opcode list
+ NULL // Default Opcode is NULl
+ );
+
+ if (IsSlaveSocketActive ()) {
+ /* Display enable slave's 32bit region */
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_DDR_SLAVE_32BIT_QUESTION_ID, // Question ID
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_ERR_SLAVE_32BIT_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_32GB_SLAVE_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_32GB_SLAVE_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+ 0,
+ NULL
+ );
+ }
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle1,
+ STRING_TOKEN (STR_MEM_INFO_FGR_MODE_VALUE0),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 0
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle1,
+ STRING_TOKEN (STR_MEM_INFO_FGR_MODE_VALUE1),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 1
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle1,
+ STRING_TOKEN (STR_MEM_INFO_FGR_MODE_VALUE2),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2
+ );
+
+ HiiCreateOneOfOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FGR_MODE_QUESTION_ID, // Question ID (or call it "key")
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_FGR_MODE_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_FGR_MODE_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_FGR_MODE_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+ EFI_IFR_NUMERIC_SIZE_4, // Data type of Question Value
+ OptionsOpCodeHandle1, // Option Opcode list
+ NULL // Default Opcode is NULl
+ );
+
+ //
+ // Create a Goto OpCode to ras memory configuration
+ //
+ HiiCreateGotoOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FORM_PERFORMANCE_ID, // Target Form ID
+ STRING_TOKEN (STR_MEM_INFO_PERFORMANCE_FORM), // Prompt text
+ STRING_TOKEN (STR_MEM_INFO_PERFORMANCE_FORM_HELP), // Help text
+ 0, // Question flag
+ MEM_INFO_FORM_PERFORMANCE_QUESTION_ID // Question ID
+ );
+
+ //
+ // Create a Goto OpCode to nvdimm-n configuration
+ //
+ HiiCreateGotoOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FORM_NVDIMM_ID, // Target Form ID
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_FORM), // Prompt text
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_FORM_HELP), // Help text
+ 0, // Question flag
+ MEM_INFO_FORM_NVDIMM_QUESTION_ID // Question ID
+ );
+
+ //
+ // Display DIMM list info
+ //
+ HiiCreateSubTitleOpCode (
+ StartOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_DIMM_INFO),
+ 0,
+ 0,
+ 0
+ );
+
+ for (Count = 0; Count < PlatformHob->DimmList.BoardDimmSlots; Count++) {
+ DimmInfo = &PlatformHob->DimmList.Dimm[Count].Info;
+ switch (DimmInfo->DimmType) {
+ case UDIMM:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"UDIMM");
+ break;
+
+ case RDIMM:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"RDIMM");
+ break;
+
+ case SODIMM:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"SODIMM");
+ break;
+
+ case LRDIMM:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"LRDIMM");
+ break;
+
+ case RSODIMM:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"RSODIMM");
+ break;
+
+ case NVRDIMM:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"NV-RDIMM");
+ break;
+
+ default:
+ UnicodeSPrint (Str, sizeof (Str), L"Unknown Type");
+ }
+ if (DimmInfo->DimmStatus == DIMM_INSTALLED_OPERATIONAL) {
+ UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: %d GB %s Installed&Operational", Count + 1, DimmInfo->DimmSize, Str);
+ } else if (DimmInfo->DimmStatus == DIMM_NOT_INSTALLED) {
+ UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: Not Installed", Count + 1, PlatformHob->DimmList.Dimm[Count].NodeId);
+ } else if (DimmInfo->DimmStatus == DIMM_INSTALLED_NONOPERATIONAL) {
+ UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: Installed&Non-Operational", Count + 1, PlatformHob->DimmList.Dimm[Count].NodeId);
+ } else {
+ UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: Installed&Failed", Count + 1, PlatformHob->DimmList.Dimm[Count].NodeId);
+ }
+
+ StringId = HiiSetString (PrivateData->HiiHandle, 0, Str1, NULL);
+
+ HiiCreateSubTitleOpCode (
+ StartOpCodeHandle,
+ StringId,
+ 0,
+ 0,
+ 0
+ );
+ }
+
+ HiiUpdateForm (
+ PrivateData->HiiHandle, // HII handle
+ &gMemInfoFormSetGuid, // Formset GUID
+ MEM_INFO_FORM_ID, // Form ID
+ StartOpCodeHandle, // Label for where to insert opcodes
+ EndOpCodeHandle // Insert data
+ );
+
+ HiiFreeOpCodeHandle (StartOpCodeHandle);
+ HiiFreeOpCodeHandle (EndOpCodeHandle);
+ HiiFreeOpCodeHandle (OptionsOpCodeHandle);
+
+ return Status;
+}
+
+EFI_STATUS
+MemInfoMainPerformanceScreen (
+ PLATFORM_INFO_HOB *PlatformHob
+ )
+{
+ EFI_STATUS Status;
+ MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData = mPrivateData;
+ VOID *StartOpCodeHandle;
+ VOID *OptionsEccOpCodeHandle, *OptionsScrubOpCodeHandle;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ VOID *EndOpCodeHandle;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ EFI_STRING_ID StringId;
+ CHAR16 Str[MAX_STRING_SIZE];
+ UINTN Idx;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Initialize the container for dynamic opcodes
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (StartOpCodeHandle != NULL);
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (EndOpCodeHandle != NULL);
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LABEL_UPDATE;
+
+ //
+ // Create Hii Extend Label OpCode as the end opcode
+ //
+ EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ /* Display ECC mode selection */
+ OptionsEccOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (OptionsEccOpCodeHandle != NULL);
+
+ UnicodeSPrint (Str, sizeof (Str), L"Disabled");
+ StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsEccOpCodeHandle,
+ StringId,
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 0
+ );
+
+ UnicodeSPrint (Str, sizeof (Str), L"SECDED");
+ StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsEccOpCodeHandle,
+ StringId,
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 1
+ );
+
+ UnicodeSPrint (Str, sizeof (Str), L"Symbol");
+ StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsEccOpCodeHandle,
+ StringId,
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2
+ );
+
+ HiiCreateOneOfOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FORM_PERFORMANCE_ECC_QUESTION_ID, // Question ID (or call it "key")
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_ECC_MODE_SEL_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_ECC_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_ECC_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+ EFI_IFR_NUMERIC_SIZE_4, // Data type of Question Value
+ OptionsEccOpCodeHandle, // Option Opcode list
+ NULL // Default Opcode is NULl
+ );
+
+ /*
+ * Display ErrCtrl options
+ */
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_DE_QUESTION_ID, // Question ID
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_ERR_CTRL_DE_MODE_SEL_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_DE_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_DE_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+ 0,
+ NULL
+ );
+
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_FI_QUESTION_ID, // Question ID
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_ERR_CTRL_FI_MODE_SEL_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_FI_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_FI_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+ 0,
+ NULL
+ );
+
+ /* Display Scrub Patrol selection */
+ OptionsScrubOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (OptionsScrubOpCodeHandle != NULL);
+
+ UnicodeSPrint (Str, sizeof (Str), L"Disabled");
+ StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsScrubOpCodeHandle,
+ StringId,
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 0
+ );
+
+ for (Idx = 1; Idx <= MAX_NUMBER_OF_HOURS_IN_A_DAY; Idx++) {
+ UnicodeSPrint (Str, sizeof (Str), L"%d", Idx);
+ StringId = HiiSetString (
+ PrivateData->HiiHandle,
+ 0,
+ Str,
+ NULL
+ );
+ HiiCreateOneOfOptionOpCode (
+ OptionsScrubOpCodeHandle,
+ StringId,
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ Idx
+ );
+ }
+
+ HiiCreateOneOfOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_DDR_SCRUB_PATROL_QUESTION_ID, // Question ID (or call it "key")
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_DDR_SCRUB_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_SCRUB), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_SCRUB_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+ EFI_IFR_NUMERIC_SIZE_4, // Data type of Question Value
+ OptionsScrubOpCodeHandle, // Option Opcode list
+ NULL // Default Opcode is NULl
+ );
+
+ /*
+ * Display Demand Scrub options
+ */
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_DDR_DEMAND_SCRUB_QUESTION_ID, // Question ID
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_DDR_DEMAND_SCRUB_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_DEMAND_SCRUB_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_DEMAND_SCRUB_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+ 0,
+ NULL
+ );
+
+ /*
+ * Display Write CRC options
+ */
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_DDR_WRITE_CRC_QUESTION_ID, // Question ID
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_DDR_WRITE_CRC_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_WRITE_CRC_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_ENABLE_WRITE_CRC_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+ 0,
+ NULL
+ );
+
+ /*
+ * Display CVE-2020-10255 options
+ */
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_REFRESH2X_MODE_QUESTION_ID, // Question ID
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_REFRESH2X_MODE_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_REFRESH2X_MODE_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_REFRESH2X_MODE_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+ 0,
+ NULL
+ );
+
+ HiiUpdateForm (
+ PrivateData->HiiHandle, // HII handle
+ &gMemInfoFormSetGuid, // Formset GUID
+ MEM_INFO_FORM_PERFORMANCE_ID, // Form ID
+ StartOpCodeHandle, // Label for where to insert opcodes
+ EndOpCodeHandle // Insert data
+ );
+
+ HiiFreeOpCodeHandle (StartOpCodeHandle);
+ HiiFreeOpCodeHandle (EndOpCodeHandle);
+ HiiFreeOpCodeHandle (OptionsEccOpCodeHandle);
+ HiiFreeOpCodeHandle (OptionsScrubOpCodeHandle);
+
+ return Status;
+}
+
+EFI_STATUS
+MemInfoMainNvdimmScreen (
+ PLATFORM_INFO_HOB *PlatformHob
+ )
+{
+ EFI_STATUS Status;
+ MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData;
+ VOID *StartOpCodeHandle;
+ VOID *OptionsOpCodeHandle;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ VOID *EndOpCodeHandle;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ CHAR16 Str[MAX_STRING_SIZE];
+
+ Status = EFI_SUCCESS;
+ PrivateData = mPrivateData;
+
+ if (PlatformHob == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Initialize the container for dynamic opcodes
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (StartOpCodeHandle != NULL);
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (EndOpCodeHandle != NULL);
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ StartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LABEL_UPDATE;
+
+ //
+ // Create Hii Extend Label OpCode as the end opcode
+ //
+ EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+ EndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ //
+ // Update Current NVDIMM-N Mode title Socket0
+ //
+ switch (PlatformHob->DramInfo.NvdimmMode[0]) {
+ case 0:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-NVDIMM");
+ break;
+
+ case 1:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-Hashed");
+ break;
+
+ case 2:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Hashed");
+ break;
+
+ default:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Unknown");
+ break;
+ }
+
+ HiiSetString (
+ PrivateData->HiiHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0_VALUE),
+ Str,
+ NULL
+ );
+
+ HiiCreateTextOpCode (
+ StartOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0),
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0),
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0_VALUE)
+ );
+
+ //
+ // Update Current NVDIMM-N Mode title Socket1
+ //
+ if (IsSlaveSocketActive ()) {
+ switch (PlatformHob->DramInfo.NvdimmMode[1]) {
+ case 0:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-NVDIMM");
+ break;
+
+ case 1:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-Hashed");
+ break;
+
+ case 2:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Hashed");
+ break;
+
+ default:
+ UnicodeSPrint (Str, sizeof (Str), L"%s", L"Unknown");
+ break;
+ }
+
+ HiiSetString (
+ PrivateData->HiiHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1_VALUE),
+ Str,
+ NULL
+ );
+
+ HiiCreateTextOpCode (
+ StartOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1),
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1),
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1_VALUE)
+ );
+ }
+ //
+ // Create Option OpCode to NVDIMM-N Mode Selection
+ //
+ OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
+ ASSERT (OptionsOpCodeHandle != NULL);
+
+ //
+ // Create OpCode to NVDIMM-N Mode Selection
+ //
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE0),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 0
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE1),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 1
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE2),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 2
+ );
+
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE3),
+ 0,
+ EFI_IFR_NUMERIC_SIZE_4,
+ 3
+ );
+
+ HiiCreateOneOfOpCode (
+ StartOpCodeHandle, // Container for dynamic created opcodes
+ MEM_INFO_FORM_NVDIMM_MODE_SEL_QUESTION_ID, // Question ID (or call it "key")
+ MEM_INFO_VARSTORE_ID, // VarStore ID
+ (UINT16)MEM_INFO_NVDIMM_MODE_SEL_OFFSET, // Offset in Buffer Storage
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_PROMPT), // Question prompt text
+ STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_HELP), // Question help text
+ EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+ EFI_IFR_NUMERIC_SIZE_4, // Data type of Question Value
+ OptionsOpCodeHandle, // Option Opcode list
+ NULL // Default Opcode is NULl
+ );
+
+ HiiUpdateForm (
+ PrivateData->HiiHandle, // HII handle
+ &gMemInfoFormSetGuid, // Formset GUID
+ MEM_INFO_FORM_NVDIMM_ID, // Form ID
+ StartOpCodeHandle, // Label for where to insert opcodes
+ EndOpCodeHandle // Insert data
+ );
+
+ HiiFreeOpCodeHandle (StartOpCodeHandle);
+ HiiFreeOpCodeHandle (EndOpCodeHandle);
+ HiiFreeOpCodeHandle (OptionsOpCodeHandle);
+
+ return Status;
+}
+
+/**
+ This function sets up the first elements of the form.
+ @param PrivateData Private data.
+ @retval EFI_SUCCESS The form is set up successfully.
+**/
+EFI_STATUS
+MemInfoScreenSetup (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ VOID *Hob;
+ PLATFORM_INFO_HOB *PlatformHob;
+
+ /* Get the Platform HOB */
+ Hob = GetFirstGuidHob (&gPlatformHobGuid);
+ if (Hob == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+ PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+ Status = MemInfoMainScreen (PlatformHob);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = MemInfoMainPerformanceScreen (PlatformHob);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = MemInfoMainNvdimmScreen (PlatformHob);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MemInfoScreenInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+ BOOLEAN ActionFlag;
+ EFI_STRING ConfigRequestHdr;
+
+ //
+ // Initialize driver private data
+ //
+ mPrivateData = AllocateZeroPool (sizeof (MEM_INFO_SCREEN_PRIVATE_DATA));
+ if (mPrivateData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mPrivateData->Signature = MEM_INFO_SCREEN_PRIVATE_DATA_SIGNATURE;
+
+ mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
+ mPrivateData->ConfigAccess.RouteConfig = RouteConfig;
+ mPrivateData->ConfigAccess.Callback = DriverCallback;
+
+ //
+ // Locate ConfigRouting protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ mPrivateData->HiiConfigRouting = HiiConfigRouting;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &mPrivateData->ConfigAccess,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ mPrivateData->DriverHandle = DriverHandle;
+
+ //
+ // Publish our HII data
+ //
+ HiiHandle = HiiAddPackages (
+ &gMemInfoFormSetGuid,
+ DriverHandle,
+ MemInfoDxeStrings,
+ MemInfoScreenVfrBin,
+ NULL
+ );
+ if (HiiHandle == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mPrivateData->HiiHandle = HiiHandle;
+
+ //
+ // Try to read NV config EFI variable first
+ //
+ ConfigRequestHdr = HiiConstructConfigHdr (
+ &gMemInfoFormSetGuid,
+ MEM_INFO_VARSTORE_NAME,
+ DriverHandle
+ );
+ ASSERT (ConfigRequestHdr != NULL);
+
+ //
+ // Validate Current Setting
+ //
+ ActionFlag = HiiValidateSettings (ConfigRequestHdr);
+ if (!ActionFlag) {
+ MemInfoScreenUnload (ImageHandle);
+ return EFI_INVALID_PARAMETER;
+ }
+ FreePool (ConfigRequestHdr);
+
+ Status = MemInfoScreenSetup ();
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MemInfoScreenUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ ASSERT (mPrivateData != NULL);
+
+ if (DriverHandle != NULL) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &mPrivateData->ConfigAccess,
+ NULL
+ );
+ DriverHandle = NULL;
+ }
+
+ if (mPrivateData->HiiHandle != NULL) {
+ HiiRemovePackages (mPrivateData->HiiHandle);
+ }
+
+ FreePool (mPrivateData);
+ mPrivateData = NULL;
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni
new file mode 100644
index 000000000000..a8c7cb99d6a7
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni
@@ -0,0 +1,9 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#string STR_MODULE_ABSTRACT #language en-US "An Altra DDR screen setup driver"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This driver exposes a screen setup for DDR information and configuration."
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni
new file mode 100644
index 000000000000..f44f210594be
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni
@@ -0,0 +1,9 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Ampere Altra MemInfo DXE Driver"
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni
new file mode 100644
index 000000000000..d170f9ee7313
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni
@@ -0,0 +1,64 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#langdef en-US "English" // English
+
+#string STR_MEM_INFO_FORM #language en-US "Memory Configuration"
+#string STR_MEM_INFO_FORM_HELP #language en-US "Memory Configuration"
+#string STR_MEM_INFO_TOTAL_MEM #language en-US "Total Memory"
+#string STR_MEM_INFO_TOTAL_MEM_VALUE #language en-US "0 GB"
+#string STR_MEM_INFO_EFFECT_MEM #language en-US "Effective Memory"
+#string STR_MEM_INFO_EFFECT_MEM_VALUE #language en-US "0 MB"
+#string STR_MEM_INFO_CURRENT_SPEED #language en-US "Memory Speed"
+#string STR_MEM_INFO_CURRENT_SPEED_VALUE #language en-US "0 MHz"
+#string STR_MEM_INFO_SPEED_SELECT_PROMPT #language en-US "Memory Operating Speed Selection"
+#string STR_MEM_INFO_SPEED_SELECT_HELP #language en-US "Force specific Memory Operating Speed or use Auto setting."
+#string STR_MEM_INFO_SPEED_SELECT_VALUE0 #language en-US "Auto"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE1 #language en-US "2133"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE2 #language en-US "2400"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE3 #language en-US "2666"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE4 #language en-US "2933"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE5 #language en-US "3200"
+#string STR_MEM_INFO_DIMM_INFO #language en-US "DIMM Information"
+
+#string STR_MEM_INFO_PERFORMANCE_FORM #language en-US "Memory RAS and Performance Configuration"
+#string STR_MEM_INFO_PERFORMANCE_FORM_HELP #language en-US "Displays and provides options to change the memory RAS and performance Settings"
+#string STR_MEM_INFO_ENABLE_ECC_PROMPT #language en-US "ECC mode"
+#string STR_MEM_INFO_ENABLE_ECC_HELP #language en-US "ECC mode: Disabled, SECDED or Symbol"
+#string STR_MEM_INFO_ENABLE_ERRCTRL_DE_PROMPT #language en-US "Defer uncorrectable read errors"
+#string STR_MEM_INFO_ENABLE_ERRCTRL_DE_HELP #language en-US "When enabled the DMC defers uncorrectable read errors to the consumer by sending an OK response and setting the TXDAT poison flag on the CHI-B interconnect. If this bit is clear the DMC defaults to non-deferred behavior when encountering an unrecoverable error"
+#string STR_MEM_INFO_ENABLE_ERRCTRL_FI_PROMPT #language en-US "Fault handling interrupt"
+#string STR_MEM_INFO_ENABLE_ERRCTRL_FI_HELP #language en-US "Enables fault handling interrupt. The fault handling interrupt is raised to give notice that ECC fault has been recorded"
+#string STR_MEM_INFO_ENABLE_SCRUB #language en-US "Scrub Patrol duration (hour)"
+#string STR_MEM_INFO_ENABLE_SCRUB_HELP #language en-US "Select duration (hour) for Scrub Patrol"
+#string STR_MEM_INFO_ENABLE_DEMAND_SCRUB_PROMPT #language en-US "Demand scrub"
+#string STR_MEM_INFO_ENABLE_DEMAND_SCRUB_HELP #language en-US "Enable/Disable the ability to write corrected data back to the memory once a correctable error is detected"
+#string STR_MEM_INFO_ENABLE_WRITE_CRC_PROMPT #language en-US "Write CRC"
+#string STR_MEM_INFO_ENABLE_WRITE_CRC_HELP #language en-US "Enable/Disable Cyclic Redundancy Check (CRC) functionality on write data. Be noted that enabling CRC will degrade Write bandwidth"
+
+
+#string STR_MEM_INFO_ENABLE_32GB_SLAVE_PROMPT #language en-US "Enable Slave 32bit memory region"
+#string STR_MEM_INFO_ENABLE_32GB_SLAVE_HELP #language en-US "Enables 32bit memory region (2GB) for slave socket"
+#string STR_MEM_INFO_FGR_MODE_PROMPT #language en-US "Fine Granularity Refresh (FGR)"
+#string STR_MEM_INFO_FGR_MODE_VALUE0 #language en-US "1x"
+#string STR_MEM_INFO_FGR_MODE_VALUE1 #language en-US "2x"
+#string STR_MEM_INFO_FGR_MODE_VALUE2 #language en-US "4x"
+#string STR_MEM_INFO_FGR_MODE_HELP #language en-US "Select DDR Fine Granularity Refresh (FGR) mode 1x/2x/4x"
+#string STR_MEM_INFO_REFRESH2X_MODE_PROMPT #language en-US "CVE-2020-10255 mitigation"
+#string STR_MEM_INFO_REFRESH2X_MODE_HELP #language en-US "Enable mitigation for CVE-2020-10255, TRRespass"
+
+#string STR_MEM_INFO_NVDIMM_FORM #language en-US "NVDIMM-N Configuration"
+#string STR_MEM_INFO_NVDIMM_FORM_HELP #language en-US "Displays and provides options to change the NVDIMM-N Settings"
+#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK0 #language en-US "Socket0 Configured Mode"
+#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK1 #language en-US "Socket1 Configured Mode"
+#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK0_VALUE #language en-US "Non-NVDIMM"
+#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK1_VALUE #language en-US "Non-NVDIMM"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_PROMPT #language en-US "Mode Selection"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE0 #language en-US "Non-NVDIMM"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE1 #language en-US "Non-Hashed"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE2 #language en-US "Hashed"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE3 #language en-US "Auto"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_HELP #language en-US "Select NVDIMM-N Mode (Non-NVDIMM/Non-Hashed/Hashed/Auto)"
--
2.17.1