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