]> git.proxmox.com Git - mirror_edk2.git/blob - UnixPkg/RealTimeClockRuntimeDxe/RealTimeClock.c
b94e1f1776524ec88e641e593b6b46a18c0f520e
[mirror_edk2.git] / UnixPkg / RealTimeClockRuntimeDxe / RealTimeClock.c
1 /*++
2
3 Copyright (c) 2004 - 2008, 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 RealTimeClock.c
15
16 Abstract:
17
18 UNIX Emulation Architectural Protocol Driver as defined in Tiano
19
20 --*/
21 #include "PiDxe.h"
22 #include "UnixDxe.h"
23 #include <Protocol/RealTimeClock.h>
24
25 #include <Library/BaseLib.h>
26 #include <Library/DebugLib.h>
27 #include <Library/UefiLib.h>
28 #include <Library/UefiDriverEntryPoint.h>
29 #include <Library/UnixLib.h>
30 #include <Library/MemoryAllocationLib.h>
31 #include <Library/UefiBootServicesTableLib.h>
32
33 BOOLEAN
34 DayValid (
35 IN EFI_TIME *Time
36 );
37
38 BOOLEAN
39 IsLeapYear (
40 IN EFI_TIME *Time
41 );
42
43 EFI_STATUS
44 RtcTimeFieldsValid (
45 IN EFI_TIME *Time
46 );
47
48 EFI_STATUS
49 EFIAPI
50 InitializeRealTimeClock (
51 IN EFI_HANDLE ImageHandle,
52 IN EFI_SYSTEM_TABLE *SystemTable
53 );
54
55 EFI_STATUS
56 EFIAPI
57 UnixGetTime (
58 OUT EFI_TIME * Time,
59 OUT EFI_TIME_CAPABILITIES * Capabilities OPTIONAL
60 )
61 /*++
62
63 Routine Description:
64 Service routine for RealTimeClockInstance->GetTime
65
66 Arguments:
67
68 Time - A pointer to storage that will receive a snapshot of the current time.
69
70 Capabilities - A pointer to storage that will receive the capabilities of the real time clock
71 in the platform. This includes the real time clock's resolution and accuracy.
72 All reported device capabilities are rounded up. This is an OPTIONAL argument.
73
74 Returns:
75
76 EFI_SUCEESS - The underlying GetSystemTime call occurred and returned
77 Note that in the NT32 emulation, the GetSystemTime call has no return value
78 thus you will always receive a EFI_SUCCESS on this.
79
80 --*/
81 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
82 {
83
84 //
85 // Check parameter for null pointer
86 //
87 if (Time == NULL) {
88 return EFI_INVALID_PARAMETER;
89
90 }
91
92 gUnix->GetLocalTime (Time);
93
94 if (Capabilities != NULL) {
95 Capabilities->Resolution = 1;
96 Capabilities->Accuracy = 50000000;
97 Capabilities->SetsToZero = FALSE;
98 }
99
100 return EFI_SUCCESS;
101 }
102
103 EFI_STATUS
104 EFIAPI
105 UnixSetTime (
106 IN EFI_TIME *Time
107 )
108 /*++
109
110 Routine Description:
111 Service routine for RealTimeClockInstance->SetTime
112
113 Arguments:
114
115 Time - A pointer to storage containing the time and date information to
116 program into the real time clock.
117
118 Returns:
119
120 EFI_SUCEESS - The operation completed successfully.
121
122 EFI_INVALID_PARAMETER - One of the fields in Time is out of range.
123
124 EFI_DEVICE_ERROR - The operation could not be complete due to a device error.
125
126 --*/
127 // TODO: EFI_SUCCESS - add return value to function comment
128 {
129 EFI_STATUS Status;
130
131 if (Time == NULL) {
132 return EFI_INVALID_PARAMETER;
133 }
134 //
135 // Make sure that the time fields are valid
136 //
137 Status = RtcTimeFieldsValid (Time);
138 if (EFI_ERROR (Status)) {
139 return Status;
140 }
141 return EFI_UNSUPPORTED;
142 }
143
144 EFI_STATUS
145 EFIAPI
146 UnixGetWakeupTime (
147 OUT BOOLEAN *Enabled,
148 OUT BOOLEAN *Pending,
149 OUT EFI_TIME *Time
150 )
151 /*++
152
153 Routine Description:
154 Service routine for RealTimeClockInstance->GetWakeupTime
155
156 Arguments:
157 This - Indicates the protocol instance structure.
158
159 Enabled - Indicates if the alarm is currently enabled or disabled.
160
161 Pending - Indicates if the alarm signal is pending and requires
162 acknowledgement.
163
164 Time - The current alarm setting.
165
166 Returns:
167
168 EFI_SUCEESS - The operation completed successfully.
169
170 EFI_DEVICE_ERROR - The operation could not be complete due to a device error.
171
172 EFI_UNSUPPORTED - The operation is not supported on this platform.
173
174 --*/
175 {
176 return EFI_UNSUPPORTED;
177 }
178
179 EFI_STATUS
180 EFIAPI
181 UnixSetWakeupTime (
182 IN BOOLEAN Enable,
183 OUT EFI_TIME *Time
184 )
185 /*++
186
187 Routine Description:
188 Service routine for RealTimeClockInstance->SetWakeupTime
189
190 Arguments:
191
192 Enabled - Enable or disable the wakeup alarm.
193
194 Time - If enable is TRUE, the time to set the wakup alarm for.
195 If enable is FALSE, then this parameter is optional, and
196 may be NULL.
197
198 Returns:
199
200 EFI_SUCEESS - The operation completed successfully.
201
202 EFI_DEVICE_ERROR - The operation could not be complete due to a device error.
203
204 EFI_INVALID_PARAMETER - A field in Time is out of range.
205
206 EFI_UNSUPPORTED - The operation is not supported on this platform.
207
208 --*/
209 {
210 return EFI_UNSUPPORTED;
211 }
212
213 EFI_STATUS
214 EFIAPI
215 InitializeRealTimeClock (
216 IN EFI_HANDLE ImageHandle,
217 IN EFI_SYSTEM_TABLE *SystemTable
218 )
219 /*++
220
221 Routine Description:
222 Install Real Time Clock Protocol
223
224 Arguments:
225 ImageHandle - Image Handle
226 SystemTable - Pointer to system table
227
228 Returns:
229
230 EFI_SUCEESS - Real Time Clock Services are installed into the Runtime Services Table
231
232 --*/
233 {
234 EFI_STATUS Status;
235 EFI_HANDLE Handle;
236
237 SystemTable->RuntimeServices->GetTime = UnixGetTime;
238 SystemTable->RuntimeServices->SetTime = UnixSetTime;
239 SystemTable->RuntimeServices->GetWakeupTime = UnixGetWakeupTime;
240 SystemTable->RuntimeServices->SetWakeupTime = UnixSetWakeupTime;
241
242 Handle = NULL;
243 Status = gBS->InstallMultipleProtocolInterfaces (
244 &Handle,
245 &gEfiRealTimeClockArchProtocolGuid,
246 NULL,
247 NULL
248 );
249 return Status;
250 }
251
252 EFI_STATUS
253 RtcTimeFieldsValid (
254 IN EFI_TIME *Time
255 )
256 /*++
257
258 Routine Description:
259
260 Arguments:
261
262 Returns:
263 --*/
264 // TODO: Time - add argument and description to function comment
265 // TODO: EFI_INVALID_PARAMETER - add return value to function comment
266 // TODO: EFI_SUCCESS - add return value to function comment
267 {
268 if (Time->Year < 1998 ||
269 Time->Year > 2099 ||
270 Time->Month < 1 ||
271 Time->Month > 12 ||
272 (!DayValid (Time)) ||
273 Time->Hour > 23 ||
274 Time->Minute > 59 ||
275 Time->Second > 59 ||
276 Time->Nanosecond > 999999999 ||
277 (!(Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE || (Time->TimeZone >= -1440 && Time->TimeZone <= 1440))) ||
278 (Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT)))
279 ) {
280 return EFI_INVALID_PARAMETER;
281 }
282
283 return EFI_SUCCESS;
284 }
285
286 BOOLEAN
287 DayValid (
288 IN EFI_TIME *Time
289 )
290 /*++
291
292 Routine Description:
293
294 TODO: Add function description
295
296 Arguments:
297
298 Time - TODO: add argument description
299
300 Returns:
301
302 TODO: add return values
303
304 --*/
305 {
306
307 STATIC const INTN DayOfMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
308
309 if (Time->Day < 1 ||
310 Time->Day > DayOfMonth[Time->Month - 1] ||
311 (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))
312 ) {
313 return FALSE;
314 }
315
316 return TRUE;
317 }
318
319 BOOLEAN
320 IsLeapYear (
321 IN EFI_TIME *Time
322 )
323 /*++
324
325 Routine Description:
326
327 TODO: Add function description
328
329 Arguments:
330
331 Time - TODO: add argument description
332
333 Returns:
334
335 TODO: add return values
336
337 --*/
338 {
339 if (Time->Year % 4 == 0) {
340 if (Time->Year % 100 == 0) {
341 if (Time->Year % 400 == 0) {
342 return TRUE;
343 } else {
344 return FALSE;
345 }
346 } else {
347 return TRUE;
348 }
349 } else {
350 return FALSE;
351 }
352 }