]>
Commit | Line | Data |
---|---|---|
504214c4 | 1 | /** @file\r |
96437c90 | 2 | Implementation of Watchdog Timer Architectural Protocol using UEFI APIs.\r |
504214c4 LG |
3 | \r |
4 | Copyright (c) 2006 - 2008, Intel Corporation\r | |
de4c8a30 | 5 | All rights reserved. This program and the accompanying materials\r |
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 |
ba237732 | 69 | REPORT_STATUS_CODE (EFI_ERROR_CODE | EFI_ERROR_MINOR, PcdGet32 (PcdStatusCodeValueEfiWatchDogTimerExpired));\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 | |
77 | //\r | |
78 | // Reset the platform\r | |
79 | //\r | |
80 | gRT->ResetSystem (EfiResetCold, EFI_TIMEOUT, 0, NULL);\r | |
81 | }\r | |
82 | \r | |
ba237732 | 83 | \r |
36093af9 | 84 | /**\r |
96437c90 | 85 | Registers a handler that is to be invoked when the watchdog timer fires.\r |
86 | \r | |
de4c8a30 | 87 | This function registers a handler that is to be invoked when the watchdog\r |
88 | timer fires. By default, the EFI_WATCHDOG_TIMER protocol will call the\r | |
89 | Runtime Service ResetSystem() when the watchdog timer fires. If a\r | |
90 | NotifyFunction is registered, then the NotifyFunction will be called before\r | |
91 | the Runtime Service ResetSystem() is called. If NotifyFunction is NULL, then\r | |
92 | the watchdog handler is unregistered. If a watchdog handler is registered,\r | |
93 | then EFI_SUCCESS is returned. If an attempt is made to register a handler\r | |
94 | when a handler is already registered, then EFI_ALREADY_STARTED is returned.\r | |
95 | If an attempt is made to uninstall a handler when a handler is not installed,\r | |
96 | then return EFI_INVALID_PARAMETER.\r | |
97 | \r | |
36093af9 | 98 | @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.\r |
99 | @param NotifyFunction The function to call when the watchdog timer fires. If this\r | |
100 | is NULL, then the handler will be unregistered.\r | |
de4c8a30 | 101 | \r |
96437c90 | 102 | @retval EFI_SUCCESS The watchdog timer handler was registered or unregistered.\r |
103 | @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already registered.\r | |
104 | @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not previously registered.\r | |
de4c8a30 | 105 | \r |
36093af9 | 106 | **/\r |
107 | EFI_STATUS\r | |
108 | EFIAPI\r | |
109 | WatchdogTimerDriverRegisterHandler (\r | |
110 | IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,\r | |
111 | IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction\r | |
112 | )\r | |
de4c8a30 | 113 | {\r |
96437c90 | 114 | //\r |
115 | // If NotifyFunction is NULL, and a handler was not previously registered,\r | |
116 | // return EFI_INVALID_PARAMETER.\r | |
117 | //\r | |
de4c8a30 | 118 | if (NotifyFunction == NULL && mWatchdogTimerNotifyFunction == NULL) {\r |
119 | return EFI_INVALID_PARAMETER;\r | |
120 | }\r | |
96437c90 | 121 | //\r |
122 | // If NotifyFunction is not NULL, and a handler is already registered,\r | |
123 | // return EFI_ALREADY_STARTED.\r | |
124 | //\r | |
de4c8a30 | 125 | if (NotifyFunction != NULL && mWatchdogTimerNotifyFunction != NULL) {\r |
126 | return EFI_ALREADY_STARTED;\r | |
127 | }\r | |
128 | \r | |
129 | mWatchdogTimerNotifyFunction = NotifyFunction;\r | |
130 | \r | |
131 | return EFI_SUCCESS;\r | |
132 | }\r | |
133 | \r | |
36093af9 | 134 | /**\r |
96437c90 | 135 | Sets the amount of time in the future to fire the watchdog timer.\r |
136 | \r | |
de4c8a30 | 137 | This function sets the amount of time to wait before firing the watchdog\r |
96437c90 | 138 | timer to TimerPeriod 100 ns units. If TimerPeriod is 0, then the watchdog\r |
de4c8a30 | 139 | timer is disabled.\r |
140 | \r | |
36093af9 | 141 | @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.\r |
96437c90 | 142 | @param TimerPeriod The amount of time in 100 ns units to wait before the watchdog\r |
36093af9 | 143 | timer is fired. If TimerPeriod is zero, then the watchdog\r |
144 | timer is disabled.\r | |
de4c8a30 | 145 | \r |
96437c90 | 146 | @retval EFI_SUCCESS The watchdog timer has been programmed to fire in Time\r |
147 | 100 ns units.\r | |
148 | @retval EFI_DEVICE_ERROR A watchdog timer could not be programmed due to a device\r | |
36093af9 | 149 | error.\r |
de4c8a30 | 150 | \r |
36093af9 | 151 | **/\r |
152 | EFI_STATUS\r | |
153 | EFIAPI\r | |
154 | WatchdogTimerDriverSetTimerPeriod (\r | |
155 | IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,\r | |
156 | IN UINT64 TimerPeriod\r | |
157 | )\r | |
de4c8a30 | 158 | {\r |
159 | mWatchdogTimerPeriod = TimerPeriod;\r | |
160 | \r | |
161 | return gBS->SetTimer (\r | |
162 | mWatchdogTimerEvent,\r | |
163 | (mWatchdogTimerPeriod == 0) ? TimerCancel : TimerRelative,\r | |
164 | mWatchdogTimerPeriod\r | |
165 | );\r | |
166 | }\r | |
167 | \r | |
36093af9 | 168 | /**\r |
96437c90 | 169 | Retrieves the amount of time in 100 ns units that the system will wait before firing the watchdog timer.\r |
170 | \r | |
de4c8a30 | 171 | This function retrieves the amount of time the system will wait before firing\r |
172 | the watchdog timer. This period is returned in TimerPeriod, and EFI_SUCCESS\r | |
173 | is returned. If TimerPeriod is NULL, then EFI_INVALID_PARAMETER is returned.\r | |
174 | \r | |
36093af9 | 175 | @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.\r |
96437c90 | 176 | @param TimerPeriod A pointer to the amount of time in 100 ns units that the system\r |
36093af9 | 177 | will wait before the watchdog timer is fired. If TimerPeriod of\r |
178 | zero is returned, then the watchdog timer is disabled.\r | |
de4c8a30 | 179 | \r |
96437c90 | 180 | @retval EFI_SUCCESS The amount of time that the system will wait before\r |
36093af9 | 181 | firing the watchdog timer was returned in TimerPeriod.\r |
96437c90 | 182 | @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.\r |
de4c8a30 | 183 | \r |
36093af9 | 184 | **/\r |
185 | EFI_STATUS\r | |
186 | EFIAPI\r | |
187 | WatchdogTimerDriverGetTimerPeriod (\r | |
188 | IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,\r | |
189 | IN UINT64 *TimerPeriod\r | |
190 | )\r | |
de4c8a30 | 191 | {\r |
192 | if (TimerPeriod == NULL) {\r | |
193 | return EFI_INVALID_PARAMETER;\r | |
194 | }\r | |
195 | \r | |
196 | *TimerPeriod = mWatchdogTimerPeriod;\r | |
197 | \r | |
198 | return EFI_SUCCESS;\r | |
199 | }\r | |
200 | \r | |
36093af9 | 201 | /**\r |
96437c90 | 202 | Entry point of the Watchdog Timer Architectural Protocol driver.\r |
36093af9 | 203 | \r |
96437c90 | 204 | @param ImageHandle The image handle of this driver.\r |
205 | @param SystemTable The pointer of EFI_SYSTEM_TABLE.\r | |
36093af9 | 206 | \r |
96437c90 | 207 | @retval EFI_SUCCESS Watchdog Timer Architectural Protocol successfully installed.\r |
36093af9 | 208 | \r |
209 | **/\r | |
de4c8a30 | 210 | EFI_STATUS\r |
211 | EFIAPI\r | |
212 | WatchdogTimerDriverInitialize (\r | |
213 | IN EFI_HANDLE ImageHandle,\r | |
214 | IN EFI_SYSTEM_TABLE *SystemTable\r | |
215 | )\r | |
de4c8a30 | 216 | {\r |
217 | EFI_STATUS Status;\r | |
218 | \r | |
de4c8a30 | 219 | //\r |
96437c90 | 220 | // Make sure the Watchdog Timer Architectural Protocol has not been installed in the system yet.\r |
de4c8a30 | 221 | //\r |
222 | ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);\r | |
223 | \r | |
224 | //\r | |
96437c90 | 225 | // Create the timer event to implement a simple watchdog timer\r |
de4c8a30 | 226 | //\r |
227 | Status = gBS->CreateEvent (\r | |
228 | EVT_TIMER | EVT_NOTIFY_SIGNAL,\r | |
229 | TPL_NOTIFY,\r | |
230 | WatchdogTimerDriverExpires,\r | |
231 | NULL,\r | |
232 | &mWatchdogTimerEvent\r | |
233 | );\r | |
234 | ASSERT_EFI_ERROR (Status);\r | |
235 | \r | |
236 | //\r | |
237 | // Install the Watchdog Timer Arch Protocol onto a new handle\r | |
238 | //\r | |
239 | Status = gBS->InstallMultipleProtocolInterfaces (\r | |
240 | &mWatchdogTimerHandle,\r | |
241 | &gEfiWatchdogTimerArchProtocolGuid,\r | |
242 | &mWatchdogTimer,\r | |
243 | NULL\r | |
244 | );\r | |
245 | ASSERT_EFI_ERROR (Status);\r | |
246 | \r | |
96437c90 | 247 | return EFI_SUCCESS;\r |
de4c8a30 | 248 | }\r |