gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum|26|UINT32|0x00000040\r
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|27|UINT32|0x00000041\r
\r
+ #\r
+ # ARM Generic Watchdog\r
+ #\r
+\r
+ gArmTokenSpaceGuid.PcdGenericWatchdogControlBase|0x2A440000|UINT32|0x00000007\r
+ gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase|0x2A450000|UINT32|0x00000008\r
+ gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum|93|UINT32|0x00000009\r
+\r
#\r
# ARM Generic Interrupt Controller\r
#\r
ArmPkg/Drivers/ArmGic/ArmGicDxe.inf\r
ArmPkg/Drivers/ArmGic/ArmGicLib.inf\r
ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf\r
+ ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf\r
ArmPkg/Drivers/TimerDxe/TimerDxe.inf\r
\r
ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf\r
--- /dev/null
+/** @file\r
+*\r
+* Copyright (c) 2013-2014, ARM Limited. All rights reserved.\r
+*\r
+* This program and the accompanying materials\r
+* are licensed and made available under the terms and conditions of the BSD\r
+* License which accompanies this distribution. The full text of the license\r
+* may be found at http://opensource.org/licenses/bsd-license.php\r
+*\r
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+*\r
+**/\r
+#ifndef __GENERIC_WATCHDOG_H__\r
+#define __GENERIC_WATCHDOG_H__\r
+\r
+// Refresh Frame:\r
+#define GENERIC_WDOG_REFRESH_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogRefreshBase) + 0x000)\r
+\r
+// Control Frame:\r
+#define GENERIC_WDOG_CONTROL_STATUS_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x000)\r
+#define GENERIC_WDOG_OFFSET_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x008)\r
+#define GENERIC_WDOG_COMPARE_VALUE_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x010)\r
+\r
+// Values of bit 0 of the Control/Status Register\r
+#define GENERIC_WDOG_ENABLED 1\r
+#define GENERIC_WDOG_DISABLED 0\r
+\r
+#endif // __GENERIC_WATCHDOG_H__\r
--- /dev/null
+/** @file\r
+*\r
+* Copyright (c) 2013-2014, ARM Limited. All rights reserved.\r
+*\r
+* This program and the accompanying materials\r
+* are licensed and made available under the terms and conditions of the BSD\r
+* License which accompanies this distribution. The full text of the license\r
+* may be found at http://opensource.org/licenses/bsd-license.php\r
+*\r
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+*\r
+**/\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/ArmGenericTimerCounterLib.h>\r
+\r
+#include <Protocol/WatchdogTimer.h>\r
+#include <Protocol/HardwareInterrupt.h>\r
+\r
+#include "GenericWatchdog.h"\r
+\r
+// The number of 100ns periods (the unit of time passed to these functions)\r
+// in a second\r
+#define TIME_UNITS_PER_SECOND 10000000\r
+\r
+// Tick frequency of the generic timer that is the basis of the generic watchdog\r
+UINTN mTimerFrequencyHz = 0;\r
+\r
+// In cases where the compare register was set manually, information about\r
+// how long the watchdog was asked to wait cannot be retrieved from hardware.\r
+// It is therefore stored here. 0 means the timer is not running.\r
+UINT64 mNumTimerTicks = 0;\r
+\r
+EFI_HARDWARE_INTERRUPT_PROTOCOL *mInterruptProtocol;\r
+\r
+EFI_STATUS\r
+WatchdogWriteOffsetRegister (\r
+ UINT32 Value\r
+ )\r
+{\r
+ return MmioWrite32 (GENERIC_WDOG_OFFSET_REG, Value);\r
+}\r
+\r
+EFI_STATUS\r
+WatchdogWriteCompareRegister (\r
+ UINT64 Value\r
+ )\r
+{\r
+ return MmioWrite64 (GENERIC_WDOG_COMPARE_VALUE_REG, Value);\r
+}\r
+\r
+EFI_STATUS\r
+WatchdogEnable (\r
+ VOID\r
+ )\r
+{\r
+ return MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_ENABLED);\r
+}\r
+\r
+EFI_STATUS\r
+WatchdogDisable (\r
+ VOID\r
+ )\r
+{\r
+ return MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_DISABLED);\r
+}\r
+\r
+/**\r
+ On exiting boot services we must make sure the Watchdog Timer\r
+ is stopped.\r
+**/\r
+VOID\r
+EFIAPI\r
+WatchdogExitBootServicesEvent (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ WatchdogDisable ();\r
+ mNumTimerTicks = 0;\r
+}\r
+\r
+/*\r
+ This function is called when the watchdog's first signal (WS0) goes high.\r
+ It uses the ResetSystem Runtime Service to reset the board.\r
+*/\r
+VOID\r
+EFIAPI\r
+WatchdogInterruptHandler (\r
+ IN HARDWARE_INTERRUPT_SOURCE Source,\r
+ IN EFI_SYSTEM_CONTEXT SystemContext\r
+ )\r
+{\r
+ STATIC CONST CHAR16 ResetString[] = L"The generic watchdog timer ran out.";\r
+\r
+ WatchdogDisable ();\r
+\r
+ mInterruptProtocol->EndOfInterrupt (mInterruptProtocol, Source);\r
+\r
+ gRT->ResetSystem (\r
+ EfiResetCold,\r
+ EFI_TIMEOUT,\r
+ StrSize (ResetString),\r
+ &ResetString\r
+ );\r
+\r
+ // If we got here then the reset didn't work\r
+ ASSERT (FALSE);\r
+}\r
+\r
+/**\r
+ This function registers the handler NotifyFunction so it is called every time\r
+ the watchdog timer expires. It also passes the amount of time since the last\r
+ handler call to the NotifyFunction.\r
+ If NotifyFunction is not NULL and a handler is not already registered,\r
+ then the new handler is registered and EFI_SUCCESS is returned.\r
+ If NotifyFunction is NULL, and a handler is already registered,\r
+ then that handler is unregistered.\r
+ If an attempt is made to register a handler when a handler is already registered,\r
+ then EFI_ALREADY_STARTED is returned.\r
+ If an attempt is made to unregister a handler when a handler is not registered,\r
+ then EFI_INVALID_PARAMETER is returned.\r
+\r
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.\r
+ @param NotifyFunction The function to call when a timer interrupt fires.\r
+ This function executes at TPL_HIGH_LEVEL. The DXE\r
+ Core will register a handler for the timer interrupt,\r
+ so it can know how much time has passed. This\r
+ information is used to signal timer based events.\r
+ NULL will unregister the handler.\r
+\r
+ @retval EFI_SUCCESS The watchdog timer handler was registered.\r
+ @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already\r
+ registered.\r
+ @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not\r
+ previously registered.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WatchdogRegisterHandler (\r
+ IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,\r
+ 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
+}\r
+\r
+/**\r
+ This function sets the amount of time to wait before firing the watchdog\r
+ timer to TimerPeriod 100 nS units. If TimerPeriod is 0, then the watchdog\r
+ timer is disabled.\r
+\r
+ @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.\r
+ @param TimerPeriod The amount of time in 100 nS units to wait before the watchdog\r
+ timer is fired. If TimerPeriod is zero, then the watchdog\r
+ timer is disabled.\r
+\r
+ @retval EFI_SUCCESS The watchdog timer has been programmed to fire in Time\r
+ 100 nS units.\r
+ @retval EFI_DEVICE_ERROR A watchdog timer could not be programmed due to a device\r
+ error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WatchdogSetTimerPeriod (\r
+ IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,\r
+ IN UINT64 TimerPeriod // In 100ns units\r
+ )\r
+{\r
+ UINTN TimerVal;\r
+ EFI_STATUS Status;\r
+\r
+ // if TimerPerdiod is 0, this is a request to stop the watchdog.\r
+ if (TimerPeriod == 0) {\r
+ mNumTimerTicks = 0;\r
+ return WatchdogDisable ();\r
+ }\r
+\r
+ // Work out how many timer ticks will equate to TimerPeriod\r
+ mNumTimerTicks = (mTimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;\r
+\r
+ //\r
+ // If the number of required ticks is greater than the max number the\r
+ // watchdog's offset register (WOR) can hold, we need to manually compute and\r
+ // set the compare register (WCV)\r
+ //\r
+ if (mNumTimerTicks > MAX_UINT32) {\r
+ //\r
+ // We need to enable the watchdog *before* writing to the compare register,\r
+ // because enabling the watchdog causes an "explicit refresh", which\r
+ // clobbers the compare register (WCV). In order to make sure this doesn't\r
+ // trigger an interrupt, set the offset to max.\r
+ //\r
+ Status = WatchdogWriteOffsetRegister (MAX_UINT32);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ WatchdogEnable ();\r
+ TimerVal = ArmGenericTimerGetTimerVal ();\r
+ Status = WatchdogWriteCompareRegister (TimerVal + mNumTimerTicks);\r
+ } else {\r
+ Status = WatchdogWriteOffsetRegister ((UINT32)mNumTimerTicks);\r
+ WatchdogEnable ();\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function retrieves the period of timer interrupts in 100 ns units,\r
+ returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod\r
+ is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is\r
+ returned, then the timer is currently disabled.\r
+\r
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.\r
+ @param TimerPeriod A pointer to the timer period to retrieve in 100\r
+ ns units. If 0 is returned, then the timer is\r
+ currently disabled.\r
+\r
+\r
+ @retval EFI_SUCCESS The timer period was returned in TimerPeriod.\r
+ @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WatchdogGetTimerPeriod (\r
+ IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,\r
+ OUT UINT64 *TimerPeriod\r
+ )\r
+{\r
+ if (TimerPeriod == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Interface structure for the Watchdog Architectural Protocol.\r
+\r
+ @par Protocol Description:\r
+ This protocol provides a service to set the amount of time to wait\r
+ before firing the watchdog timer, and it also provides a service to\r
+ register a handler that is invoked when the watchdog timer fires.\r
+\r
+ @par When the watchdog timer fires, control will be passed to a handler\r
+ if one has been registered. If no handler has been registered,\r
+ or the registered handler returns, then the system will be\r
+ reset by calling the Runtime Service ResetSystem().\r
+\r
+ @param RegisterHandler\r
+ Registers a handler that will be called each time the\r
+ watchdogtimer interrupt fires. TimerPeriod defines the minimum\r
+ time between timer interrupts, so TimerPeriod will also\r
+ be the minimum time between calls to the registered\r
+ handler.\r
+ NOTE: If the watchdog resets the system in hardware, then\r
+ this function will not have any chance of executing.\r
+\r
+ @param SetTimerPeriod\r
+ Sets the period of the timer interrupt in 100 nS units.\r
+ This function is optional, and may return EFI_UNSUPPORTED.\r
+ If this function is supported, then the timer period will\r
+ be rounded up to the nearest supported timer period.\r
+\r
+ @param GetTimerPeriod\r
+ Retrieves the period of the timer interrupt in 100 nS units.\r
+\r
+**/\r
+EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = {\r
+ (EFI_WATCHDOG_TIMER_REGISTER_HANDLER) WatchdogRegisterHandler,\r
+ (EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD) WatchdogSetTimerPeriod,\r
+ (EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD) WatchdogGetTimerPeriod\r
+};\r
+\r
+EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GenericWatchdogEntry (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE Handle;\r
+\r
+ //\r
+ // Make sure the Watchdog Timer Architectural Protocol has not been installed\r
+ // in the system yet.\r
+ // This will avoid conflicts with the universal watchdog\r
+ //\r
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);\r
+\r
+ mTimerFrequencyHz = ArmGenericTimerGetTimerFreq ();\r
+ ASSERT (mTimerFrequencyHz != 0);\r
+\r
+ // Register for an ExitBootServicesEvent\r
+ Status = gBS->CreateEvent (\r
+ EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY,\r
+ WatchdogExitBootServicesEvent, NULL, &EfiExitBootServicesEvent\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ // Install interrupt handler\r
+ Status = gBS->LocateProtocol (\r
+ &gHardwareInterruptProtocolGuid,\r
+ NULL,\r
+ (VOID **)&mInterruptProtocol\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = mInterruptProtocol->RegisterInterruptSource (\r
+ mInterruptProtocol,\r
+ FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),\r
+ WatchdogInterruptHandler\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ // Install the Timer Architectural Protocol onto a new handle\r
+ Handle = NULL;\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Handle,\r
+ &gEfiWatchdogTimerArchProtocolGuid, &gWatchdogTimer,\r
+ NULL\r
+ );\r
+ }\r
+ }\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ // The watchdog failed to initialize\r
+ ASSERT (FALSE);\r
+ }\r
+\r
+ mNumTimerTicks = 0;\r
+ WatchdogDisable ();\r
+\r
+ return Status;\r
+}\r
--- /dev/null
+#\r
+# Copyright (c) 2013-2014, ARM Limited. All rights reserved.\r
+#\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010016\r
+ BASE_NAME = GenericWatchdogDxe\r
+ FILE_GUID = 0619f5c2-4858-4caa-a86a-73a21a18df6b\r
+ MODULE_TYPE = DXE_DRIVER\r
+ VERSION_STRING = 1.0\r
+\r
+ ENTRY_POINT = GenericWatchdogEntry\r
+\r
+[Sources.common]\r
+ GenericWatchdogDxe.c\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ EmbeddedPkg/EmbeddedPkg.dec\r
+ ArmPkg/ArmPkg.dec\r
+ ArmPlatformPkg/ArmPlatformPkg.dec\r
+\r
+[LibraryClasses]\r
+ ArmGenericTimerCounterLib\r
+ BaseLib\r
+ BaseMemoryLib\r
+ DebugLib\r
+ IoLib\r
+ PcdLib\r
+ UefiLib\r
+ UefiBootServicesTableLib\r
+ UefiDriverEntryPoint\r
+ UefiRuntimeServicesTableLib\r
+\r
+[Pcd.common]\r
+ gArmTokenSpaceGuid.PcdGenericWatchdogControlBase\r
+ gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase\r
+ gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum\r
+\r
+[Protocols]\r
+ gEfiWatchdogTimerArchProtocolGuid\r
+ gHardwareInterruptProtocolGuid\r
+\r
+[Depex]\r
+ gHardwareInterruptProtocolGuid\r
gArmJunoTokenSpaceGuid = { 0xa1147a20, 0x3144, 0x4f8d, { 0x82, 0x95, 0xb4, 0x83, 0x11, 0xc8, 0xe4, 0xa4 } }\r
\r
[PcdsFixedAtBuild.common]\r
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogControlBase|0x2A440000|UINT32|0x00000001\r
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogRefreshBase|0x2A450000|UINT32|0x00000002\r
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum|93|UINT32|0x00000003\r
-\r
gArmJunoTokenSpaceGuid.PcdSynopsysUsbOhciBaseAddress|0x7FFB0000|UINT32|0x00000004\r
gArmJunoTokenSpaceGuid.PcdSynopsysUsbEhciBaseAddress|0x7FFC0000|UINT32|0x00000005\r
ArmPkg/Drivers/ArmGic/ArmGicDxe.inf\r
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf\r
ArmPkg/Drivers/TimerDxe/TimerDxe.inf\r
- ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf\r
+ ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf\r
\r
#\r
# Semi-hosting filesystem\r
\r
INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf\r
INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf\r
- INF ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf\r
+ INF ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf\r
\r
# NOR Flash driver\r
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf\r
+++ /dev/null
-/** @file\r
-*\r
-* Copyright (c) 2013-2014, ARM Limited. All rights reserved.\r
-*\r
-* This program and the accompanying materials\r
-* are licensed and made available under the terms and conditions of the BSD\r
-* License which accompanies this distribution. The full text of the license\r
-* may be found at http://opensource.org/licenses/bsd-license.php\r
-*\r
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-*\r
-**/\r
-\r
-#include <PiDxe.h>\r
-\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/IoLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/ArmGenericTimerCounterLib.h>\r
-\r
-#include <Protocol/WatchdogTimer.h>\r
-#include <Protocol/HardwareInterrupt.h>\r
-\r
-#include <Drivers/GenericWatchdog.h>\r
-\r
-// The number of 100ns periods (the unit of time passed to these functions)\r
-// in a second\r
-#define TIME_UNITS_PER_SECOND 10000000\r
-\r
-// Tick frequency of the generic timer that is the basis of the generic watchdog\r
-UINTN mTimerFrequencyHz = 0;\r
-\r
-// In cases where the compare register was set manually, information about\r
-// how long the watchdog was asked to wait cannot be retrieved from hardware.\r
-// It is therefore stored here. 0 means the timer is not running.\r
-UINT64 mNumTimerTicks = 0;\r
-\r
-EFI_HARDWARE_INTERRUPT_PROTOCOL *mInterruptProtocol;\r
-\r
-EFI_STATUS\r
-WatchdogWriteOffsetRegister (\r
- UINT32 Value\r
- )\r
-{\r
- return MmioWrite32 (GENERIC_WDOG_OFFSET_REG, Value);\r
-}\r
-\r
-EFI_STATUS\r
-WatchdogWriteCompareRegister (\r
- UINT64 Value\r
- )\r
-{\r
- return MmioWrite64 (GENERIC_WDOG_COMPARE_VALUE_REG, Value);\r
-}\r
-\r
-EFI_STATUS\r
-WatchdogEnable (\r
- VOID\r
- )\r
-{\r
- return MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_ENABLED);\r
-}\r
-\r
-EFI_STATUS\r
-WatchdogDisable (\r
- VOID\r
- )\r
-{\r
- return MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_DISABLED);\r
-}\r
-\r
-/**\r
- On exiting boot services we must make sure the Watchdog Timer\r
- is stopped.\r
-**/\r
-VOID\r
-EFIAPI\r
-WatchdogExitBootServicesEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- WatchdogDisable ();\r
- mNumTimerTicks = 0;\r
-}\r
-\r
-/*\r
- This function is called when the watchdog's first signal (WS0) goes high.\r
- It uses the ResetSystem Runtime Service to reset the board.\r
-*/\r
-VOID\r
-EFIAPI\r
-WatchdogInterruptHandler (\r
- IN HARDWARE_INTERRUPT_SOURCE Source,\r
- IN EFI_SYSTEM_CONTEXT SystemContext\r
- )\r
-{\r
- STATIC CONST CHAR16 ResetString[] = L"The generic watchdog timer ran out.";\r
-\r
- WatchdogDisable ();\r
-\r
- mInterruptProtocol->EndOfInterrupt (mInterruptProtocol, Source);\r
-\r
- gRT->ResetSystem (\r
- EfiResetCold,\r
- EFI_TIMEOUT,\r
- StrSize (ResetString),\r
- &ResetString\r
- );\r
-\r
- // If we got here then the reset didn't work\r
- ASSERT (FALSE);\r
-}\r
-\r
-/**\r
- This function registers the handler NotifyFunction so it is called every time\r
- the watchdog timer expires. It also passes the amount of time since the last\r
- handler call to the NotifyFunction.\r
- If NotifyFunction is not NULL and a handler is not already registered,\r
- then the new handler is registered and EFI_SUCCESS is returned.\r
- If NotifyFunction is NULL, and a handler is already registered,\r
- then that handler is unregistered.\r
- If an attempt is made to register a handler when a handler is already registered,\r
- then EFI_ALREADY_STARTED is returned.\r
- If an attempt is made to unregister a handler when a handler is not registered,\r
- then EFI_INVALID_PARAMETER is returned.\r
-\r
- @param This The EFI_TIMER_ARCH_PROTOCOL instance.\r
- @param NotifyFunction The function to call when a timer interrupt fires.\r
- This function executes at TPL_HIGH_LEVEL. The DXE\r
- Core will register a handler for the timer interrupt,\r
- so it can know how much time has passed. This\r
- information is used to signal timer based events.\r
- NULL will unregister the handler.\r
-\r
- @retval EFI_SUCCESS The watchdog timer handler was registered.\r
- @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already\r
- registered.\r
- @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not\r
- previously registered.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-WatchdogRegisterHandler (\r
- IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,\r
- 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
-}\r
-\r
-/**\r
- This function sets the amount of time to wait before firing the watchdog\r
- timer to TimerPeriod 100 nS units. If TimerPeriod is 0, then the watchdog\r
- timer is disabled.\r
-\r
- @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.\r
- @param TimerPeriod The amount of time in 100 nS units to wait before the watchdog\r
- timer is fired. If TimerPeriod is zero, then the watchdog\r
- timer is disabled.\r
-\r
- @retval EFI_SUCCESS The watchdog timer has been programmed to fire in Time\r
- 100 nS units.\r
- @retval EFI_DEVICE_ERROR A watchdog timer could not be programmed due to a device\r
- error.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-WatchdogSetTimerPeriod (\r
- IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,\r
- IN UINT64 TimerPeriod // In 100ns units\r
- )\r
-{\r
- UINTN TimerVal;\r
- EFI_STATUS Status;\r
-\r
- // if TimerPerdiod is 0, this is a request to stop the watchdog.\r
- if (TimerPeriod == 0) {\r
- mNumTimerTicks = 0;\r
- return WatchdogDisable ();\r
- }\r
-\r
- // Work out how many timer ticks will equate to TimerPeriod\r
- mNumTimerTicks = (mTimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;\r
-\r
- //\r
- // If the number of required ticks is greater than the max number the\r
- // watchdog's offset register (WOR) can hold, we need to manually compute and\r
- // set the compare register (WCV)\r
- //\r
- if (mNumTimerTicks > MAX_UINT32) {\r
- //\r
- // We need to enable the watchdog *before* writing to the compare register,\r
- // because enabling the watchdog causes an "explicit refresh", which\r
- // clobbers the compare register (WCV). In order to make sure this doesn't\r
- // trigger an interrupt, set the offset to max.\r
- //\r
- Status = WatchdogWriteOffsetRegister (MAX_UINT32);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- WatchdogEnable ();\r
- TimerVal = ArmGenericTimerGetTimerVal ();\r
- Status = WatchdogWriteCompareRegister (TimerVal + mNumTimerTicks);\r
- } else {\r
- Status = WatchdogWriteOffsetRegister ((UINT32)mNumTimerTicks);\r
- WatchdogEnable ();\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- This function retrieves the period of timer interrupts in 100 ns units,\r
- returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod\r
- is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is\r
- returned, then the timer is currently disabled.\r
-\r
- @param This The EFI_TIMER_ARCH_PROTOCOL instance.\r
- @param TimerPeriod A pointer to the timer period to retrieve in 100\r
- ns units. If 0 is returned, then the timer is\r
- currently disabled.\r
-\r
-\r
- @retval EFI_SUCCESS The timer period was returned in TimerPeriod.\r
- @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-WatchdogGetTimerPeriod (\r
- IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,\r
- OUT UINT64 *TimerPeriod\r
- )\r
-{\r
- if (TimerPeriod == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Interface structure for the Watchdog Architectural Protocol.\r
-\r
- @par Protocol Description:\r
- This protocol provides a service to set the amount of time to wait\r
- before firing the watchdog timer, and it also provides a service to\r
- register a handler that is invoked when the watchdog timer fires.\r
-\r
- @par When the watchdog timer fires, control will be passed to a handler\r
- if one has been registered. If no handler has been registered,\r
- or the registered handler returns, then the system will be\r
- reset by calling the Runtime Service ResetSystem().\r
-\r
- @param RegisterHandler\r
- Registers a handler that will be called each time the\r
- watchdogtimer interrupt fires. TimerPeriod defines the minimum\r
- time between timer interrupts, so TimerPeriod will also\r
- be the minimum time between calls to the registered\r
- handler.\r
- NOTE: If the watchdog resets the system in hardware, then\r
- this function will not have any chance of executing.\r
-\r
- @param SetTimerPeriod\r
- Sets the period of the timer interrupt in 100 nS units.\r
- This function is optional, and may return EFI_UNSUPPORTED.\r
- If this function is supported, then the timer period will\r
- be rounded up to the nearest supported timer period.\r
-\r
- @param GetTimerPeriod\r
- Retrieves the period of the timer interrupt in 100 nS units.\r
-\r
-**/\r
-EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = {\r
- (EFI_WATCHDOG_TIMER_REGISTER_HANDLER) WatchdogRegisterHandler,\r
- (EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD) WatchdogSetTimerPeriod,\r
- (EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD) WatchdogGetTimerPeriod\r
-};\r
-\r
-EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-GenericWatchdogEntry (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HANDLE Handle;\r
-\r
- //\r
- // Make sure the Watchdog Timer Architectural Protocol has not been installed\r
- // in the system yet.\r
- // This will avoid conflicts with the universal watchdog\r
- //\r
- ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);\r
-\r
- mTimerFrequencyHz = ArmGenericTimerGetTimerFreq ();\r
- ASSERT (mTimerFrequencyHz != 0);\r
-\r
- // Register for an ExitBootServicesEvent\r
- Status = gBS->CreateEvent (\r
- EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY,\r
- WatchdogExitBootServicesEvent, NULL, &EfiExitBootServicesEvent\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- // Install interrupt handler\r
- Status = gBS->LocateProtocol (\r
- &gHardwareInterruptProtocolGuid,\r
- NULL,\r
- (VOID **)&mInterruptProtocol\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = mInterruptProtocol->RegisterInterruptSource (\r
- mInterruptProtocol,\r
- FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),\r
- WatchdogInterruptHandler\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- // Install the Timer Architectural Protocol onto a new handle\r
- Handle = NULL;\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &Handle,\r
- &gEfiWatchdogTimerArchProtocolGuid, &gWatchdogTimer,\r
- NULL\r
- );\r
- }\r
- }\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- // The watchdog failed to initialize\r
- ASSERT (FALSE);\r
- }\r
-\r
- mNumTimerTicks = 0;\r
- WatchdogDisable ();\r
-\r
- return Status;\r
-}\r
+++ /dev/null
-#\r
-# Copyright (c) 2013-2014, ARM Limited. All rights reserved.\r
-#\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-\r
-[Defines]\r
- INF_VERSION = 0x00010016\r
- BASE_NAME = GenericWatchdogDxe\r
- FILE_GUID = 0619f5c2-4858-4caa-a86a-73a21a18df6b\r
- MODULE_TYPE = DXE_DRIVER\r
- VERSION_STRING = 1.0\r
-\r
- ENTRY_POINT = GenericWatchdogEntry\r
-\r
-[Sources.common]\r
- GenericWatchdogDxe.c\r
-\r
-[Packages]\r
- MdePkg/MdePkg.dec\r
- EmbeddedPkg/EmbeddedPkg.dec\r
- ArmPkg/ArmPkg.dec\r
- ArmPlatformPkg/ArmPlatformPkg.dec\r
- ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec\r
-\r
-[LibraryClasses]\r
- ArmGenericTimerCounterLib\r
- BaseLib\r
- BaseMemoryLib\r
- DebugLib\r
- IoLib\r
- PcdLib\r
- UefiLib\r
- UefiBootServicesTableLib\r
- UefiDriverEntryPoint\r
- UefiRuntimeServicesTableLib\r
-\r
-[FixedPcd]\r
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogControlBase\r
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogRefreshBase\r
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum\r
-\r
-[Protocols]\r
- gEfiWatchdogTimerArchProtocolGuid\r
- gHardwareInterruptProtocolGuid\r
-\r
-[Depex]\r
- gHardwareInterruptProtocolGuid\r
+++ /dev/null
-/** @file\r
-*\r
-* Copyright (c) 2013-2014, ARM Limited. All rights reserved.\r
-*\r
-* This program and the accompanying materials\r
-* are licensed and made available under the terms and conditions of the BSD\r
-* License which accompanies this distribution. The full text of the license\r
-* may be found at http://opensource.org/licenses/bsd-license.php\r
-*\r
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-*\r
-**/\r
-#ifndef __GENERIC_WATCHDOG_H__\r
-#define __GENERIC_WATCHDOG_H__\r
-\r
-// Refresh Frame:\r
-#define GENERIC_WDOG_REFRESH_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogRefreshBase) + 0x000)\r
-\r
-// Control Frame:\r
-#define GENERIC_WDOG_CONTROL_STATUS_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x000)\r
-#define GENERIC_WDOG_OFFSET_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x008)\r
-#define GENERIC_WDOG_COMPARE_VALUE_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x010)\r
-\r
-// Values of bit 0 of the Control/Status Register\r
-#define GENERIC_WDOG_ENABLED 1\r
-#define GENERIC_WDOG_DISABLED 0\r
-\r
-#endif // __GENERIC_WATCHDOG_H__\r