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