]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Universal/WatchdogTimer/Dxe/WatchDogTimer.c
Add some definitions for efi event in Uefi/UefiSpec.h to follow spec.
[mirror_edk2.git] / EdkModulePkg / Universal / WatchdogTimer / Dxe / WatchDogTimer.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 WatchDogTimer.c
15
16 Abstract:
17
18 Generic watchdog timer implemenetation using EFI APIs
19
20 Revision History
21
22 --*/
23
24 #include "WatchDogTimer.h"
25
26 //
27 // Handle for the Watchdog Timer Architectural Protocol instance produced by this driver
28 //
29 EFI_HANDLE mWatchdogTimerHandle = NULL;
30
31 //
32 // The Watchdog Timer Architectural Protocol instance produced by this driver
33 //
34 EFI_WATCHDOG_TIMER_ARCH_PROTOCOL mWatchdogTimer = {
35 WatchdogTimerDriverRegisterHandler,
36 WatchdogTimerDriverSetTimerPeriod,
37 WatchdogTimerDriverGetTimerPeriod
38 };
39
40 //
41 // The watchdog timer period in 100 nS units
42 //
43 UINT64 mWatchdogTimerPeriod = 0;
44
45 //
46 // The notification function to call if the watchdig timer fires
47 //
48 EFI_WATCHDOG_TIMER_NOTIFY mWatchdogTimerNotifyFunction = NULL;
49
50 //
51 // The one-shot timer event that is armed when the watchdog timer is enabled
52 //
53 EFI_EVENT mWatchdogTimerEvent;
54
55 //
56 // Worker Functions
57 //
58 STATIC
59 VOID
60 EFIAPI
61 WatchdogTimerDriverExpires (
62 IN EFI_EVENT Timer,
63 IN VOID *Context
64 )
65 /*++
66
67 Routine Description:
68
69 Notification function that is called if the watchdog timer is fired. If a
70 handler has been registered with the Watchdog Timer Architectural Protocol,
71 then that handler is called passing in the time period that has passed that
72 cause the watchdog timer to fire. Then, a call to the Runtime Service
73 ResetSystem() is made to reset the platform.
74
75 Arguments:
76
77 Timer - The one-shot timer event that was signaled when the watchdog timer
78 expired.
79
80 Context - The context that was registered when the event Timer was created.
81
82 Returns:
83
84 None.
85
86 --*/
87 {
88 //
89 // Report error code before exiting
90 //
91 REPORT_STATUS_CODE (
92 EFI_ERROR_CODE | EFI_ERROR_MINOR,
93 (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_TIMER_EXPIRED)
94 );
95
96 //
97 // If a notification function has been registered, then call it
98 //
99 if (mWatchdogTimerNotifyFunction != NULL) {
100 mWatchdogTimerNotifyFunction (mWatchdogTimerPeriod);
101 }
102 //
103 // Reset the platform
104 //
105 gRT->ResetSystem (EfiResetCold, EFI_TIMEOUT, 0, NULL);
106 }
107
108 EFI_STATUS
109 EFIAPI
110 WatchdogTimerDriverRegisterHandler (
111 IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
112 IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction
113 )
114 /*++
115
116 Routine Description:
117
118 This function registers a handler that is to be invoked when the watchdog
119 timer fires. By default, the EFI_WATCHDOG_TIMER protocol will call the
120 Runtime Service ResetSystem() when the watchdog timer fires. If a
121 NotifyFunction is registered, then the NotifyFunction will be called before
122 the Runtime Service ResetSystem() is called. If NotifyFunction is NULL, then
123 the watchdog handler is unregistered. If a watchdog handler is registered,
124 then EFI_SUCCESS is returned. If an attempt is made to register a handler
125 when a handler is already registered, then EFI_ALREADY_STARTED is returned.
126 If an attempt is made to uninstall a handler when a handler is not installed,
127 then return EFI_INVALID_PARAMETER.
128
129 Arguments:
130
131 This - The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
132
133 NotifyFunction - The function to call when the watchdog timer fires. If this
134 is NULL, then the handler will be unregistered.
135
136 Returns:
137
138 EFI_SUCCESS - The watchdog timer handler was registered or
139 unregistered.
140
141 EFI_ALREADY_STARTED - NotifyFunction is not NULL, and a handler is already
142 registered.
143
144 EFI_INVALID_PARAMETER - NotifyFunction is NULL, and a handler was not
145 previously registered.
146
147 --*/
148 {
149 if (NotifyFunction == NULL && mWatchdogTimerNotifyFunction == NULL) {
150 return EFI_INVALID_PARAMETER;
151 }
152
153 if (NotifyFunction != NULL && mWatchdogTimerNotifyFunction != NULL) {
154 return EFI_ALREADY_STARTED;
155 }
156
157 mWatchdogTimerNotifyFunction = NotifyFunction;
158
159 return EFI_SUCCESS;
160 }
161
162 EFI_STATUS
163 EFIAPI
164 WatchdogTimerDriverSetTimerPeriod (
165 IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
166 IN UINT64 TimerPeriod
167 )
168 /*++
169
170 Routine Description:
171
172 This function sets the amount of time to wait before firing the watchdog
173 timer to TimerPeriod 100 nS units. If TimerPeriod is 0, then the watchdog
174 timer is disabled.
175
176 Arguments:
177
178 This - The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
179
180 TimerPeriod - The amount of time in 100 nS units to wait before the watchdog
181 timer is fired. If TimerPeriod is zero, then the watchdog
182 timer is disabled.
183
184 Returns:
185
186 EFI_SUCCESS - The watchdog timer has been programmed to fire in Time
187 100 nS units.
188
189 EFI_DEVICE_ERROR - A watchdog timer could not be programmed due to a device
190 error.
191
192 --*/
193 {
194 mWatchdogTimerPeriod = TimerPeriod;
195
196 return gBS->SetTimer (
197 mWatchdogTimerEvent,
198 (mWatchdogTimerPeriod == 0) ? TimerCancel : TimerRelative,
199 mWatchdogTimerPeriod
200 );
201 }
202
203 EFI_STATUS
204 EFIAPI
205 WatchdogTimerDriverGetTimerPeriod (
206 IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
207 IN UINT64 *TimerPeriod
208 )
209 /*++
210
211 Routine Description:
212
213 This function retrieves the amount of time the system will wait before firing
214 the watchdog timer. This period is returned in TimerPeriod, and EFI_SUCCESS
215 is returned. If TimerPeriod is NULL, then EFI_INVALID_PARAMETER is returned.
216
217 Arguments:
218
219 This - The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
220
221 TimerPeriod - A pointer to the amount of time in 100 nS units that the system
222 will wait before the watchdog timer is fired. If TimerPeriod of
223 zero is returned, then the watchdog timer is disabled.
224
225 Returns:
226
227 EFI_SUCCESS - The amount of time that the system will wait before
228 firing the watchdog timer was returned in TimerPeriod.
229
230 EFI_INVALID_PARAMETER - TimerPeriod is NULL.
231
232 --*/
233 {
234 if (TimerPeriod == NULL) {
235 return EFI_INVALID_PARAMETER;
236 }
237
238 *TimerPeriod = mWatchdogTimerPeriod;
239
240 return EFI_SUCCESS;
241 }
242
243 EFI_STATUS
244 EFIAPI
245 WatchdogTimerDriverInitialize (
246 IN EFI_HANDLE ImageHandle,
247 IN EFI_SYSTEM_TABLE *SystemTable
248 )
249 /*++
250
251 Routine Description:
252
253 Initialize the Watchdog Timer Architectural Protocol driver
254
255 Arguments:
256
257 ImageHandle - ImageHandle of the loaded driver
258
259 SystemTable - Pointer to the System Table
260
261 Returns:
262
263 EFI_SUCCESS - Timer Architectural Protocol created
264
265 EFI_OUT_OF_RESOURCES - Not enough resources available to initialize driver.
266
267 EFI_DEVICE_ERROR - A device error occured attempting to initialize the driver.
268
269 --*/
270 {
271 EFI_STATUS Status;
272
273 REPORT_STATUS_CODE (
274 EFI_PROGRESS_CODE,
275 (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_SW_PC_INIT_BEGIN)
276 );
277 //
278 // Make sure the Watchdog Timer Architectural Protocol is not already installed in the system
279 //
280 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
281
282 //
283 // Create the timer event used to implement a simple watchdog timer
284 //
285 Status = gBS->CreateEvent (
286 EVT_TIMER | EVT_NOTIFY_SIGNAL,
287 TPL_NOTIFY,
288 WatchdogTimerDriverExpires,
289 NULL,
290 &mWatchdogTimerEvent
291 );
292 ASSERT_EFI_ERROR (Status);
293
294 //
295 // Install the Watchdog Timer Arch Protocol onto a new handle
296 //
297 Status = gBS->InstallMultipleProtocolInterfaces (
298 &mWatchdogTimerHandle,
299 &gEfiWatchdogTimerArchProtocolGuid,
300 &mWatchdogTimer,
301 NULL
302 );
303 ASSERT_EFI_ERROR (Status);
304
305 REPORT_STATUS_CODE (
306 EFI_PROGRESS_CODE,
307 (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_SW_PC_INIT_END)
308 );
309
310 return Status;
311 }