Re: [PATCH v3 27/28] AmpereAltraPkg: Add configuration screen for Watchdog timer


Leif Lindholm
 

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

There are secure and non-secure watchdog timers supported in the Mt.
Jade system. They are used to monitor the system booting like system
firmware, UEFI, and OS. The system will be reset if the timer expires.
So, this patch adds the configuration screen for the watchdog timer
which provides options to configure the timeout of these timers.

By default, the values of these options are 5 minutes.

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>
---
Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec | 3 +
Platform/Ampere/JadePkg/Jade.dsc | 1 +
Platform/Ampere/JadePkg/Jade.fdf | 1 +
Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf | 50 +++
Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h | 82 ++++
Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigNVDataStruct.h | 27 ++
Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h | 19 +
Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigVfr.vfr | 58 +++
Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c | 460 ++++++++++++++++++++
Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigStrings.uni | 26 ++
10 files changed, 727 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
index 196611d67280..b0e1f3ec6f2a 100644
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
@@ -56,6 +56,9 @@ [Guids]
# GUID for the ACPI HII configuration form
gAcpiConfigFormSetGuid = { 0x0ceb6764, 0xd415, 0x4b01, { 0xa8, 0x43, 0xd1, 0x01, 0xbc, 0xb0, 0xd8, 0x29 } }

+ # GUID for the Watchdog HII configuration form
+ gWatchdogConfigFormSetGuid = { 0xC3F8EC6E, 0x95EE, 0x460C, { 0xA4, 0x8D, 0xEA, 0x54, 0x2F, 0xFF, 0x01, 0x61 } }
+
## NVParam MM GUID
gNVParamMmGuid = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } }

diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index b5ac2547c8f8..b752ea3e5264 100644
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -201,3 +201,4 @@ [Components.common]
Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
+ Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index e0d4b049f6bf..8f3df6ccf01b 100644
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -359,5 +359,6 @@ [FV.FvMain]
INF Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
INF Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
INF Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
+ INF Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf

!include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
new file mode 100644
index 000000000000..3ed37bfb15da
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
@@ -0,0 +1,50 @@
+## @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 = WatchdogConfigDxe
+ FILE_GUID = 135A0CA5-4851-4EF5-9E1A-C6E4610C39A9
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = WatchdogConfigInitialize
+
+[Sources.common]
+ WatchdogConfigNVDataStruct.h
+ WatchdogConfigVfr.vfr
+ WatchdogConfigStrings.uni
+ WatchdogConfigDxe.c
+ WatchdogConfigDxe.h
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+ Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ DevicePathLib
+ HiiLib
+ NVParamLib
+ PrintLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Guids]
+ gPlatformManagerFormsetGuid
+ gWatchdogConfigFormSetGuid
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## CONSUMES
+ gEfiHiiConfigRoutingProtocolGuid ## CONSUMES
+ gEfiHiiConfigAccessProtocolGuid ## PRODUCES
+
+[Depex]
+ TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h
new file mode 100644
index 000000000000..5f47531c538e
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h
@@ -0,0 +1,82 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef WATCHDOG_CONFIG_DXE_H_
+#define WATCHDOG_CONFIG_DXE_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/NVParamLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <NVParamDef.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/HiiConfigRouting.h>
Should only include files actually required here.

/
Leif

