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