2 Emu RTC Architectural Protocol Driver as defined in PI
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
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>
19 #include <Protocol/RealTimeClock.h>
38 InitializeRealTimeClock (
39 IN EFI_HANDLE ImageHandle
,
40 IN EFI_SYSTEM_TABLE
*SystemTable
47 OUT EFI_TIME_CAPABILITIES
*Capabilities OPTIONAL
53 Service routine for RealTimeClockInstance->GetTime
57 Time - A pointer to storage that will receive a snapshot of the current time.
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.
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.
72 // Check parameter for null pointer
75 return EFI_INVALID_PARAMETER
;
78 gEmuThunk
->GetTime (Time
, Capabilities
);
92 Service routine for RealTimeClockInstance->SetTime
96 Time - A pointer to storage containing the time and date information to
97 program into the real time clock.
101 EFI_SUCEESS - The operation completed successfully.
103 EFI_INVALID_PARAMETER - One of the fields in Time is out of range.
105 EFI_DEVICE_ERROR - The operation could not be complete due to a device error.
112 return EFI_INVALID_PARAMETER
;
116 // Make sure that the time fields are valid
118 Status
= RtcTimeFieldsValid (Time
);
119 if (EFI_ERROR (Status
)) {
123 return EFI_UNSUPPORTED
;
129 OUT BOOLEAN
*Enabled
,
130 OUT BOOLEAN
*Pending
,
137 Service routine for RealTimeClockInstance->GetWakeupTime
140 This - Indicates the protocol instance structure.
142 Enabled - Indicates if the alarm is currently enabled or disabled.
144 Pending - Indicates if the alarm signal is pending and requires
147 Time - The current alarm setting.
151 EFI_SUCEESS - The operation completed successfully.
153 EFI_DEVICE_ERROR - The operation could not be complete due to a device error.
155 EFI_UNSUPPORTED - The operation is not supported on this platform.
159 return EFI_UNSUPPORTED
;
172 Service routine for RealTimeClockInstance->SetWakeupTime
176 Enabled - Enable or disable the wakeup alarm.
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
184 EFI_SUCEESS - The operation completed successfully.
186 EFI_DEVICE_ERROR - The operation could not be complete due to a device error.
188 EFI_INVALID_PARAMETER - A field in Time is out of range.
190 EFI_UNSUPPORTED - The operation is not supported on this platform.
194 return EFI_UNSUPPORTED
;
199 InitializeRealTimeClock (
200 IN EFI_HANDLE ImageHandle
,
201 IN EFI_SYSTEM_TABLE
*SystemTable
207 Install Real Time Clock Protocol
210 ImageHandle - Image Handle
211 SystemTable - Pointer to system table
215 EFI_SUCEESS - Real Time Clock Services are installed into the Runtime Services Table
222 SystemTable
->RuntimeServices
->GetTime
= EmuGetTime
;
223 SystemTable
->RuntimeServices
->SetTime
= EmuSetTime
;
224 SystemTable
->RuntimeServices
->GetWakeupTime
= EmuGetWakeupTime
;
225 SystemTable
->RuntimeServices
->SetWakeupTime
= EmuSetWakeupTime
;
228 Status
= gBS
->InstallMultipleProtocolInterfaces (
230 &gEfiRealTimeClockArchProtocolGuid
,
251 if ((Time
->Year
< 1998) ||
252 (Time
->Year
> 2099) ||
254 (Time
->Month
> 12) ||
255 (!DayValid (Time
)) ||
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
)))
264 return EFI_INVALID_PARAMETER
;
275 STATIC
const INTN DayOfMonth
[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
277 if ((Time
->Day
< 1) ||
278 (Time
->Day
> DayOfMonth
[Time
->Month
- 1]) ||
279 ((Time
->Month
== 2) && (!IsLeapYear (Time
) && (Time
->Day
> 28)))
293 if (Time
->Year
% 4 == 0) {
294 if (Time
->Year
% 100 == 0) {
295 if (Time
->Year
% 400 == 0) {