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