summaryrefslogtreecommitdiffstats
path: root/ArmPkg/Drivers/GenericWatchdogDxe
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2018-12-18 14:10:14 +0100
committerArd Biesheuvel <ard.biesheuvel@linaro.org>2018-12-20 12:41:21 +0100
commitba808d11f6a3206cbf4bee8340c7a26b2b19e809 (patch)
tree87bc364475a913288573a9dd319da79531206e62 /ArmPkg/Drivers/GenericWatchdogDxe
parentd3b05936d961fa9530ae7a5ca6363abd45864b83 (diff)
downloadedk2-ba808d11f6a3206cbf4bee8340c7a26b2b19e809.tar.gz
edk2-ba808d11f6a3206cbf4bee8340c7a26b2b19e809.tar.bz2
edk2-ba808d11f6a3206cbf4bee8340c7a26b2b19e809.zip
ArmPkg/GenericWatchdogDxe: implement RegisterHandler() method
Even though UEFI does not appear to use it, let's implement the complete PI watchdog protocol, including handler registration, which will be invoked before the ResetSystem() runtime service when the watchdog timer expires. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Diffstat (limited to 'ArmPkg/Drivers/GenericWatchdogDxe')
-rw-r--r--ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
index 285727fc0e..a1ef0363eb 100644
--- a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
+++ b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
@@ -42,6 +42,7 @@ STATIC UINTN mTimerFrequencyHz = 0;
STATIC UINT64 mNumTimerTicks = 0;
STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;
+STATIC EFI_WATCHDOG_TIMER_NOTIFY mWatchdogNotify;
STATIC
VOID
@@ -107,17 +108,25 @@ WatchdogInterruptHandler (
)
{
STATIC CONST CHAR16 ResetString[]= L"The generic watchdog timer ran out.";
+ UINT64 TimerPeriod;
WatchdogDisable ();
mInterruptProtocol->EndOfInterrupt (mInterruptProtocol, Source);
- gRT->ResetSystem (
- EfiResetCold,
- EFI_TIMEOUT,
- StrSize (ResetString),
- (VOID *) &ResetString
- );
+ //
+ // The notify function should be called with the elapsed number of ticks
+ // since the watchdog was armed, which should exceed the timer period.
+ // We don't actually know the elapsed number of ticks, so let's return
+ // the timer period plus 1.
+ //
+ if (mWatchdogNotify != NULL) {
+ TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);
+ mWatchdogNotify (TimerPeriod + 1);
+ }
+
+ gRT->ResetSystem (EfiResetCold, EFI_TIMEOUT, StrSize (ResetString),
+ (CHAR16 *)ResetString);
// If we got here then the reset didn't work
ASSERT (FALSE);
@@ -155,9 +164,16 @@ WatchdogRegisterHandler (
IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction
)
{
- // ERROR: This function is not supported.
- // The watchdog will reset the board
- return EFI_UNSUPPORTED;
+ if (mWatchdogNotify == NULL && NotifyFunction == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mWatchdogNotify != NULL && NotifyFunction != NULL) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ mWatchdogNotify = NotifyFunction;
+ return EFI_SUCCESS;
}
/**