29#define TIME_UNITS_PER_SECOND 10000000
34STATIC UINT64 mTimerPeriod = 0;
39#define MAX_UINT48 0xFFFFFFFFFFFFULL
57 UINT64 MaxWatchdogOffsetValue;
59 UINT8 WatchdogArchRevision;
61 WatchdogIId =
MmioRead32 (GENERIC_WDOG_IID_REG);
62 WatchdogArchRevision = (WatchdogIId >> GENERIC_WDOG_IID_ARCH_REV_SHIFT) & GENERIC_WDOG_IID_ARCH_REV_MASK;
64 if (WatchdogArchRevision == 0) {
65 MaxWatchdogOffsetValue = MAX_UINT32;
67 MaxWatchdogOffsetValue = MAX_UINT48;
70 return MaxWatchdogOffsetValue;
75WatchdogWriteOffsetRegister (
79 MmioWrite32 (GENERIC_WDOG_OFFSET_REG_LOW, Value & MAX_UINT32);
81 MmioWrite32 (GENERIC_WDOG_OFFSET_REG_HIGH, (Value >> 32) & MAX_UINT16);
87WatchdogWriteCompareRegister (
91 MmioWrite32 (GENERIC_WDOG_COMPARE_VALUE_REG_LOW, Value & MAX_UINT32);
92 MmioWrite32 (GENERIC_WDOG_COMPARE_VALUE_REG_HIGH, (Value >> 32) & MAX_UINT32);
101 MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_ENABLED);
110 MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_DISABLED);
126 mExitedBootServices =
TRUE;
135WatchdogInterruptHandler (
136 IN HARDWARE_INTERRUPT_SOURCE Source,
140 STATIC CONST CHAR16 ResetString[] = L
"The generic watchdog timer ran out.";
144 mInterruptProtocol->EndOfInterrupt (mInterruptProtocol, Source);
152 if (mWatchdogNotify !=
NULL) {
153 mWatchdogNotify (mTimerPeriod + 1);
160 (CHAR16 *)ResetString
200 return EFI_INVALID_PARAMETER;
204 return EFI_ALREADY_STARTED;
232 IN UINT64 TimerPeriod
236 UINT64 MaxWatchdogOffsetValue;
237 UINT64 TimerFrequencyHz;
238 UINT64 NumTimerTicks;
242 if (mExitedBootServices && (TimerPeriod != 0)) {
245 return EFI_DEVICE_ERROR;
249 if (TimerPeriod == 0) {
256 TimerFrequencyHz = ArmGenericTimerGetTimerFreq ();
257 ASSERT (TimerFrequencyHz != 0);
258 mTimerPeriod = TimerPeriod;
259 NumTimerTicks = (TimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
265 if (NumTimerTicks > MaxWatchdogOffsetValue) {
270 WatchdogWriteOffsetRegister (MaxWatchdogOffsetValue);
272 SystemCount = ArmGenericTimerGetSystemCount ();
273 WatchdogWriteCompareRegister (SystemCount + NumTimerTicks);
275 WatchdogWriteOffsetRegister (NumTimerTicks);
303 OUT UINT64 *TimerPeriod
306 if (TimerPeriod ==
NULL) {
307 return EFI_INVALID_PARAMETER;
310 *TimerPeriod = mTimerPeriod;
355GenericWatchdogEntry (
363 Status =
gBS->LocateProtocol (
364 &gHardwareInterrupt2ProtocolGuid,
366 (VOID **)&mInterruptProtocol
376 Status = mInterruptProtocol->RegisterInterruptSource (
379 WatchdogInterruptHandler
381 if (EFI_ERROR (Status)) {
385 Status = mInterruptProtocol->SetTriggerType (
388 EFI_HARDWARE_INTERRUPT2_TRIGGER_EDGE_RISING
390 if (EFI_ERROR (Status)) {
391 goto UnregisterHandler;
398 Status =
gBS->InstallMultipleProtocolInterfaces (
400 &gEfiWatchdogTimerArchProtocolGuid,
404 if (EFI_ERROR (Status)) {
405 goto UnregisterHandler;
409 Status =
gBS->CreateEvent (
410 EVT_SIGNAL_EXIT_BOOT_SERVICES,
414 &mEfiExitBootServicesEvent
422 mInterruptProtocol->RegisterInterruptSource (
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
STATIC EFI_STATUS EFIAPI WatchdogRegisterHandler(IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction)
STATIC VOID EFIAPI WatchdogExitBootServicesEvent(IN EFI_EVENT Event, IN VOID *Context)
STATIC EFI_STATUS EFIAPI WatchdogGetTimerPeriod(IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, OUT UINT64 *TimerPeriod)
STATIC UINT64 GetMaxWatchdogOffsetRegisterValue(VOID)
STATIC EFI_STATUS EFIAPI WatchdogSetTimerPeriod(IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This, IN UINT64 TimerPeriod)
STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL mWatchdogTimer
UINT32 EFIAPI MmioRead32(IN UINTN Address)
UINT32 EFIAPI MmioWrite32(IN UINTN Address, IN UINT32 Value)
EFI_RUNTIME_SERVICES * gRT
#define ASSERT_EFI_ERROR(StatusParameter)
#define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid)
VOID(EFIAPI * EFI_WATCHDOG_TIMER_NOTIFY)(IN UINT64 Time)
#define FixedPcdGet32(TokenName)
VOID EFIAPI NotifyFunction(IN EFI_EVENT Event, IN VOID *Context)