ArmPkg/GenericWatchdogDxe: implement RegisterHandler() method
[mirror_edk2.git] / ArmPkg / Drivers / GenericWatchdogDxe / GenericWatchdogDxe.c
index 285727f..a1ef036 100644 (file)
@@ -42,6 +42,7 @@ STATIC UINTN mTimerFrequencyHz = 0;
 STATIC UINT64 mNumTimerTicks = 0;\r
 \r
 STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;\r
+STATIC EFI_WATCHDOG_TIMER_NOTIFY        mWatchdogNotify;\r
 \r
 STATIC\r
 VOID\r
@@ -107,17 +108,25 @@ WatchdogInterruptHandler (
   )\r
 {\r
   STATIC CONST CHAR16 ResetString[]= L"The generic watchdog timer ran out.";\r
+  UINT64              TimerPeriod;\r
 \r
   WatchdogDisable ();\r
 \r
   mInterruptProtocol->EndOfInterrupt (mInterruptProtocol, Source);\r
 \r
-  gRT->ResetSystem (\r
-         EfiResetCold,\r
-         EFI_TIMEOUT,\r
-         StrSize (ResetString),\r
-         (VOID *) &ResetString\r
-         );\r
+  //\r
+  // The notify function should be called with the elapsed number of ticks\r
+  // since the watchdog was armed, which should exceed the timer period.\r
+  // We don't actually know the elapsed number of ticks, so let's return\r
+  // the timer period plus 1.\r
+  //\r
+  if (mWatchdogNotify != NULL) {\r
+    TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);\r
+    mWatchdogNotify (TimerPeriod + 1);\r
+  }\r
+\r
+  gRT->ResetSystem (EfiResetCold, EFI_TIMEOUT, StrSize (ResetString),\r
+         (CHAR16 *)ResetString);\r
 \r
   // If we got here then the reset didn't work\r
   ASSERT (FALSE);\r
@@ -155,9 +164,16 @@ WatchdogRegisterHandler (
   IN EFI_WATCHDOG_TIMER_NOTIFY                NotifyFunction\r
   )\r
 {\r
-  // ERROR: This function is not supported.\r
-  // The watchdog will reset the board\r
-  return EFI_UNSUPPORTED;\r
+  if (mWatchdogNotify == NULL && NotifyFunction == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (mWatchdogNotify != NULL && NotifyFunction != NULL) {\r
+    return EFI_ALREADY_STARTED;\r
+  }\r
+\r
+  mWatchdogNotify = NotifyFunction;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r