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