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