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