]>
Commit | Line | Data |
---|---|---|
504214c4 | 1 | /** @file\r |
96437c90 | 2 | Implementation of Watchdog Timer Architectural Protocol using UEFI APIs.\r |
d1102dba LG |
3 | \r |
4 | Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r | |
9d510e61 | 5 | SPDX-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 | 14 | EFI_HANDLE mWatchdogTimerHandle = NULL;\r |
de4c8a30 | 15 | \r |
16 | //\r | |
17 | // The Watchdog Timer Architectural Protocol instance produced by this driver\r | |
18 | //\r | |
19 | EFI_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 | 28 | UINT64 mWatchdogTimerPeriod = 0;\r |
de4c8a30 | 29 | \r |
30 | //\r | |
31 | // The notification function to call if the watchdig timer fires\r | |
32 | //\r | |
96437c90 | 33 | EFI_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 | 38 | EFI_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 | 56 | VOID\r |
57 | EFIAPI\r | |
58 | WatchdogTimerDriverExpires (\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 |
104 | EFI_STATUS\r | |
105 | EFIAPI\r | |
106 | WatchdogTimerDriverRegisterHandler (\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 |
149 | EFI_STATUS\r | |
150 | EFIAPI\r | |
151 | WatchdogTimerDriverSetTimerPeriod (\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 |
182 | EFI_STATUS\r | |
183 | EFIAPI\r | |
184 | WatchdogTimerDriverGetTimerPeriod (\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 | 207 | EFI_STATUS\r |
208 | EFIAPI\r | |
209 | WatchdogTimerDriverInitialize (\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 |