1) Add MdeModulePkg\Universal\WatchDogTimerDxe driver. Because this driver use Report...
[mirror_edk2.git] / MdeModulePkg / Universal / WatchDogTimerDxe / 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 //
25 // The package level header files this module uses
26 //
27 #include <PiDxe.h>
28 #include <FrameworkDxe.h>
29 //
30 // The protocols, PPI and GUID defintions for this module
31 //
32 //
33 // The Library classes this module consumes
34 //
35 #include <Library/DebugLib.h>
36 #include <Library/UefiDriverEntryPoint.h>
37 #include <Library/ReportStatusCodeLib.h>
38 #include <Library/UefiBootServicesTableLib.h>
39 #include <Library/UefiRuntimeServicesTableLib.h>
40 #include <Protocol/WatchDogTimer.h>
41
42 #include "WatchDogTimer.h"
43
44 //
45 // Handle for the Watchdog Timer Architectural Protocol instance produced by this driver
46 //
47 EFI_HANDLE mWatchdogTimerHandle = NULL;
48
49 //
50 // The Watchdog Timer Architectural Protocol instance produced by this driver
51 //
52 EFI_WATCHDOG_TIMER_ARCH_PROTOCOL mWatchdogTimer = {
53 WatchdogTimerDriverRegisterHandler,
54 WatchdogTimerDriverSetTimerPeriod,
55 WatchdogTimerDriverGetTimerPeriod
56 };
57
58 //
59 // The watchdog timer period in 100 nS units
60 //
61 UINT64 mWatchdogTimerPeriod = 0;
62
63 //
64 // The notification function to call if the watchdig timer fires
65 //
66 EFI_WATCHDOG_TIMER_NOTIFY mWatchdogTimerNotifyFunction = NULL;
67
68 //
69 // The one-shot timer event that is armed when the watchdog timer is enabled
70 //
71 EFI_EVENT mWatchdogTimerEvent;
72
73 //
74 // Worker Functions
75 //
76 STATIC
77 VOID
78 EFIAPI
79 WatchdogTimerDriverExpires (
80 IN EFI_EVENT Timer,
81 IN VOID *Context
82 )
83 /*++
84
85 Routine Description:
86
87 Notification function that is called if the watchdog timer is fired. If a
88 handler has been registered with the Watchdog Timer Architectural Protocol,
89 then that handler is called passing in the time period that has passed that
90 cause the watchdog timer to fire. Then, a call to the Runtime Service
91 ResetSystem() is made to reset the platform.
92
93 Arguments:
94
95 Timer - The one-shot timer event that was signaled when the watchdog timer
96 expired.
97
98 Context - The context that was registered when the event Timer was created.
99
100 Returns:
101
102 None.
103
104 --*/
105 {
106 //
107 // Report error code before exiting
108 //
109 REPORT_STATUS_CODE (
110 EFI_ERROR_CODE | EFI_ERROR_MINOR,
111 (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_TIMER_EXPIRED)
112 );
113
114 //
115 // If a notification function has been registered, then call it
116 //
117 if (mWatchdogTimerNotifyFunction != NULL) {
118 mWatchdogTimerNotifyFunction (mWatchdogTimerPeriod);
119 }
120 //
121 // Reset the platform
122 //
123 gRT->ResetSystem (EfiResetCold, EFI_TIMEOUT, 0, NULL);
124 }
125
126 EFI_STATUS
127 EFIAPI
128 WatchdogTimerDriverRegisterHandler (
129 IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
130 IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction
131 )
132 /*++
133
134 Routine Description:
135
136 This function registers a handler that is to be invoked when the watchdog
137 timer fires. By default, the EFI_WATCHDOG_TIMER protocol will call the
138 Runtime Service ResetSystem() when the watchdog timer fires. If a
139 NotifyFunction is registered, then the NotifyFunction will be called before
140 the Runtime Service ResetSystem() is called. If NotifyFunction is NULL, then
141 the watchdog handler is unregistered. If a watchdog handler is registered,
142 then EFI_SUCCESS is returned. If an attempt is made to register a handler
143 when a handler is already registered, then EFI_ALREADY_STARTED is returned.
144 If an attempt is made to uninstall a handler when a handler is not installed,
145 then return EFI_INVALID_PARAMETER.
146
147 Arguments:
148
149 This - The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
150
151 NotifyFunction - The function to call when the watchdog timer fires. If this
152 is NULL, then the handler will be unregistered.
153
154 Returns:
155
156 EFI_SUCCESS - The watchdog timer handler was registered or
157 unregistered.
158
159 EFI_ALREADY_STARTED - NotifyFunction is not NULL, and a handler is already
160 registered.
161
162 EFI_INVALID_PARAMETER - NotifyFunction is NULL, and a handler was not
163 previously registered.
164
165 --*/
166 {
167 if (NotifyFunction == NULL && mWatchdogTimerNotifyFunction == NULL) {
168 return EFI_INVALID_PARAMETER;
169 }
170
171 if (NotifyFunction != NULL && mWatchdogTimerNotifyFunction != NULL) {
172 return EFI_ALREADY_STARTED;
173 }
174
175 mWatchdogTimerNotifyFunction = NotifyFunction;
176
177 return EFI_SUCCESS;
178 }
179
180 EFI_STATUS
181 EFIAPI
182 WatchdogTimerDriverSetTimerPeriod (
183 IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
184 IN UINT64 TimerPeriod
185 )
186 /*++
187
188 Routine Description:
189
190 This function sets the amount of time to wait before firing the watchdog
191 timer to TimerPeriod 100 nS units. If TimerPeriod is 0, then the watchdog
192 timer is disabled.
193
194 Arguments:
195
196 This - The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
197
198 TimerPeriod - The amount of time in 100 nS units to wait before the watchdog
199 timer is fired. If TimerPeriod is zero, then the watchdog
200 timer is disabled.
201
202 Returns:
203
204 EFI_SUCCESS - The watchdog timer has been programmed to fire in Time
205 100 nS units.
206
207 EFI_DEVICE_ERROR - A watchdog timer could not be programmed due to a device
208 error.
209
210 --*/
211 {
212 mWatchdogTimerPeriod = TimerPeriod;
213
214 return gBS->SetTimer (
215 mWatchdogTimerEvent,
216 (mWatchdogTimerPeriod == 0) ? TimerCancel : TimerRelative,
217 mWatchdogTimerPeriod
218 );
219 }
220
221 EFI_STATUS
222 EFIAPI
223 WatchdogTimerDriverGetTimerPeriod (
224 IN EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
225 IN UINT64 *TimerPeriod
226 )
227 /*++
228
229 Routine Description:
230
231 This function retrieves the amount of time the system will wait before firing
232 the watchdog timer. This period is returned in TimerPeriod, and EFI_SUCCESS
233 is returned. If TimerPeriod is NULL, then EFI_INVALID_PARAMETER is returned.
234
235 Arguments:
236
237 This - The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
238
239 TimerPeriod - A pointer to the amount of time in 100 nS units that the system
240 will wait before the watchdog timer is fired. If TimerPeriod of
241 zero is returned, then the watchdog timer is disabled.
242
243 Returns:
244
245 EFI_SUCCESS - The amount of time that the system will wait before
246 firing the watchdog timer was returned in TimerPeriod.
247
248 EFI_INVALID_PARAMETER - TimerPeriod is NULL.
249
250 --*/
251 {
252 if (TimerPeriod == NULL) {
253 return EFI_INVALID_PARAMETER;
254 }
255
256 *TimerPeriod = mWatchdogTimerPeriod;
257
258 return EFI_SUCCESS;
259 }
260
261 EFI_STATUS
262 EFIAPI
263 WatchdogTimerDriverInitialize (
264 IN EFI_HANDLE ImageHandle,
265 IN EFI_SYSTEM_TABLE *SystemTable
266 )
267 /*++
268
269 Routine Description:
270
271 Initialize the Watchdog Timer Architectural Protocol driver
272
273 Arguments:
274
275 ImageHandle - ImageHandle of the loaded driver
276
277 SystemTable - Pointer to the System Table
278
279 Returns:
280
281 EFI_SUCCESS - Timer Architectural Protocol created
282
283 EFI_OUT_OF_RESOURCES - Not enough resources available to initialize driver.
284
285 EFI_DEVICE_ERROR - A device error occured attempting to initialize the driver.
286
287 --*/
288 {
289 EFI_STATUS Status;
290
291 REPORT_STATUS_CODE (
292 EFI_PROGRESS_CODE,
293 (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_SW_PC_INIT_BEGIN)
294 );
295 //
296 // Make sure the Watchdog Timer Architectural Protocol is not already installed in the system
297 //
298 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
299
300 //
301 // Create the timer event used to implement a simple watchdog timer
302 //
303 Status = gBS->CreateEvent (
304 EVT_TIMER | EVT_NOTIFY_SIGNAL,
305 TPL_NOTIFY,
306 WatchdogTimerDriverExpires,
307 NULL,
308 &mWatchdogTimerEvent
309 );
310 ASSERT_EFI_ERROR (Status);
311
312 //
313 // Install the Watchdog Timer Arch Protocol onto a new handle
314 //
315 Status = gBS->InstallMultipleProtocolInterfaces (
316 &mWatchdogTimerHandle,
317 &gEfiWatchdogTimerArchProtocolGuid,
318 &mWatchdogTimer,
319 NULL
320 );
321 ASSERT_EFI_ERROR (Status);
322
323 REPORT_STATUS_CODE (
324 EFI_PROGRESS_CODE,
325 (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_SW_PC_INIT_END)
326 );
327
328 return Status;
329 }