From: Vu Nguyen <vungu...@os.amperecomputing.com> Provide memory screen with below info: * Memory total capacity * Memory RAS and Performance Configuration * Per DIMM Information
Cc: Thang Nguyen <th...@os.amperecomputing.com> Cc: Chuong Tran <chu...@os.amperecomputing.com> Cc: Phong Vo <ph...@os.amperecomputing.com> Cc: Leif Lindholm <l...@nuviainc.com> Cc: Michael D Kinney <michael.d.kin...@intel.com> Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org> Cc: Nate DeSimone <nathaniel.l.desim...@intel.com> Signed-off-by: Vu Nguyen <vungu...@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 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#80727): https://edk2.groups.io/g/devel/message/80727 Mute This Topic: https://groups.io/mt/85631213/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-