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