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