+
+#include "WatchdogConfigNVDataStruct.h"
+
+//
+// This is the generated IFR binary data for each formset defined in VFR.
+//
+extern UINT8 WatchdogConfigVfrBin[];
+
+//
+// This is the generated String package data for all .UNI files.
+//
+extern UINT8 WatchdogConfigDxeStrings[];
+
+#define WATCHDOG_CONFIG_PRIVATE_SIGNATURE SIGNATURE_32 ('W', 'D', 'T', 'C')
+
+typedef struct {
+ UINTN Signature;
+
+ EFI_HANDLE DriverHandle;
+ EFI_HII_HANDLE HiiHandle;
+ WATCHDOG_CONFIG_VARSTORE_DATA Configuration;
+
+ //
+ // Consumed protocol
+ //
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+ //
+ // Produced protocol
+ //
+ EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+} WATCHDOG_CONFIG_PRIVATE_DATA;
+
+#define WATCHDOG_CONFIG_PRIVATE_FROM_THIS(a) CR (a, WATCHDOG_CONFIG_PRIVATE_DATA, ConfigAccess, WATCHDOG_CONFIG_PRIVATE_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
+WatchdogConfigNvParamSet (
+ IN WATCHDOG_CONFIG_VARSTORE_DATA *VarStoreConfig
+ );
+
+EFI_STATUS
+WatchdogConfigNvParamGet (
+ OUT WATCHDOG_CONFIG_VARSTORE_DATA *VarStoreConfig
+ );
+
+#endif /* WATCHDOG_CONFIG_DXE_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigNVDataStruct.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigNVDataStruct.h
new file mode 100644
index 000000000000..470a2821ffe7
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigNVDataStruct.h
@@ -0,0 +1,27 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef WATCHDOG_CONFIG_NV_DATA_STRUCT_H_
+#define WATCHDOG_CONFIG_NV_DATA_STRUCT_H_
+
+#include <Guid/WatchdogConfigHii.h>
+
+#define WATCHDOG_CONFIG_VARSTORE_ID 0x1234
+#define WATCHDOG_CONFIG_FORM_ID 0x1235
+
+#define NWDT_UEFI_DEFAULT_VALUE 300 // 5 minutes
+#define SWDT_DEFAULT_VALUE 300 // 5 minutes
+
+#pragma pack(1)
+typedef struct {
+ UINT32 WatchdogTimerUEFITimeout;
+ UINT32 SecureWatchdogTimerTimeout;
+} WATCHDOG_CONFIG_VARSTORE_DATA;
+#pragma pack()
+
+#endif /* WATCHDOG_CONFIG_NV_DATA_STRUCT_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h
new file mode 100644
index 000000000000..16319d61a759
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h
@@ -0,0 +1,19 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef WATCHDOG_CONFIG_HII_H_
+#define WATCHDOG_CONFIG_HII_H_
+
+#define WATCHDOG_CONFIG_FORMSET_GUID \
+ { \
+ 0xC3F8EC6E, 0x95EE, 0x460C, { 0xA4, 0x8D, 0xEA, 0x54, 0x2F, 0xFF, 0x01, 0x61 } \
+ }
+
+extern EFI_GUID gWatchdogConfigFormSetGuid;
+
+#endif /* WATCHDOG_CONFIG_HII_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigVfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigVfr.vfr
new file mode 100644
index 000000000000..48f2aef227f6
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigVfr.vfr
@@ -0,0 +1,58 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "WatchdogConfigNVDataStruct.h"
+
+formset
+ guid = WATCHDOG_CONFIG_FORMSET_GUID,
+ title = STRING_TOKEN(STR_WATCHDOG_CONFIG_FORM),
+ help = STRING_TOKEN(STR_WATCHDOG_CONFIG_FORM_HELP),
+ classguid = gPlatformManagerFormsetGuid,
+
+ //
+ // Define a variable Storage
+ //
+ varstore WATCHDOG_CONFIG_VARSTORE_DATA,
+ varid = WATCHDOG_CONFIG_VARSTORE_ID,
+ name = WatchdogConfigNVData,
+ guid = WATCHDOG_CONFIG_FORMSET_GUID;
+
+ form
+ formid = WATCHDOG_CONFIG_FORM_ID,
+ title = STRING_TOKEN(STR_WATCHDOG_CONFIG_FORM);
+ subtitle text = STRING_TOKEN(STR_WATCHDOG_CONFIG_FORM_HELP);
+
+ oneof varid = WatchdogConfigNVData.WatchdogTimerUEFITimeout,
+ prompt = STRING_TOKEN(STR_NWDT_TIMEOUT_UEFI),
+ help = STRING_TOKEN(STR_NWDT_TIMEOUT_UEFI_HELP),
+ flags = RESET_REQUIRED,
+ option text = STRING_TOKEN (STR_WDT_TIME_DISABLE), value = 0, flags = 0;
+ option text = STRING_TOKEN (STR_WDT_TIME_5MIN), value = 300, flags = 0;
+ option text = STRING_TOKEN (STR_WDT_TIME_6MIN), value = 360, flags = 0;
+ option text = STRING_TOKEN (STR_WDT_TIME_10MIN), value = 600, flags = 0;
+ option text = STRING_TOKEN (STR_WDT_TIME_15MIN), value = 900, flags = 0;
+ option text = STRING_TOKEN (STR_WDT_TIME_20MIN), value = 1200, flags = 0;
+ default = NWDT_UEFI_DEFAULT_VALUE,
+ endoneof;
+
+ oneof varid = WatchdogConfigNVData.SecureWatchdogTimerTimeout,
+ prompt = STRING_TOKEN(STR_SWDT_TIMEOUT),
+ help = STRING_TOKEN(STR_SWDT_TIMEOUT_HELP),
+ flags = RESET_REQUIRED,
+ option text = STRING_TOKEN (STR_WDT_TIME_DISABLE), value = 0, flags = 0;
+ option text = STRING_TOKEN (STR_WDT_TIME_5MIN), value = 300, flags = 0;
+ option text = STRING_TOKEN (STR_WDT_TIME_6MIN), value = 360, flags = 0;
+ option text = STRING_TOKEN (STR_WDT_TIME_10MIN), value = 600, flags = 0;
+ option text = STRING_TOKEN (STR_WDT_TIME_15MIN), value = 900, flags = 0;
+ option text = STRING_TOKEN (STR_WDT_TIME_20MIN), value = 1200, flags = 0;
+ default = SWDT_DEFAULT_VALUE,
+ endoneof;
+
+ endform;
+
+endformset;
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c
new file mode 100644
index 000000000000..bd7b929dccda
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c
@@ -0,0 +1,460 @@
+/** @file
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "WatchdogConfigDxe.h"
+
+CHAR16 WatchDogConfigVarstoreDataName[] = L"WatchdogConfigNVData";
+
+EFI_HANDLE mDriverHandle = NULL;
+WATCHDOG_CONFIG_PRIVATE_DATA *mPrivateData = NULL;
+
+HII_VENDOR_DEVICE_PATH mWatchdogConfigHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ WATCHDOG_CONFIG_FORMSET_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8)(END_DEVICE_PATH_LENGTH),
+ (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+EFI_STATUS
+WatchdogConfigNvParamGet (
+ OUT WATCHDOG_CONFIG_VARSTORE_DATA *VarStoreConfig
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Value;
+ BOOLEAN SetDefault;
+
+ SetDefault = FALSE;
+ Status = NVParamGet (
+ NV_SI_WDT_BIOS_EXP_MINS,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->WatchdogTimerUEFITimeout = NWDT_UEFI_DEFAULT_VALUE;
+ if (Status == EFI_NOT_FOUND) {
+ SetDefault = TRUE;
+ } else {
+ ASSERT (FALSE);
+ }
+ } else {
+ VarStoreConfig->WatchdogTimerUEFITimeout = Value * 60;
+ }
+
+ Status = NVParamGet (
+ NV_SI_SEC_WDT_BIOS_EXP_MINS,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ VarStoreConfig->SecureWatchdogTimerTimeout = SWDT_DEFAULT_VALUE;
+ if (Status == EFI_NOT_FOUND) {
+ SetDefault = TRUE;
+ } else {
+ ASSERT (FALSE);
+ }
+ } else {
+ VarStoreConfig->SecureWatchdogTimerTimeout = Value;
+ }
+
+ if (SetDefault) {
+ WatchdogConfigNvParamSet (VarStoreConfig);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+WatchdogConfigNvParamSet (
+ IN WATCHDOG_CONFIG_VARSTORE_DATA *VarStoreConfig
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Value;
+
+ Status = NVParamGet (
+ NV_SI_WDT_BIOS_EXP_MINS,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)
+ || Value != (VarStoreConfig->WatchdogTimerUEFITimeout / 60))
+ {
+ Status = NVParamSet (
+ NV_SI_WDT_BIOS_EXP_MINS,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ (VarStoreConfig->WatchdogTimerUEFITimeout / 60)
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ Status = NVParamGet (
+ NV_SI_SEC_WDT_BIOS_EXP_MINS,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ &Value
+ );
+ if (EFI_ERROR (Status)
+ || Value != VarStoreConfig->SecureWatchdogTimerTimeout)
+ {
+ Status = NVParamSet (
+ NV_SI_SEC_WDT_BIOS_EXP_MINS,
+ NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+ NV_PERM_BIOS | NV_PERM_MANU,
+ VarStoreConfig->SecureWatchdogTimerTimeout
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ 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_OUT_OF_RESOURCES Not enough memory to store the results.
+ @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
+WatchdogConfigExtractConfig (
+ 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;
+ WATCHDOG_CONFIG_PRIVATE_DATA *PrivateData;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+ EFI_STRING ConfigRequest;
+ EFI_STRING ConfigRequestHdr;
+ UINTN Size;
+ 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;
+
+ if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gWatchdogConfigFormSetGuid, WatchDogConfigVarstoreDataName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ PrivateData = WATCHDOG_CONFIG_PRIVATE_FROM_THIS (This);
+ HiiConfigRouting = PrivateData->HiiConfigRouting;
+
+ //
+ // Get current setting from NVParam.
+ //
+ Status = WatchdogConfigNvParamGet (&PrivateData->Configuration);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+ //
+ BufferSize = sizeof (WATCHDOG_CONFIG_VARSTORE_DATA);
+ ConfigRequest = Request;
+ if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
+ //
+ // Request has no request element, 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 (&gWatchdogConfigFormSetGuid, WatchDogConfigVarstoreDataName, PrivateData->DriverHandle);
+ Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+ ConfigRequest = AllocateZeroPool (Size);
+ ASSERT (ConfigRequest != NULL);
+ if (ConfigRequest == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ AllocatedRequest = TRUE;
+ UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+ FreePool (ConfigRequestHdr);
+ }
+
+ //
+ // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+ //
+ Status = HiiConfigRouting->BlockToConfig (
+ HiiConfigRouting,
+ ConfigRequest,
+ (UINT8 *)&PrivateData->Configuration,
+ BufferSize,
+ Results,
+ Progress
+ );
+
+ //
+ // Free the allocated config request string.
+ //
+ if (AllocatedRequest) {
+ FreePool (ConfigRequest);
+ ConfigRequest = NULL;
+ }
+
+ //
+ // 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
+WatchdogConfigRouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ WATCHDOG_CONFIG_PRIVATE_DATA *PrivateData;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+ if (Configuration == NULL || Progress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = WATCHDOG_CONFIG_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, &gWatchdogConfigFormSetGuid, WatchDogConfigVarstoreDataName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Get configuration data from NVParam
+ //
+ Status = WatchdogConfigNvParamGet (&PrivateData->Configuration);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
+ //
+ BufferSize = sizeof (WATCHDOG_CONFIG_VARSTORE_DATA);
+ Status = HiiConfigRouting->ConfigToBlock (
+ HiiConfigRouting,
+ Configuration,
+ (UINT8 *)&PrivateData->Configuration,
+ &BufferSize,
+ Progress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Store configuration data back to NVParam
+ //
+ Status = WatchdogConfigNvParamSet (&PrivateData->Configuration);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ 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 The setup browser call this function with invalid parameters.
+
+**/
+EFI_STATUS
+EFIAPI
+WatchdogConfigCallback (
+ 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 (Action != EFI_BROWSER_ACTION_CHANGING) {
+ //
+ // Do nothing for other UEFI Action. Only do call back when data is changed.
+ //
+ return EFI_UNSUPPORTED;
+ }
+ if (((Value == NULL)
+ && (Action != EFI_BROWSER_ACTION_FORM_OPEN)
+ && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))
+ || (ActionRequest == NULL))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+WatchdogConfigInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+ //
+ // Initialize driver private data
+ //
+ mPrivateData = AllocateZeroPool (sizeof (WATCHDOG_CONFIG_PRIVATE_DATA));
+ if (mPrivateData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mPrivateData->Signature = WATCHDOG_CONFIG_PRIVATE_SIGNATURE;
+
+ mPrivateData->ConfigAccess.ExtractConfig = WatchdogConfigExtractConfig;
+ mPrivateData->ConfigAccess.RouteConfig = WatchdogConfigRouteConfig;
+ mPrivateData->ConfigAccess.Callback = WatchdogConfigCallback;
+
+ //
+ // Locate ConfigRouting protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ mPrivateData->HiiConfigRouting = HiiConfigRouting;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mDriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mWatchdogConfigHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &mPrivateData->ConfigAccess,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ mPrivateData->DriverHandle = mDriverHandle;
+
+ //
+ // Publish our HII data
+ //
+ HiiHandle = HiiAddPackages (
+ &gWatchdogConfigFormSetGuid,
+ mDriverHandle,
+ WatchdogConfigDxeStrings,
+ WatchdogConfigVfrBin,
+ NULL
+ );
+ if (HiiHandle == NULL) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ mDriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mWatchdogConfigHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &mPrivateData->ConfigAccess,
+ NULL
+ );
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mPrivateData->HiiHandle = HiiHandle;
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigStrings.uni
new file mode 100644
index 000000000000..1d0f820e456f
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigStrings.uni
@@ -0,0 +1,26 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#langdef en-US "English"
+
+#string STR_WATCHDOG_CONFIG_FORM #language en-US "Watchdog Configuration"
+#string STR_WATCHDOG_CONFIG_FORM_HELP #language en-US "Watchdog Configuration"
+
+#string STR_WDT_TIME_DISABLE #language en-US "Disabled"
+#string STR_WDT_TIME_3MIN #language en-US "3 minutes"
+#string STR_WDT_TIME_4MIN #language en-US "4 minutes"
+#string STR_WDT_TIME_5MIN #language en-US "5 minutes"
+#string STR_WDT_TIME_6MIN #language en-US "6 minutes"
+#string STR_WDT_TIME_10MIN #language en-US "10 minutes"
+#string STR_WDT_TIME_15MIN #language en-US "15 minutes"
+#string STR_WDT_TIME_20MIN #language en-US "20 minutes"
+
+#string STR_NWDT_TIMEOUT_OS #language en-US "OS Watchdog Timeout"
+#string STR_NWDT_TIMEOUT_OS_HELP #language en-US "Timeout when boot OS."
+#string STR_NWDT_TIMEOUT_UEFI #language en-US "UEFI Watchdog Timeout"
+#string STR_NWDT_TIMEOUT_UEFI_HELP #language en-US "Timeout when boot UEFI"
+#string STR_SWDT_TIMEOUT #language en-US "Secure Watchdog Timeout"
+#string STR_SWDT_TIMEOUT_HELP #language en-US "Timeout when SCP will reset system if it doesn't receive response from ARMv8."
--
2.17.1

Join devel@edk2.groups.io to automatically receive all group messages.