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