From: "Nhi Pham" <nhi@os.amperecomputing.com>
To: Leif Lindholm <leif@nuviainc.com>
Cc: devel@edk2.groups.io, Thang Nguyen <thang@os.amperecomputing.com>,
Chuong Tran <chuong@os.amperecomputing.com>,
Phong Vo <phong@os.amperecomputing.com>,
Michael D Kinney <michael.d.kinney@intel.com>,
Ard Biesheuvel <ardb+tianocore@kernel.org>,
Nate DeSimone <nathaniel.l.desimone@intel.com>
Subject: Re: [edk2-platforms][PATCH v2 04/32] AmperePlatformPkg: Add FailSafe and WDT support
Date: Tue, 15 Jun 2021 23:47:29 +0700 [thread overview]
Message-ID: <cb426871-ca09-2c6e-6823-30b03004d30c@os.amperecomputing.com> (raw)
In-Reply-To: <20210604231251.qdmtx7tzf2ph4d2p@leviathan>
Hi Leif,
On 6/5/21 06:12, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:06:56 +0700, Nhi Pham wrote:
>> The FailSafeDxe driver reverts the system's configuration to known good
>> values if the system fails to boot up multiple times. It also implements
>> the Watchdog Timer Architectural Protocol to reset the system if it
>> hangs.
>>
>> By default, when system starts, it configures the secure watchdog timer
>> with a default value of 5 minutes. If the system boots up cleanly to the
>> considered good stage, the counter is cleared as it indicates FailSafe
>> monitor (ATF) that has booted up successfully. If the timer expires, it
>> is considered a failed boot and system is rebooted.
>>
>> 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: Nhi Pham <nhi@os.amperecomputing.com>
>> ---
>> Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc | 1 -
>> Platform/Ampere/JadePkg/Jade.dsc | 9 +
>> Platform/Ampere/JadePkg/Jade.fdf | 6 +-
>> Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf | 54 +++
>> Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h | 20 ++
>> Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h | 29 ++
>> Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c | 184 ++++++++++
>> Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c | 357 ++++++++++++++++++++
>> 8 files changed, 658 insertions(+), 2 deletions(-)
>>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> index 0332473b59b0..6a6f72e995af 100755
>> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> @@ -585,7 +585,6 @@ [Components.common]
>> # Timer
>> #
>> ArmPkg/Drivers/TimerDxe/TimerDxe.inf
>> - MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> It's not clear from the commit message why this should happen.
>
>>
>> #
>> # ARM GIC Dxe
>> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
>> index f68af24a0d78..f92855af99ab 100755
>> --- a/Platform/Ampere/JadePkg/Jade.dsc
>> +++ b/Platform/Ampere/JadePkg/Jade.dsc
>> @@ -75,6 +75,11 @@ [LibraryClasses]
>> #
>> RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
>>
>> + #
>> + # Library for FailSafe support
>> + #
>> + FailSafeLib|Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
>> +
>> ################################################################################
>> #
>> # Specific Platform Pcds
>> @@ -98,3 +103,7 @@ [PcdsFixedAtBuild.common]
>> #
>> ################################################################################
>> [Components.common]
>> + #
>> + # FailSafe and Watchdog Timer
>> + #
>> + Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
>> index 905289844378..80a86d7c1156 100755
>> --- a/Platform/Ampere/JadePkg/Jade.fdf
>> +++ b/Platform/Ampere/JadePkg/Jade.fdf
>> @@ -185,7 +185,11 @@ [FV.FvMain]
>> # Timer
>> #
>> INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
>> - INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> It's not clear from the commit message why this should happen.
The Watchdog protocol which is implemented in this Failsafe driver will
replace the WatchdogTimer.inf. I will update the commit message to
clarify this.
Best regards,
Nhi
>
> /
> Leif
>
>> +
>> + #
>> + # FailSafe and Watchdog Timer
>> + #
>> + INF Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>>
>> #
>> # ARM GIC Dxe
>> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>> new file mode 100755
>> index 000000000000..60de10c95c85
>> --- /dev/null
>> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>> @@ -0,0 +1,54 @@
>> +## @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 = FailSafeDxe
>> + FILE_GUID = 7BC4F970-B1CF-11E6-80F5-76304DEC7EB7
>> + MODULE_TYPE = DXE_DRIVER
>> + VERSION_STRING = 1.0
>> + ENTRY_POINT = FailSafeDxeEntryPoint
>> +
>> +[Sources]
>> + FailSafe.h
>> + FailSafeDxe.c
>> + Watchdog.c
>> + Watchdog.h
>> +
>> +[Packages]
>> + ArmPkg/ArmPkg.dec
>> + ArmPlatformPkg/ArmPlatformPkg.dec
>> + EmbeddedPkg/EmbeddedPkg.dec
>> + MdeModulePkg/MdeModulePkg.dec
>> + MdePkg/MdePkg.dec
>> + Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
>> + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> + Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +
>> +[LibraryClasses]
>> + ArmSmcLib
>> + DebugLib
>> + FailSafeLib
>> + NVParamLib
>> + PcdLib
>> + TimerLib
>> + UefiBootServicesTableLib
>> + UefiDriverEntryPoint
>> + UefiLib
>> + UefiRuntimeServicesTableLib
>> +
>> +[Pcd]
>> + gArmTokenSpaceGuid.PcdGenericWatchdogControlBase
>> + gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
>> +
>> +[Protocols]
>> + gEfiWatchdogTimerArchProtocolGuid ## PRODUCES
>> + gHardwareInterrupt2ProtocolGuid ## CONSUMES
>> +
>> +[Depex]
>> + gHardwareInterrupt2ProtocolGuid
>> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h
>> new file mode 100644
>> index 000000000000..8bf3a98f1d8e
>> --- /dev/null
>> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h
>> @@ -0,0 +1,20 @@
>> +/** @file
>> +
>> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef FAILSAFE_H_
>> +#define FAILSAFE_H_
>> +
>> +#include <Uefi.h>
>> +
>> +BOOLEAN
>> +EFIAPI
>> +IsFailSafeOff (
>> + VOID
>> + );
>> +
>> +#endif /* FAILSAFE_H_ */
>> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h
>> new file mode 100755
>> index 000000000000..6c9106fdbea5
>> --- /dev/null
>> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h
>> @@ -0,0 +1,29 @@
>> +/** @file
>> +
>> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef GENERIC_WATCHDOG_H_
>> +#define GENERIC_WATCHDOG_H_
>> +
>> +#include <Protocol/WatchdogTimer.h>
>> +
>> +/* The number of 100ns periods (the unit of time passed to these functions)
>> + in a second */
>> +#define TIME_UNITS_PER_SECOND 10000000
>> +
>> +/**
>> + The function to install Watchdog timer protocol to the system
>> +
>> + @retval Return EFI_SUCCESS if install Watchdog timer protocol successfully.
>> + **/
>> +EFI_STATUS
>> +EFIAPI
>> +WatchdogTimerInstallProtocol (
>> + EFI_WATCHDOG_TIMER_ARCH_PROTOCOL **WatchdogTimerProtocol
>> + );
>> +
>> +#endif /* GENERIC_WATCHDOG_H_ */
>> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c
>> new file mode 100644
>> index 000000000000..1b8978b12ea7
>> --- /dev/null
>> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c
>> @@ -0,0 +1,184 @@
>> +/** @file
>> +
>> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Guid/EventGroup.h>
>> +#include <Library/ArmSmcLib.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/FailSafeLib.h>
>> +#include <Library/NVParamLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +
>> +#include "FailSafe.h"
>> +#include "Watchdog.h"
>> +
>> +STATIC UINTN gWatchdogOSTimeout;
>> +STATIC BOOLEAN gFailSafeOff;
>> +STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer;
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +FailSafeTestBootFailure (
>> + VOID
>> + );
>> +
>> +STATIC VOID
>> +FailSafeTurnOff (
>> + VOID
>> + )
>> +{
>> + EFI_STATUS Status;
>> +
>> + if (IsFailSafeOff ()) {
>> + return;
>> + }
>> +
>> + Status = FailSafeBootSuccessfully ();
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + gFailSafeOff = TRUE;
>> +
>> + /* Disable Watchdog timer */
>> + gWatchdogTimer->SetTimerPeriod (gWatchdogTimer, 0);
>> +}
>> +
>> +BOOLEAN
>> +EFIAPI
>> +IsFailSafeOff (
>> + VOID
>> + )
>> +{
>> + return gFailSafeOff;
>> +}
>> +
>> +/**
>> + The function to disable Watchdog timer when enter Setup screen
>> + **/
>> +VOID
>> +WdtTimerEnterSetupScreenCallback (
>> + IN EFI_EVENT Event,
>> + IN VOID *Context
>> + )
>> +{
>> + /* Make sure FailSafe is turned off */
>> + FailSafeTurnOff ();
>> +}
>> +
>> +/**
>> + The function to refresh Watchdog timer in the event before booting
>> + **/
>> +VOID
>> +WdtTimerBeforeBootCallback (
>> + IN EFI_EVENT Event,
>> + IN VOID *Context
>> + )
>> +{
>> + /*
>> + * At this point, the system is considered boot successfully to BIOS
>> + */
>> + FailSafeTurnOff ();
>> +
>> + /*
>> + * It is BIOS's responsibility to setup Watchdog when load an EFI application
>> + * after this step
>> + */
>> +}
>> +
>> +/**
>> + The function to refresh Watchdog timer in the event before exiting boot services
>> + **/
>> +VOID
>> +WdtTimerExitBootServiceCallback (
>> + IN EFI_EVENT Event,
>> + IN VOID *Context
>> + )
>> +{
>> +
>> + /* Enable Watchdog timer for OS booting */
>> + if (gWatchdogOSTimeout != 0) {
>> + gWatchdogTimer->SetTimerPeriod (
>> + gWatchdogTimer,
>> + gWatchdogOSTimeout * TIME_UNITS_PER_SECOND
>> + );
>> + } else {
>> + /* Disable Watchdog timer */
>> + gWatchdogTimer->SetTimerPeriod (gWatchdogTimer, 0);
>> + }
>> +}
>> +
>> +/**
>> + This function is a hook called when user loads the manufacturing
>> + or optimal defaults.
>> +
>> + @param Defaults : (NVRAM_VARIABLE *)optimal or manufacturing
>> + @Data : Messagebox
>> +
>> + @retval VOID
>> +**/
>> +VOID
>> +LoadNVRAMDefaultConfig (
>> + IN VOID *Defaults,
>> + IN UINTN Data
>> + )
>> +{
>> + NVParamClrAll ();
>> +}
>> +
>> +/**
>> + Main entry for this driver.
>> +
>> + @param ImageHandle Image handle this driver.
>> + @param SystemTable Pointer to SystemTable.
>> +
>> + @retval EFI_SUCESS This function always complete successfully.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +FailSafeDxeEntryPoint (
>> + IN EFI_HANDLE ImageHandle,
>> + IN EFI_SYSTEM_TABLE *SystemTable
>> + )
>> +{
>> + EFI_EVENT ExitBootServicesEvent;
>> + EFI_STATUS Status;
>> +
>> + gFailSafeOff = FALSE;
>> +
>> + FailSafeTestBootFailure ();
>> +
>> + /* We need to setup non secure Watchdog to ensure that the system will
>> + * boot to OS successfully.
>> + *
>> + * The BIOS doesn't handle Watchdog interrupt so we expect WS1 asserted EL3
>> + * when Watchdog timeout triggered
>> + */
>> +
>> + Status = WatchdogTimerInstallProtocol (&gWatchdogTimer);
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + // FIXME: We should register a callback function before entering to Setup screen
>> + // rather than always call it at DXE phase.
>> + FailSafeTurnOff ();
>> +
>> + /* Register event before exit boot services */
>> + Status = gBS->CreateEvent (
>> + EVT_SIGNAL_EXIT_BOOT_SERVICES,
>> + TPL_NOTIFY,
>> + WdtTimerExitBootServiceCallback,
>> + NULL,
>> + &ExitBootServicesEvent
>> + );
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + return Status;
>> +}
>> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c
>> new file mode 100644
>> index 000000000000..34329d04206a
>> --- /dev/null
>> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c
>> @@ -0,0 +1,357 @@
>> +/** @file
>> +
>> + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> + SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Library/ArmGenericTimerCounterLib.h>
>> +#include <Library/ArmLib.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/IoLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +#include <Protocol/HardwareInterrupt2.h>
>> +
>> +#include "FailSafe.h"
>> +#include "Watchdog.h"
>> +
>> +/* Watchdog timer controller registers */
>> +#define WDT_CTRL_BASE_REG FixedPcdGet64 (PcdGenericWatchdogControlBase)
>> +#define WDT_CTRL_WCS_OFF 0x0
>> +#define WDT_CTRL_WCS_ENABLE_MASK 0x1
>> +#define WDT_CTRL_WOR_OFF 0x8
>> +#define WDT_CTRL_WCV_OFF 0x10
>> +#define WS0_INTERRUPT_SOURCE FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum)
>> +
>> +STATIC UINT64 mNumTimerTicks;
>> +STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;
>> +BOOLEAN mInterruptWS0Enabled;
>> +
>> +STATIC
>> +VOID
>> +WatchdogTimerWriteOffsetRegister (
>> + UINT32 Value
>> + )
>> +{
>> + MmioWrite32 (WDT_CTRL_BASE_REG + WDT_CTRL_WOR_OFF, Value);
>> +}
>> +
>> +STATIC
>> +VOID
>> +WatchdogTimerWriteCompareRegister (
>> + UINT64 Value
>> + )
>> +{
>> + MmioWrite64 (WDT_CTRL_BASE_REG + WDT_CTRL_WCV_OFF, Value);
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +WatchdogTimerEnable (
>> + IN BOOLEAN Enable
>> + )
>> +{
>> + UINT32 Val = MmioRead32 ((UINTN)(WDT_CTRL_BASE_REG + WDT_CTRL_WCS_OFF));
>> +
>> + if (Enable) {
>> + Val |= WDT_CTRL_WCS_ENABLE_MASK;
>> + } else {
>> + Val &= ~WDT_CTRL_WCS_ENABLE_MASK;
>> + }
>> + MmioWrite32 ((UINTN)(WDT_CTRL_BASE_REG + WDT_CTRL_WCS_OFF), Val);
>> +
>> + return EFI_SUCCESS;
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +WatchdogTimerSetup (
>> + VOID
>> + )
>> +{
>> + EFI_STATUS Status;
>> +
>> + /* Disable Watchdog timer */
>> + WatchdogTimerEnable (FALSE);
>> +
>> + if (!mInterruptWS0Enabled) {
>> + Status = mInterruptProtocol->EnableInterruptSource (
>> + mInterruptProtocol,
>> + WS0_INTERRUPT_SOURCE
>> + );
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + mInterruptWS0Enabled = TRUE;
>> + }
>> +
>> + if (mNumTimerTicks == 0) {
>> + return EFI_SUCCESS;
>> + }
>> +
>> + /* If the number of required ticks is greater than the max the Watchdog's
>> + offset register (WOR) can hold, we need to manually compute and set
>> + the compare register (WCV) */
>> + if (mNumTimerTicks > MAX_UINT32) {
>> + /* We need to enable the Watchdog *before* writing to the compare register,
>> + because enabling the Watchdog causes an "explicit refresh", which
>> + clobbers the compare register (WCV). In order to make sure this doesn't
>> + trigger an interrupt, set the offset to max. */
>> + WatchdogTimerWriteOffsetRegister (MAX_UINT32);
>> + WatchdogTimerEnable (TRUE);
>> + WatchdogTimerWriteCompareRegister (ArmGenericTimerGetSystemCount () + mNumTimerTicks);
>> + } else {
>> + WatchdogTimerWriteOffsetRegister ((UINT32)mNumTimerTicks);
>> + WatchdogTimerEnable (TRUE);
>> + }
>> +
>> + return EFI_SUCCESS;
>> +}
>> +
>> +
>> +/* This function is called when the Watchdog's first signal (WS0) goes high.
>> + It uses the ResetSystem Runtime Service to reset the board.
>> +*/
>> +VOID
>> +EFIAPI
>> +WatchdogTimerInterruptHandler (
>> + IN HARDWARE_INTERRUPT_SOURCE Source,
>> + IN EFI_SYSTEM_CONTEXT SystemContext
>> + )
>> +{
>> + STATIC CONST CHAR16 ResetString[]= L"The generic Watchdog timer ran out.";
>> +
>> + mInterruptProtocol->EndOfInterrupt (mInterruptProtocol, Source);
>> +
>> + if (!IsFailSafeOff ()) {
>> + /* Not handling interrupt as ATF is monitoring it */
>> + return;
>> + }
>> +
>> + WatchdogTimerEnable (FALSE);
>> +
>> + gRT->ResetSystem (
>> + EfiResetCold,
>> + EFI_TIMEOUT,
>> + StrSize (ResetString),
>> + (VOID *)&ResetString
>> + );
>> +
>> + /* If we got here then the reset didn't work */
>> + ASSERT (FALSE);
>> +}
>> +
>> +/**
>> + This function registers the handler NotifyFunction so it is called every time
>> + the Watchdog timer expires. It also passes the amount of time since the last
>> + handler call to the NotifyFunction.
>> + If NotifyFunction is not NULL and a handler is not already registered,
>> + then the new handler is registered and EFI_SUCCESS is returned.
>> + If NotifyFunction is NULL, and a handler is already registered,
>> + then that handler is unregistered.
>> + If an attempt is made to register a handler when a handler is already
>> + registered, then EFI_ALREADY_STARTED is returned.
>> + If an attempt is made to unregister a handler when a handler is not
>> + registered, then EFI_INVALID_PARAMETER is returned.
>> +
>> + @param This The EFI_TIMER_ARCH_PROTOCOL instance.
>> + @param NotifyFunction The function to call when a timer interrupt fires.
>> + This function executes at TPL_HIGH_LEVEL. The DXE
>> + Core will register a handler for the timer interrupt,
>> + so it can know how much time has passed. This
>> + information is used to signal timer based events.
>> + NULL will unregister the handler.
>> +
>> + @retval EFI_UNSUPPORTED The code does not support NotifyFunction.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +WatchdogTimerRegisterHandler (
>> + IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
>> + IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction
>> + )
>> +{
>> + /* Not support. Watchdog will reset the board */
>> + return EFI_UNSUPPORTED;
>> +}
>> +
>> +/**
>> + This function sets the amount of time to wait before firing the Watchdog
>> + timer to TimerPeriod 100ns units. If TimerPeriod is 0, then the Watchdog
>> + timer is disabled.
>> +
>> + @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
>> + @param TimerPeriod The amount of time in 100ns units to wait before
>> + the Watchdog timer is fired. If TimerPeriod is zero,
>> + then the Watchdog timer is disabled.
>> +
>> + @retval EFI_SUCCESS The Watchdog timer has been programmed to fire
>> + in Time 100ns units.
>> + @retval EFI_DEVICE_ERROR A Watchdog timer could not be programmed due
>> + to a device error.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +WatchdogTimerSetPeriod (
>> + IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
>> + IN UINT64 TimerPeriod // In 100ns units
>> + )
>> +{
>> + mNumTimerTicks = (ArmGenericTimerGetTimerFreq () * TimerPeriod) / TIME_UNITS_PER_SECOND;
>> +
>> + if (!IsFailSafeOff ()) {
>> + /* Not support Watchdog timer service until FailSafe is off as ATF is monitoring it */
>> + return EFI_SUCCESS;
>> + }
>> +
>> + return WatchdogTimerSetup ();
>> +}
>> +
>> +/**
>> + This function retrieves the period of timer interrupts in 100ns units,
>> + returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod
>> + is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is
>> + returned, then the timer is currently disabled.
>> +
>> + @param This The EFI_TIMER_ARCH_PROTOCOL instance.
>> + @param TimerPeriod A pointer to the timer period to retrieve in
>> + 100ns units. If 0 is returned, then the timer is
>> + currently disabled.
>> +
>> +
>> + @retval EFI_SUCCESS The timer period was returned in TimerPeriod.
>> + @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +WatchdogTimerGetPeriod (
>> + IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
>> + OUT UINT64 *TimerPeriod
>> + )
>> +{
>> + if (TimerPeriod == NULL) {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> +
>> + *TimerPeriod = ((TIME_UNITS_PER_SECOND / ArmGenericTimerGetTimerFreq ()) * mNumTimerTicks);
>> +
>> + return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> + Interface structure for the Watchdog Architectural Protocol.
>> +
>> + @par Protocol Description:
>> + This protocol provides a service to set the amount of time to wait
>> + before firing the Watchdog timer, and it also provides a service to
>> + register a handler that is invoked when the Watchdog timer fires.
>> +
>> + @par When the Watchdog timer fires, control will be passed to a handler
>> + if one has been registered. If no handler has been registered,
>> + or the registered handler returns, then the system will be
>> + reset by calling the Runtime Service ResetSystem().
>> +
>> + @param RegisterHandler
>> + Registers a handler that will be called each time the
>> + Watchdogtimer interrupt fires. TimerPeriod defines the minimum
>> + time between timer interrupts, so TimerPeriod will also
>> + be the minimum time between calls to the registered
>> + handler.
>> + NOTE: If the Watchdog resets the system in hardware, then
>> + this function will not have any chance of executing.
>> +
>> + @param SetTimerPeriod
>> + Sets the period of the timer interrupt in 100ns units.
>> + This function is optional, and may return EFI_UNSUPPORTED.
>> + If this function is supported, then the timer period will
>> + be rounded up to the nearest supported timer period.
>> +
>> + @param GetTimerPeriod
>> + Retrieves the period of the timer interrupt in 100ns units.
>> +
>> +**/
>> +STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = {
>> + (EFI_WATCHDOG_TIMER_REGISTER_HANDLER)WatchdogTimerRegisterHandler,
>> + (EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD)WatchdogTimerSetPeriod,
>> + (EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD)WatchdogTimerGetPeriod
>> +};
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +WatchdogTimerInstallProtocol (
>> + EFI_WATCHDOG_TIMER_ARCH_PROTOCOL **WatchdogTimerProtocol
>> + )
>> +{
>> + EFI_STATUS Status;
>> + EFI_HANDLE Handle;
>> + EFI_TPL CurrentTpl;
>> +
>> + /* Make sure the Watchdog Timer Architectural Protocol has not been installed
>> + in the system yet.
>> + This will avoid conflicts with the universal Watchdog */
>> + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
>> +
>> + ASSERT (ArmGenericTimerGetTimerFreq () != 0);
>> +
>> + /* Install interrupt handler */
>> + Status = gBS->LocateProtocol (
>> + &gHardwareInterrupt2ProtocolGuid,
>> + NULL,
>> + (VOID **)&mInterruptProtocol
>> + );
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + /*
>> + * We don't want to be interrupted while registering Watchdog interrupt source as the interrupt
>> + * may be trigger in the middle because the interrupt line already enabled in the EL3.
>> + */
>> + CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
>> +
>> + Status = mInterruptProtocol->RegisterInterruptSource (
>> + mInterruptProtocol,
>> + WS0_INTERRUPT_SOURCE,
>> + WatchdogTimerInterruptHandler
>> + );
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + /* Don't enable interrupt until FailSafe off */
>> + mInterruptWS0Enabled = FALSE;
>> + Status = mInterruptProtocol->DisableInterruptSource (
>> + mInterruptProtocol,
>> + WS0_INTERRUPT_SOURCE
>> + );
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + gBS->RestoreTPL (CurrentTpl);
>> +
>> + Status = mInterruptProtocol->SetTriggerType (
>> + mInterruptProtocol,
>> + WS0_INTERRUPT_SOURCE,
>> + EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH
>> + );
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + /* Install the Timer Architectural Protocol onto a new handle */
>> + Handle = NULL;
>> + Status = gBS->InstallMultipleProtocolInterfaces (
>> + &Handle,
>> + &gEfiWatchdogTimerArchProtocolGuid,
>> + &gWatchdogTimer,
>> + NULL
>> + );
>> + ASSERT_EFI_ERROR (Status);
>> +
>> + mNumTimerTicks = 0;
>> +
>> + if (WatchdogTimerProtocol != NULL) {
>> + *WatchdogTimerProtocol = &gWatchdogTimer;
>> + }
>> +
>> + return Status;
>> +}
>> --
>> 2.17.1
>>
next prev parent reply other threads:[~2021-06-15 16:47 UTC|newest]
Thread overview: 87+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 01/32] Ampere: Initial support for Ampere Altra processor and " Nhi Pham
2021-06-04 23:04 ` Leif Lindholm
2021-06-09 4:50 ` Nhi Pham
2021-06-09 12:40 ` Leif Lindholm
2021-06-15 16:46 ` Nhi Pham
2021-05-26 10:06 ` [PATCH 1/1] UsbCdcNetDxe: Remove reading connection status in SNP GetStatus Nhi Pham
2021-05-26 10:23 ` [edk2-devel] " Nhi Pham
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 02/32] AmpereAltraPkg: Add MmCommunication modules Nhi Pham
2021-06-04 23:05 ` Leif Lindholm
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 03/32] AmperePlatformPkg: Implement FailSafe library Nhi Pham
2021-06-04 23:07 ` Leif Lindholm
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 04/32] AmperePlatformPkg: Add FailSafe and WDT support Nhi Pham
2021-06-04 23:12 ` Leif Lindholm
2021-06-15 16:47 ` Nhi Pham [this message]
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 05/32] AmpereAltraPkg: Add DwI2cLib library Nhi Pham
2021-06-04 23:21 ` Leif Lindholm
2021-06-15 16:47 ` Nhi Pham
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 06/32] AmpereAltraPkg: Add DwGpioLib library Nhi Pham
2021-06-04 23:22 ` Leif Lindholm
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 07/32] JadePkg: Implement RealTimeClockLib for PCF85063 Nhi Pham
2021-06-04 23:26 ` Leif Lindholm
2021-06-15 16:48 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 08/32] AmpereAltraPkg: Add BootProgress support Nhi Pham
2021-06-04 23:27 ` Leif Lindholm
2021-06-15 16:48 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 09/32] AmpereAltraPkg: Support non-volatile variables Nhi Pham
2021-06-04 23:36 ` Leif Lindholm
2021-06-15 16:48 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 10/32] AmpereSiliconPkg: Add PlatformManagerUiLib library instance Nhi Pham
2021-06-04 23:37 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 11/32] AmperePlatformPkg: Add AcpiPccLib to support ACPI PCCT Table Nhi Pham
2021-06-04 23:44 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 12/32] AmperePlatformPkg: Add AcpiHelperLib to update ACPI DSDT table Nhi Pham
2021-06-04 23:47 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 13/32] AmpereAltraPkg, JadePkg: Add ACPI support Nhi Pham
2021-06-04 23:50 ` Leif Lindholm
2021-06-15 16:49 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 14/32] AmpereAltraPkg: Add PcieCoreLib library instance Nhi Pham
2021-06-05 0:05 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 15/32] JadePkg: Add PcieBoardLib " Nhi Pham
2021-06-07 22:45 ` Leif Lindholm
2021-06-15 16:50 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 16/32] AmpereAltraPkg: Add PciHostBridge driver Nhi Pham
2021-06-08 22:26 ` Leif Lindholm
2021-06-09 5:29 ` Ard Biesheuvel
2021-06-15 15:54 ` Nhi Pham
2021-06-16 14:20 ` Ard Biesheuvel
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 17/32] JadePkg: Enable PCIe-related libraries and device drivers Nhi Pham
2021-06-07 22:51 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 18/32] JadePkg: Add ASpeed GOP driver Nhi Pham
2021-06-07 22:51 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 19/32] AmpereAltraPkg: Add Random Number Generator Support Nhi Pham
2021-06-08 11:13 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 20/32] JadePkg: Add SMBIOS tables support Nhi Pham
2021-06-07 23:00 ` Leif Lindholm
2021-06-15 16:51 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 21/32] AmpereAltraPkg: Add DebugInfoPei module Nhi Pham
2021-06-07 23:08 ` Leif Lindholm
2021-06-15 16:51 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 22/32] AmpereAltraPkg: Add platform info screen Nhi Pham
2021-06-07 23:10 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 23/32] AmpereAltraPkg: Add configuration screen for memory Nhi Pham
2021-06-07 23:14 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 24/32] AmpereAltraPkg: Add configuration screen for CPU Nhi Pham
2021-06-07 23:15 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 25/32] AmpereAltraPkg: Add configuration screen for ACPI Nhi Pham
2021-06-07 23:20 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 26/32] AmpereAltraPkg: Add configuration screen for RAS Nhi Pham
2021-06-07 23:22 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 27/32] AmpereAltraPkg: Add configuration screen for Watchdog timer Nhi Pham
2021-06-07 23:24 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 28/32] AmpereAltraPkg: Add configuration screen for Pcie Devices Nhi Pham
2021-06-07 23:34 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 29/32] JadePkg: Recover boot options when NVRAM cleared Nhi Pham
2021-06-07 23:46 ` Leif Lindholm
2021-06-15 16:52 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 30/32] AmpereSiliconPkg: Implement PlatformBootManagerLib for LinuxBoot Nhi Pham
2021-06-07 23:50 ` Leif Lindholm
2021-06-09 15:21 ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 31/32] Platform/Ampere: Introduce the LinuxBootPkg Nhi Pham
2021-06-07 23:51 ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 32/32] AmpereAltraPkg,JadePkg: Support LinuxBoot DSC/FDF build for Jade platform Nhi Pham
2021-06-07 23:58 ` Leif Lindholm
2021-06-09 15:20 ` Nhi Pham
2021-05-27 12:56 ` [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. " Leif Lindholm
2021-06-04 13:54 ` Leif Lindholm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cb426871-ca09-2c6e-6823-30b03004d30c@os.amperecomputing.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox