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
52 Service routine for RealTimeClockInstance->GetTime
56 Time - A pointer to storage that will receive a snapshot of the current time.
58 Capabilities - A pointer to storage that will receive the capabilities of the real time clock
59 in the platform. This includes the real time clock's resolution and accuracy.
60 All reported device capabilities are rounded up. This is an OPTIONAL argument.
64 EFI_SUCEESS - The underlying GetSystemTime call occurred and returned
65 Note that in the NT32 emulation, the GetSystemTime call has no return value
66 thus you will always receive a EFI_SUCCESS on this.
72 // Check parameter for null pointer
75 return EFI_INVALID_PARAMETER
;
79 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
;
115 // Make sure that the time fields are valid
117 Status
= RtcTimeFieldsValid (Time
);
118 if (EFI_ERROR (Status
)) {
121 return EFI_UNSUPPORTED
;
127 OUT BOOLEAN
*Enabled
,
128 OUT BOOLEAN
*Pending
,
134 Service routine for RealTimeClockInstance->GetWakeupTime
137 This - Indicates the protocol instance structure.
139 Enabled - Indicates if the alarm is currently enabled or disabled.
141 Pending - Indicates if the alarm signal is pending and requires
144 Time - The current alarm setting.
148 EFI_SUCEESS - The operation completed successfully.
150 EFI_DEVICE_ERROR - The operation could not be complete due to a device error.
152 EFI_UNSUPPORTED - The operation is not supported on this platform.
156 return EFI_UNSUPPORTED
;
168 Service routine for RealTimeClockInstance->SetWakeupTime
172 Enabled - Enable or disable the wakeup alarm.
174 Time - If enable is TRUE, the time to set the wakup alarm for.
175 If enable is FALSE, then this parameter is optional, and
180 EFI_SUCEESS - The operation completed successfully.
182 EFI_DEVICE_ERROR - The operation could not be complete due to a device error.
184 EFI_INVALID_PARAMETER - A field in Time is out of range.
186 EFI_UNSUPPORTED - The operation is not supported on this platform.
190 return EFI_UNSUPPORTED
;
195 InitializeRealTimeClock (
196 IN EFI_HANDLE ImageHandle
,
197 IN EFI_SYSTEM_TABLE
*SystemTable
202 Install Real Time Clock Protocol
205 ImageHandle - Image Handle
206 SystemTable - Pointer to system table
210 EFI_SUCEESS - Real Time Clock Services are installed into the Runtime Services Table
217 SystemTable
->RuntimeServices
->GetTime
= EmuGetTime
;
218 SystemTable
->RuntimeServices
->SetTime
= EmuSetTime
;
219 SystemTable
->RuntimeServices
->GetWakeupTime
= EmuGetWakeupTime
;
220 SystemTable
->RuntimeServices
->SetWakeupTime
= EmuSetWakeupTime
;
223 Status
= gBS
->InstallMultipleProtocolInterfaces (
225 &gEfiRealTimeClockArchProtocolGuid
,
245 if (Time
->Year
< 1998 ||
249 (!DayValid (Time
)) ||
253 Time
->Nanosecond
> 999999999 ||
254 (!(Time
->TimeZone
== EFI_UNSPECIFIED_TIMEZONE
|| (Time
->TimeZone
>= -1440 && Time
->TimeZone
<= 1440))) ||
255 (Time
->Daylight
& (~(EFI_TIME_ADJUST_DAYLIGHT
| EFI_TIME_IN_DAYLIGHT
)))
257 return EFI_INVALID_PARAMETER
;
269 STATIC
const INTN DayOfMonth
[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
272 Time
->Day
> DayOfMonth
[Time
->Month
- 1] ||
273 (Time
->Month
== 2 && (!IsLeapYear (Time
) && Time
->Day
> 28))
286 if (Time
->Year
% 4 == 0) {
287 if (Time
->Year
% 100 == 0) {
288 if (Time
->Year
% 400 == 0) {