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