]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/RealTimeClockRuntimeDxe/RealTimeClock.c
SignedCapsulePkg: Replace [Ascii|Unicode]ValueToString
[mirror_edk2.git] / EmulatorPkg / RealTimeClockRuntimeDxe / RealTimeClock.c
CommitLineData
949f388f 1/*++\r
2 Emu RTC Architectural Protocol Driver as defined in PI\r
3\r
4Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>\r
5Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.\r
d18d8a1d 6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
949f388f 13\r
14**/\r
15#include <PiDxe.h>\r
16\r
17#include <Library/BaseLib.h>\r
18#include <Library/DebugLib.h>\r
19#include <Library/UefiLib.h>\r
20#include <Library/UefiDriverEntryPoint.h>\r
21#include <Library/EmuThunkLib.h>\r
22#include <Library/MemoryAllocationLib.h>\r
23#include <Library/UefiBootServicesTableLib.h>\r
24\r
25#include <Protocol/RealTimeClock.h>\r
26\r
27BOOLEAN\r
28DayValid (\r
29 IN EFI_TIME *Time\r
30 );\r
31\r
32BOOLEAN\r
33IsLeapYear (\r
34 IN EFI_TIME *Time\r
35 );\r
36\r
37EFI_STATUS\r
38RtcTimeFieldsValid (\r
39 IN EFI_TIME *Time\r
40 );\r
41\r
42EFI_STATUS\r
43EFIAPI\r
44InitializeRealTimeClock (\r
45 IN EFI_HANDLE ImageHandle,\r
46 IN EFI_SYSTEM_TABLE *SystemTable\r
47 );\r
48\r
49EFI_STATUS\r
50EFIAPI\r
51EmuGetTime (\r
52 OUT EFI_TIME * Time,\r
53 OUT EFI_TIME_CAPABILITIES * Capabilities OPTIONAL\r
54 )\r
55/*++\r
56\r
57Routine Description:\r
d18d8a1d 58 Service routine for RealTimeClockInstance->GetTime\r
949f388f 59\r
60Arguments:\r
61\r
62 Time - A pointer to storage that will receive a snapshot of the current time.\r
63\r
64 Capabilities - A pointer to storage that will receive the capabilities of the real time clock\r
d18d8a1d 65 in the platform. This includes the real time clock's resolution and accuracy.\r
949f388f 66 All reported device capabilities are rounded up. This is an OPTIONAL argument.\r
67\r
68Returns:\r
69\r
70 EFI_SUCEESS - The underlying GetSystemTime call occurred and returned\r
71 Note that in the NT32 emulation, the GetSystemTime call has no return value\r
72 thus you will always receive a EFI_SUCCESS on this.\r
73\r
74**/\r
75{\r
76\r
77 //\r
78 // Check parameter for null pointer\r
79 //\r
80 if (Time == NULL) {\r
81 return EFI_INVALID_PARAMETER;\r
82\r
83 }\r
84\r
85 gEmuThunk->GetTime (Time, Capabilities);\r
86\r
87 return EFI_SUCCESS;\r
88}\r
89\r
90EFI_STATUS\r
91EFIAPI\r
92EmuSetTime (\r
93 IN EFI_TIME *Time\r
94 )\r
95/*++\r
96\r
97Routine Description:\r
d18d8a1d 98 Service routine for RealTimeClockInstance->SetTime\r
949f388f 99\r
100Arguments:\r
101\r
102 Time - A pointer to storage containing the time and date information to\r
103 program into the real time clock.\r
104\r
105Returns:\r
106\r
107 EFI_SUCEESS - The operation completed successfully.\r
d18d8a1d 108\r
949f388f 109 EFI_INVALID_PARAMETER - One of the fields in Time is out of range.\r
110\r
111 EFI_DEVICE_ERROR - The operation could not be complete due to a device error.\r
112\r
113**/\r
114{\r
115 EFI_STATUS Status;\r
116\r
117 if (Time == NULL) {\r
118 return EFI_INVALID_PARAMETER;\r
119 }\r
120 //\r
121 // Make sure that the time fields are valid\r
122 //\r
123 Status = RtcTimeFieldsValid (Time);\r
124 if (EFI_ERROR (Status)) {\r
125 return Status;\r
126 }\r
127 return EFI_UNSUPPORTED;\r
128}\r
129\r
130EFI_STATUS\r
131EFIAPI\r
132EmuGetWakeupTime (\r
133 OUT BOOLEAN *Enabled,\r
134 OUT BOOLEAN *Pending,\r
135 OUT EFI_TIME *Time\r
136 )\r
137/*++\r
138\r
139Routine Description:\r
140 Service routine for RealTimeClockInstance->GetWakeupTime\r
141\r
142Arguments:\r
143 This - Indicates the protocol instance structure.\r
144\r
145 Enabled - Indicates if the alarm is currently enabled or disabled.\r
146\r
147 Pending - Indicates if the alarm signal is pending and requires\r
148 acknowledgement.\r
149\r
150 Time - The current alarm setting.\r
151\r
152Returns:\r
153\r
154 EFI_SUCEESS - The operation completed successfully.\r
d18d8a1d 155\r
949f388f 156 EFI_DEVICE_ERROR - The operation could not be complete due to a device error.\r
157\r
158 EFI_UNSUPPORTED - The operation is not supported on this platform.\r
159\r
160**/\r
161{\r
162 return EFI_UNSUPPORTED;\r
163}\r
164\r
165EFI_STATUS\r
166EFIAPI\r
167EmuSetWakeupTime (\r
168 IN BOOLEAN Enable,\r
169 OUT EFI_TIME *Time\r
170 )\r
171/*++\r
172\r
173Routine Description:\r
174 Service routine for RealTimeClockInstance->SetWakeupTime\r
175\r
176Arguments:\r
177\r
178 Enabled - Enable or disable the wakeup alarm.\r
179\r
180 Time - If enable is TRUE, the time to set the wakup alarm for.\r
181 If enable is FALSE, then this parameter is optional, and\r
182 may be NULL.\r
183\r
184Returns:\r
185\r
186 EFI_SUCEESS - The operation completed successfully.\r
d18d8a1d 187\r
949f388f 188 EFI_DEVICE_ERROR - The operation could not be complete due to a device error.\r
189\r
190 EFI_INVALID_PARAMETER - A field in Time is out of range.\r
191\r
192 EFI_UNSUPPORTED - The operation is not supported on this platform.\r
193\r
194**/\r
195{\r
196 return EFI_UNSUPPORTED;\r
197}\r
198\r
199EFI_STATUS\r
200EFIAPI\r
201InitializeRealTimeClock (\r
202 IN EFI_HANDLE ImageHandle,\r
203 IN EFI_SYSTEM_TABLE *SystemTable\r
204 )\r
205/*++\r
206\r
207Routine Description:\r
d18d8a1d 208 Install Real Time Clock Protocol\r
949f388f 209\r
210Arguments:\r
211 ImageHandle - Image Handle\r
212 SystemTable - Pointer to system table\r
213\r
214Returns:\r
215\r
216 EFI_SUCEESS - Real Time Clock Services are installed into the Runtime Services Table\r
217\r
218**/\r
219{\r
220 EFI_STATUS Status;\r
221 EFI_HANDLE Handle;\r
222\r
223 SystemTable->RuntimeServices->GetTime = EmuGetTime;\r
224 SystemTable->RuntimeServices->SetTime = EmuSetTime;\r
225 SystemTable->RuntimeServices->GetWakeupTime = EmuGetWakeupTime;\r
226 SystemTable->RuntimeServices->SetWakeupTime = EmuSetWakeupTime;\r
227\r
228 Handle = NULL;\r
229 Status = gBS->InstallMultipleProtocolInterfaces (\r
230 &Handle,\r
231 &gEfiRealTimeClockArchProtocolGuid,\r
232 NULL,\r
233 NULL\r
234 );\r
235 return Status;\r
236}\r
237\r
238EFI_STATUS\r
239RtcTimeFieldsValid (\r
240 IN EFI_TIME *Time\r
241 )\r
242/*++\r
243\r
244Routine Description:\r
245\r
246 Arguments:\r
d18d8a1d 247\r
248 Returns:\r
949f388f 249**/\r
250{\r
251 if (Time->Year < 1998 ||\r
252 Time->Year > 2099 ||\r
253 Time->Month < 1 ||\r
254 Time->Month > 12 ||\r
255 (!DayValid (Time)) ||\r
256 Time->Hour > 23 ||\r
257 Time->Minute > 59 ||\r
258 Time->Second > 59 ||\r
259 Time->Nanosecond > 999999999 ||\r
260 (!(Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE || (Time->TimeZone >= -1440 && Time->TimeZone <= 1440))) ||\r
261 (Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT)))\r
262 ) {\r
263 return EFI_INVALID_PARAMETER;\r
264 }\r
265\r
266 return EFI_SUCCESS;\r
267}\r
268\r
269BOOLEAN\r
270DayValid (\r
271 IN EFI_TIME *Time\r
272 )\r
273{\r
274\r
275 STATIC const INTN DayOfMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };\r
276\r
277 if (Time->Day < 1 ||\r
278 Time->Day > DayOfMonth[Time->Month - 1] ||\r
279 (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))\r
280 ) {\r
281 return FALSE;\r
282 }\r
283\r
284 return TRUE;\r
285}\r
286\r
287BOOLEAN\r
288IsLeapYear (\r
289 IN EFI_TIME *Time\r
290 )\r
291{\r
292 if (Time->Year % 4 == 0) {\r
293 if (Time->Year % 100 == 0) {\r
294 if (Time->Year % 400 == 0) {\r
295 return TRUE;\r
296 } else {\r
297 return FALSE;\r
298 }\r
299 } else {\r
300 return TRUE;\r
301 }\r
302 } else {\r
303 return FALSE;\r
304 }\r
305}\r