]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / WatchdogTimerDxe / WatchdogTimer.c
CommitLineData
504214c4 1/** @file\r
96437c90 2 Implementation of Watchdog Timer Architectural Protocol using UEFI APIs.\r
d1102dba
LG
3\r
4Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
de4c8a30 6\r
504214c4 7**/\r
de4c8a30 8\r
4dd60a17 9#include "WatchdogTimer.h"\r
de4c8a30 10\r
11//\r
12// Handle for the Watchdog Timer Architectural Protocol instance produced by this driver\r
13//\r
96437c90 14EFI_HANDLE mWatchdogTimerHandle = NULL;\r
de4c8a30 15\r
16//\r
17// The Watchdog Timer Architectural Protocol instance produced by this driver\r
18//\r
19EFI_WATCHDOG_TIMER_ARCH_PROTOCOL mWatchdogTimer = {\r
20 WatchdogTimerDriverRegisterHandler,\r
21 WatchdogTimerDriverSetTimerPeriod,\r
22 WatchdogTimerDriverGetTimerPeriod\r
23};\r
24\r
25//\r
96437c90 26// The watchdog timer period in 100 ns units\r
de4c8a30 27//\r
96437c90 28UINT64 mWatchdogTimerPeriod = 0;\r
de4c8a30 29\r
30//\r
31// The notification function to call if the watchdig timer fires\r
32//\r
96437c90 33EFI_WATCHDOG_TIMER_NOTIFY mWatchdogTimerNotifyFunction = NULL;\r
de4c8a30 34\r
35//\r
36// The one-shot timer event that is armed when the watchdog timer is enabled\r
37//\r
96437c90 38EFI_EVENT mWatchdogTimerEvent;\r
de4c8a30 39\r
36093af9 40\r
41/**\r
96437c90 42 Notification function that is called if the watchdog timer is fired.\r
36093af9 43\r
96437c90 44 Notification function for the one-shot timer event that was signaled\r
45 when the watchdog timer expired. If a handler has been registered with\r
46 the Watchdog Timer Architectural Protocol, then that handler is called\r
47 passing in the time period that has passed that cause the watchdog timer\r
48 to fire. Then, a call to the Runtime Service ResetSystem() is made to\r
49 reset the platform.\r
36093af9 50\r
96437c90 51 @param Timer The one-shot timer event that was signaled when the\r
52 watchdog timer expired.\r
36093af9 53 @param Context The context that was registered when the event Timer was created.\r
54\r
36093af9 55**/\r
de4c8a30 56VOID\r
57EFIAPI\r
58WatchdogTimerDriverExpires (\r
59 IN EFI_EVENT Timer,\r
60 IN VOID *Context\r
61 )\r
de4c8a30 62{\r
f9876ecf 63 REPORT_STATUS_CODE (EFI_ERROR_CODE | EFI_ERROR_MINOR, (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_TIMER_EXPIRED));\r
de4c8a30 64\r
65 //\r
66 // If a notification function has been registered, then call it\r
67 //\r
68 if (mWatchdogTimerNotifyFunction != NULL) {\r
69 mWatchdogTimerNotifyFunction (mWatchdogTimerPeriod);\r
70 }\r
d1102dba 71\r
0a18956d 72 DEBUG ((EFI_D_ERROR, "Watchdog Timer resetting system\n"));\r
dd85e4b5 73\r
de4c8a30 74 //\r
75 // Reset the platform\r
76 //\r
77 gRT->ResetSystem (EfiResetCold, EFI_TIMEOUT, 0, NULL);\r
78}\r
79\r
ba237732 80\r
36093af9 81/**\r
96437c90 82 Registers a handler that is to be invoked when the watchdog timer fires.\r
83\r
de4c8a30 84 This function registers a handler that is to be invoked when the watchdog\r
85 timer fires. By default, the EFI_WATCHDOG_TIMER protocol will call the\r
86 Runtime Service ResetSystem() when the watchdog timer fires. If a\r
87 NotifyFunction is registered, then the NotifyFunction will be called before\r
88 the Runtime Service ResetSystem() is called. If NotifyFunction is NULL, then\r
89 the watchdog handler is unregistered. If a watchdog handler is registered,\r
90 then EFI_SUCCESS is returned. If an attempt is made to register a handler\r
91 when a handler is already registered, then EFI_ALREADY_STARTED is returned.\r
92 If an attempt is made to uninstall a handler when a handler is not installed,\r
93 then return EFI_INVALID_PARAMETER.\r
94\r
36093af9 95 @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.\r
96 @param NotifyFunction The function to call when the watchdog timer fires. If this\r
97 is NULL, then the handler will be unregistered.\r
de4c8a30 98\r
96437c90 99 @retval EFI_SUCCESS The watchdog timer handler was registered or unregistered.\r
100 @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already registered.\r
101 @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not previously registered.\r
de4c8a30 102\r
36093af9 103**/\r
104EFI_STATUS\r
105EFIAPI\r
106WatchdogTimerDriverRegisterHandler (\r
107 IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,\r
108 IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction\r
109 )\r
de4c8a30 110{\r
96437c90 111 //\r
112 // If NotifyFunction is NULL, and a handler was not previously registered,\r
113 // return EFI_INVALID_PARAMETER.\r
114 //\r
de4c8a30 115 if (NotifyFunction == NULL && mWatchdogTimerNotifyFunction == NULL) {\r
116 return EFI_INVALID_PARAMETER;\r
117 }\r
96437c90 118 //\r
119 // If NotifyFunction is not NULL, and a handler is already registered,\r
120 // return EFI_ALREADY_STARTED.\r
121 //\r
de4c8a30 122 if (NotifyFunction != NULL && mWatchdogTimerNotifyFunction != NULL) {\r
123 return EFI_ALREADY_STARTED;\r
124 }\r
125\r
126 mWatchdogTimerNotifyFunction = NotifyFunction;\r
127\r
128 return EFI_SUCCESS;\r
129}\r
130\r
36093af9 131/**\r
96437c90 132 Sets the amount of time in the future to fire the watchdog timer.\r
133\r
de4c8a30 134 This function sets the amount of time to wait before firing the watchdog\r
96437c90 135 timer to TimerPeriod 100 ns units. If TimerPeriod is 0, then the watchdog\r
de4c8a30 136 timer is disabled.\r
137\r
36093af9 138 @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.\r
96437c90 139 @param TimerPeriod The amount of time in 100 ns units to wait before the watchdog\r
36093af9 140 timer is fired. If TimerPeriod is zero, then the watchdog\r
141 timer is disabled.\r
de4c8a30 142\r
96437c90 143 @retval EFI_SUCCESS The watchdog timer has been programmed to fire in Time\r
144 100 ns units.\r
145 @retval EFI_DEVICE_ERROR A watchdog timer could not be programmed due to a device\r
36093af9 146 error.\r
de4c8a30 147\r
36093af9 148**/\r
149EFI_STATUS\r
150EFIAPI\r
151WatchdogTimerDriverSetTimerPeriod (\r
152 IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,\r
153 IN UINT64 TimerPeriod\r
154 )\r
de4c8a30 155{\r
156 mWatchdogTimerPeriod = TimerPeriod;\r
157\r
158 return gBS->SetTimer (\r
159 mWatchdogTimerEvent,\r
160 (mWatchdogTimerPeriod == 0) ? TimerCancel : TimerRelative,\r
161 mWatchdogTimerPeriod\r
162 );\r
163}\r
164\r
36093af9 165/**\r
96437c90 166 Retrieves the amount of time in 100 ns units that the system will wait before firing the watchdog timer.\r
167\r
de4c8a30 168 This function retrieves the amount of time the system will wait before firing\r
169 the watchdog timer. This period is returned in TimerPeriod, and EFI_SUCCESS\r
170 is returned. If TimerPeriod is NULL, then EFI_INVALID_PARAMETER is returned.\r
171\r
36093af9 172 @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.\r
96437c90 173 @param TimerPeriod A pointer to the amount of time in 100 ns units that the system\r
36093af9 174 will wait before the watchdog timer is fired. If TimerPeriod of\r
175 zero is returned, then the watchdog timer is disabled.\r
de4c8a30 176\r
96437c90 177 @retval EFI_SUCCESS The amount of time that the system will wait before\r
36093af9 178 firing the watchdog timer was returned in TimerPeriod.\r
96437c90 179 @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.\r
de4c8a30 180\r
36093af9 181**/\r
182EFI_STATUS\r
183EFIAPI\r
184WatchdogTimerDriverGetTimerPeriod (\r
185 IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,\r
186 IN UINT64 *TimerPeriod\r
187 )\r
de4c8a30 188{\r
189 if (TimerPeriod == NULL) {\r
190 return EFI_INVALID_PARAMETER;\r
191 }\r
192\r
193 *TimerPeriod = mWatchdogTimerPeriod;\r
194\r
195 return EFI_SUCCESS;\r
196}\r
197\r
36093af9 198/**\r
96437c90 199 Entry point of the Watchdog Timer Architectural Protocol driver.\r
36093af9 200\r
96437c90 201 @param ImageHandle The image handle of this driver.\r
202 @param SystemTable The pointer of EFI_SYSTEM_TABLE.\r
36093af9 203\r
96437c90 204 @retval EFI_SUCCESS Watchdog Timer Architectural Protocol successfully installed.\r
36093af9 205\r
206**/\r
de4c8a30 207EFI_STATUS\r
208EFIAPI\r
209WatchdogTimerDriverInitialize (\r
210 IN EFI_HANDLE ImageHandle,\r
211 IN EFI_SYSTEM_TABLE *SystemTable\r
212 )\r
de4c8a30 213{\r
214 EFI_STATUS Status;\r
215\r
de4c8a30 216 //\r
96437c90 217 // Make sure the Watchdog Timer Architectural Protocol has not been installed in the system yet.\r
de4c8a30 218 //\r
219 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);\r
220\r
221 //\r
96437c90 222 // Create the timer event to implement a simple watchdog timer\r
de4c8a30 223 //\r
224 Status = gBS->CreateEvent (\r
225 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
226 TPL_NOTIFY,\r
227 WatchdogTimerDriverExpires,\r
228 NULL,\r
229 &mWatchdogTimerEvent\r
230 );\r
231 ASSERT_EFI_ERROR (Status);\r
232\r
233 //\r
234 // Install the Watchdog Timer Arch Protocol onto a new handle\r
235 //\r
236 Status = gBS->InstallMultipleProtocolInterfaces (\r
237 &mWatchdogTimerHandle,\r
238 &gEfiWatchdogTimerArchProtocolGuid,\r
239 &mWatchdogTimer,\r
240 NULL\r
241 );\r
242 ASSERT_EFI_ERROR (Status);\r
243\r
96437c90 244 return EFI_SUCCESS;\r
de4c8a30 245}\r