summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClock.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClock.c')
-rw-r--r--src/VBox/Devices/EFI/Firmware/EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClock.c227
1 files changed, 227 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClock.c b/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClock.c
new file mode 100644
index 00000000..5081d612
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClock.c
@@ -0,0 +1,227 @@
+/** @file
+ Implement EFI RealTimeClock runtime services via RTC Lib.
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2017, Linaro, Ltd. All rights reserved.<BR>
+ Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/RealTimeClockLib.h>
+#include <Library/TimeBaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Protocol/RealTimeClock.h>
+
+EFI_HANDLE mHandle = NULL;
+
+//
+// These values can be set by SetTime () and need to be returned by GetTime ()
+// but cannot usually be kept by the RTC hardware, so we store them in a UEFI
+// variable instead.
+//
+typedef struct {
+ INT16 TimeZone;
+ UINT8 Daylight;
+} NON_VOLATILE_TIME_SETTINGS;
+
+STATIC CONST CHAR16 mTimeSettingsVariableName[] = L"RtcTimeSettings";
+STATIC NON_VOLATILE_TIME_SETTINGS mTimeSettings;
+
+/**
+ Returns the current time and date information, and the time-keeping capabilities
+ of the hardware platform.
+
+ @param Time A pointer to storage to receive a snapshot of the current time.
+ @param Capabilities An optional pointer to a buffer to receive the real time clock
+ device's capabilities.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER Time is NULL.
+ @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+GetTime (
+ OUT EFI_TIME *Time,
+ OUT EFI_TIME_CAPABILITIES *Capabilities
+ )
+{
+ if (Time == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Set these first so the RealTimeClockLib implementation
+ // can override them based on its own settings.
+ //
+ Time->TimeZone = mTimeSettings.TimeZone;
+ Time->Daylight = mTimeSettings.Daylight;
+
+ return LibGetTime (Time, Capabilities);
+}
+
+
+
+/**
+ Sets the current local time and date information.
+
+ @param Time A pointer to the current time.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER A time field is out of range.
+ @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+SetTime (
+ IN EFI_TIME *Time
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN TimeSettingsChanged;
+
+ if (Time == NULL || !IsTimeValid (Time)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TimeSettingsChanged = FALSE;
+ if (mTimeSettings.TimeZone != Time->TimeZone ||
+ mTimeSettings.Daylight != Time->Daylight) {
+
+ mTimeSettings.TimeZone = Time->TimeZone;
+ mTimeSettings.Daylight = Time->Daylight;
+ TimeSettingsChanged = TRUE;
+ }
+
+ Status = LibSetTime (Time);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (TimeSettingsChanged) {
+ Status = EfiSetVariable (
+ (CHAR16 *)mTimeSettingsVariableName,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof (mTimeSettings),
+ (VOID *)&mTimeSettings);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Returns the current wakeup alarm clock setting.
+
+ @param Enabled Indicates if the alarm is currently enabled or disabled.
+ @param Pending Indicates if the alarm signal is pending and requires acknowledgement.
+ @param Time The current alarm setting.
+
+ @retval EFI_SUCCESS The alarm settings were returned.
+ @retval EFI_INVALID_PARAMETER Any parameter is NULL.
+ @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+GetWakeupTime (
+ OUT BOOLEAN *Enabled,
+ OUT BOOLEAN *Pending,
+ OUT EFI_TIME *Time
+ )
+{
+ return LibGetWakeupTime (Enabled, Pending, Time);
+}
+
+
+/**
+ Sets the system wakeup alarm clock time.
+
+ @param Enabled Enable or disable the wakeup alarm.
+ @param Time If Enable is TRUE, the time to set the wakeup alarm for.
+
+ @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If
+ Enable is FALSE, then the wakeup alarm was disabled.
+ @retval EFI_INVALID_PARAMETER A time field is out of range.
+ @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error.
+ @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform.
+
+**/
+EFI_STATUS
+EFIAPI
+SetWakeupTime (
+ IN BOOLEAN Enabled,
+ OUT EFI_TIME *Time
+ )
+{
+ return LibSetWakeupTime (Enabled, Time);
+}
+
+
+
+/**
+ This is the declaration of an EFI image entry point. This can be the entry point to an application
+ written to this specification, an EFI boot service driver, or an EFI runtime driver.
+
+ @param ImageHandle Handle that identifies the loaded image.
+ @param SystemTable System Table for this image.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeRealTimeClock (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+
+ Status = LibRtcInitialize (ImageHandle, SystemTable);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Size = sizeof (mTimeSettings);
+ Status = EfiGetVariable ((CHAR16 *)mTimeSettingsVariableName,
+ &gEfiCallerIdGuid, NULL, &Size, (VOID *)&mTimeSettings);
+ if (EFI_ERROR (Status) ||
+ !IsValidTimeZone (mTimeSettings.TimeZone) ||
+ !IsValidDaylight (mTimeSettings.Daylight)) {
+ DEBUG ((DEBUG_WARN, "%a: using default timezone/daylight settings\n",
+ __FUNCTION__));
+
+ mTimeSettings.TimeZone = EFI_UNSPECIFIED_TIMEZONE;
+ mTimeSettings.Daylight = 0;
+ }
+
+ SystemTable->RuntimeServices->GetTime = GetTime;
+ SystemTable->RuntimeServices->SetTime = SetTime;
+ SystemTable->RuntimeServices->GetWakeupTime = GetWakeupTime;
+ SystemTable->RuntimeServices->SetWakeupTime = SetWakeupTime;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEfiRealTimeClockArchProtocolGuid,
+ NULL,
+ NULL
+ );
+
+ return Status;
+}
+