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