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