uefi stuff
This commit is contained in:
@@ -0,0 +1,611 @@
|
||||
From d9b5815d797260ca8c8af1f8cca19e85c8c32a09 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Mario=20B=C4=83l=C4=83nic=C4=83?=
|
||||
<mariobalanica02@gmail.com>
|
||||
Date: Fri, 29 Dec 2023 23:29:47 +0200
|
||||
Subject: [PATCH 09/16] Platform/RPi5: Add real-time clock support
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Working get/set time and wake up alarm within UEFI.
|
||||
|
||||
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
|
||||
---
|
||||
.../Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c | 110 ++++++-
|
||||
.../Include/IndustryStandard/RpiMbox.h | 2 +
|
||||
.../Include/Protocol/RpiFirmware.h | 28 ++
|
||||
.../RaspberryPi/Library/RpiRtcLib/RpiRtcLib.c | 305 ++++++++++++++++++
|
||||
.../Library/RpiRtcLib/RpiRtcLib.inf | 42 +++
|
||||
Platform/RaspberryPi/RPi5/RPi5.dsc | 2 +-
|
||||
6 files changed, 487 insertions(+), 2 deletions(-)
|
||||
create mode 100644 Platform/RaspberryPi/Library/RpiRtcLib/RpiRtcLib.c
|
||||
create mode 100644 Platform/RaspberryPi/Library/RpiRtcLib/RpiRtcLib.inf
|
||||
|
||||
diff --git a/Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c b/Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
|
||||
index 9077f077..b432e828 100644
|
||||
--- a/Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
|
||||
+++ b/Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
|
||||
@@ -1,5 +1,6 @@
|
||||
/** @file
|
||||
*
|
||||
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
|
||||
* Copyright (c) 2020, Pete Batard <pete@akeo.ie>
|
||||
* Copyright (c) 2019, ARM Limited. All rights reserved.
|
||||
* Copyright (c) 2017-2020, Andrei Warkentin <andrey.warkentin@gmail.com>
|
||||
@@ -1332,6 +1333,111 @@ RpiFirmwareNotifyGpioSetCfg (
|
||||
return Status;
|
||||
}
|
||||
|
||||
+
|
||||
+#pragma pack()
|
||||
+typedef struct {
|
||||
+ UINT32 Register;
|
||||
+ UINT32 Value;
|
||||
+} RPI_FW_RTC_TAG;
|
||||
+
|
||||
+typedef struct {
|
||||
+ RPI_FW_BUFFER_HEAD BufferHead;
|
||||
+ RPI_FW_TAG_HEAD TagHead;
|
||||
+ RPI_FW_RTC_TAG TagBody;
|
||||
+ UINT32 EndTag;
|
||||
+} RPI_FW_RTC_CMD;
|
||||
+#pragma pack()
|
||||
+
|
||||
+STATIC
|
||||
+EFI_STATUS
|
||||
+EFIAPI
|
||||
+RpiFirmwareGetRtc (
|
||||
+ IN RASPBERRY_PI_RTC_REGISTER Register,
|
||||
+ OUT UINT32 *Value
|
||||
+ )
|
||||
+{
|
||||
+ RPI_FW_RTC_CMD *Cmd;
|
||||
+ EFI_STATUS Status;
|
||||
+ UINT32 Result;
|
||||
+
|
||||
+ if (!AcquireSpinLockOrFail (&mMailboxLock)) {
|
||||
+ DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
|
||||
+ return EFI_DEVICE_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ Cmd = mDmaBuffer;
|
||||
+ ZeroMem (Cmd, sizeof (*Cmd));
|
||||
+
|
||||
+ Cmd->BufferHead.BufferSize = sizeof (*Cmd);
|
||||
+ Cmd->BufferHead.Response = 0;
|
||||
+ Cmd->TagHead.TagId = RPI_MBOX_GET_RTC_REG;
|
||||
+ Cmd->TagHead.TagSize = sizeof (Cmd->TagBody);
|
||||
+ Cmd->TagHead.TagValueSize = 0;
|
||||
+ Cmd->TagBody.Register = Register;
|
||||
+ Cmd->TagBody.Value = 0;
|
||||
+ Cmd->EndTag = 0;
|
||||
+
|
||||
+ Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_MBOX_VC_CHANNEL, &Result);
|
||||
+
|
||||
+ if (EFI_ERROR (Status) ||
|
||||
+ Cmd->BufferHead.Response != RPI_MBOX_RESP_SUCCESS) {
|
||||
+ DEBUG ((DEBUG_ERROR,
|
||||
+ "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
|
||||
+ __FUNCTION__, Status, Cmd->BufferHead.Response));
|
||||
+ Status = EFI_DEVICE_ERROR;
|
||||
+ } else {
|
||||
+ *Value = Cmd->TagBody.Value;
|
||||
+ }
|
||||
+
|
||||
+ ReleaseSpinLock (&mMailboxLock);
|
||||
+
|
||||
+ return Status;
|
||||
+}
|
||||
+
|
||||
+STATIC
|
||||
+EFI_STATUS
|
||||
+EFIAPI
|
||||
+RpiFirmwareSetRtc (
|
||||
+ IN RASPBERRY_PI_RTC_REGISTER Register,
|
||||
+ IN UINT32 Value
|
||||
+ )
|
||||
+{
|
||||
+ RPI_FW_RTC_CMD *Cmd;
|
||||
+ EFI_STATUS Status;
|
||||
+ UINT32 Result;
|
||||
+
|
||||
+ if (!AcquireSpinLockOrFail (&mMailboxLock)) {
|
||||
+ DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
|
||||
+ return EFI_DEVICE_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ Cmd = mDmaBuffer;
|
||||
+ ZeroMem (Cmd, sizeof (*Cmd));
|
||||
+
|
||||
+ Cmd->BufferHead.BufferSize = sizeof (*Cmd);
|
||||
+ Cmd->BufferHead.Response = 0;
|
||||
+ Cmd->TagHead.TagId = RPI_MBOX_SET_RTC_REG;
|
||||
+ Cmd->TagHead.TagSize = sizeof (Cmd->TagBody);
|
||||
+ Cmd->TagHead.TagValueSize = 0;
|
||||
+ Cmd->TagBody.Register = Register;
|
||||
+ Cmd->TagBody.Value = Value;
|
||||
+ Cmd->EndTag = 0;
|
||||
+
|
||||
+ Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_MBOX_VC_CHANNEL, &Result);
|
||||
+
|
||||
+ if (EFI_ERROR (Status) ||
|
||||
+ Cmd->BufferHead.Response != RPI_MBOX_RESP_SUCCESS) {
|
||||
+ DEBUG ((DEBUG_ERROR,
|
||||
+ "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
|
||||
+ __FUNCTION__, Status, Cmd->BufferHead.Response));
|
||||
+ Status = EFI_DEVICE_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ ReleaseSpinLock (&mMailboxLock);
|
||||
+
|
||||
+ return Status;
|
||||
+}
|
||||
+
|
||||
STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL mRpiFirmwareProtocol = {
|
||||
RpiFirmwareSetPowerState,
|
||||
RpiFirmwareGetMacAddress,
|
||||
@@ -1352,7 +1458,9 @@ STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL mRpiFirmwareProtocol = {
|
||||
RpiFirmwareNotifyXhciReset,
|
||||
RpiFirmwareGetCurrentClockState,
|
||||
RpiFirmwareSetClockState,
|
||||
- RpiFirmwareNotifyGpioSetCfg
|
||||
+ RpiFirmwareNotifyGpioSetCfg,
|
||||
+ RpiFirmwareGetRtc,
|
||||
+ RpiFirmwareSetRtc,
|
||||
};
|
||||
|
||||
/**
|
||||
diff --git a/Platform/RaspberryPi/Include/IndustryStandard/RpiMbox.h b/Platform/RaspberryPi/Include/IndustryStandard/RpiMbox.h
|
||||
index 551c2b82..916b7442 100644
|
||||
--- a/Platform/RaspberryPi/Include/IndustryStandard/RpiMbox.h
|
||||
+++ b/Platform/RaspberryPi/Include/IndustryStandard/RpiMbox.h
|
||||
@@ -93,6 +93,7 @@
|
||||
#define RPI_MBOX_GET_POE_HAT_VAL 0x00030049
|
||||
#define RPI_MBOX_SET_POE_HAT_VAL 0x00030050
|
||||
#define RPI_MBOX_NOTIFY_XHCI_RESET 0x00030058
|
||||
+#define RPI_MBOX_GET_RTC_REG 0x00030087
|
||||
|
||||
#define RPI_MBOX_SET_CLOCK_STATE 0x00038001
|
||||
#define RPI_MBOX_SET_CLOCK_RATE 0x00038002
|
||||
@@ -104,6 +105,7 @@
|
||||
#define RPI_MBOX_SET_SDHOST_CLOCK 0x00038042
|
||||
#define RPI_MBOX_SET_GPIO_CONFIG 0x00038043
|
||||
#define RPI_MBOX_SET_PERIPH_REG 0x00038045
|
||||
+#define RPI_MBOX_SET_RTC_REG 0x00038087
|
||||
|
||||
#define RPI_MBOX_ALLOC_FB 0x00040001
|
||||
#define RPI_MBOX_FB_BLANK 0x00040002
|
||||
diff --git a/Platform/RaspberryPi/Include/Protocol/RpiFirmware.h b/Platform/RaspberryPi/Include/Protocol/RpiFirmware.h
|
||||
index 86bf1687..92ab7f84 100644
|
||||
--- a/Platform/RaspberryPi/Include/Protocol/RpiFirmware.h
|
||||
+++ b/Platform/RaspberryPi/Include/Protocol/RpiFirmware.h
|
||||
@@ -1,5 +1,6 @@
|
||||
/** @file
|
||||
*
|
||||
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
|
||||
* Copyright (c) 2019, ARM Limited. All rights reserved.
|
||||
* Copyright (c) 2017 - 2020, Andrei Warkentin <andrey.warkentin@gmail.com>
|
||||
* Copyright (c) 2016, Linaro Limited. All rights reserved.
|
||||
@@ -14,6 +15,17 @@
|
||||
#define RASPBERRY_PI_FIRMWARE_PROTOL_GUID \
|
||||
{ 0x0ACA9535, 0x7AD0, 0x4286, { 0xB0, 0x2E, 0x87, 0xFA, 0x7E, 0x2A, 0x57, 0x11 } }
|
||||
|
||||
+typedef enum {
|
||||
+ RpiRtcTime = 0,
|
||||
+ RpiRtcAlarm,
|
||||
+ RpiRtcAlarmPending,
|
||||
+ RpiRtcAlarmEnable,
|
||||
+ RpiRtcBatteryChargeVoltage,
|
||||
+ RpiRtcBatteryChargeVoltageMin,
|
||||
+ RpiRtcBatteryChargeVoltageMax,
|
||||
+ RpiRtcBatteryVoltage,
|
||||
+} RASPBERRY_PI_RTC_REGISTER;
|
||||
+
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *SET_POWER_STATE) (
|
||||
@@ -141,6 +153,20 @@ EFI_STATUS
|
||||
UINTN State
|
||||
);
|
||||
|
||||
+typedef
|
||||
+EFI_STATUS
|
||||
+(EFIAPI *GET_RTC) (
|
||||
+ IN RASPBERRY_PI_RTC_REGISTER Register,
|
||||
+ OUT UINT32 *Value
|
||||
+ );
|
||||
+
|
||||
+typedef
|
||||
+EFI_STATUS
|
||||
+(EFIAPI *SET_RTC) (
|
||||
+ IN RASPBERRY_PI_RTC_REGISTER Register,
|
||||
+ IN UINT32 Value
|
||||
+ );
|
||||
+
|
||||
typedef struct {
|
||||
SET_POWER_STATE SetPowerState;
|
||||
GET_MAC_ADDRESS GetMacAddress;
|
||||
@@ -162,6 +188,8 @@ typedef struct {
|
||||
GET_CLOCK_STATE GetClockState;
|
||||
SET_CLOCK_STATE SetClockState;
|
||||
GPIO_SET_CFG SetGpioConfig;
|
||||
+ GET_RTC GetRtc;
|
||||
+ SET_RTC SetRtc;
|
||||
} RASPBERRY_PI_FIRMWARE_PROTOCOL;
|
||||
|
||||
extern EFI_GUID gRaspberryPiFirmwareProtocolGuid;
|
||||
diff --git a/Platform/RaspberryPi/Library/RpiRtcLib/RpiRtcLib.c b/Platform/RaspberryPi/Library/RpiRtcLib/RpiRtcLib.c
|
||||
new file mode 100644
|
||||
index 00000000..298b3678
|
||||
--- /dev/null
|
||||
+++ b/Platform/RaspberryPi/Library/RpiRtcLib/RpiRtcLib.c
|
||||
@@ -0,0 +1,305 @@
|
||||
+/** @file
|
||||
+ *
|
||||
+ * Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
+ *
|
||||
+ **/
|
||||
+
|
||||
+#include <PiDxe.h>
|
||||
+
|
||||
+#include <Library/DebugLib.h>
|
||||
+#include <Library/RealTimeClockLib.h>
|
||||
+#include <Library/TimeBaseLib.h>
|
||||
+#include <Library/UefiBootServicesTableLib.h>
|
||||
+#include <Library/UefiRuntimeLib.h>
|
||||
+
|
||||
+#include <Protocol/RpiFirmware.h>
|
||||
+
|
||||
+STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL *mFwProtocol;
|
||||
+
|
||||
+STATIC
|
||||
+VOID
|
||||
+EFIAPI
|
||||
+OffsetTimeZoneEpoch (
|
||||
+ IN EFI_TIME *Time,
|
||||
+ IN OUT UINT32 *EpochSeconds,
|
||||
+ IN BOOLEAN Add
|
||||
+ )
|
||||
+{
|
||||
+ //
|
||||
+ // Adjust for the correct time zone
|
||||
+ // The timezone setting also reflects the DST setting of the clock
|
||||
+ //
|
||||
+ if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) {
|
||||
+ *EpochSeconds += (Add ? 1 : -1) * Time->TimeZone * SEC_PER_MIN;
|
||||
+ } else if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) {
|
||||
+ // Convert to adjusted time, i.e. spring forwards one hour
|
||||
+ *EpochSeconds += (Add ? 1 : -1) * SEC_PER_HOUR;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ 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.
|
||||
+ @retval EFI_SECURITY_VIOLATION The time could not be retrieved due to an authentication failure.
|
||||
+
|
||||
+**/
|
||||
+EFI_STATUS
|
||||
+EFIAPI
|
||||
+LibGetTime (
|
||||
+ OUT EFI_TIME *Time,
|
||||
+ OUT EFI_TIME_CAPABILITIES *Capabilities
|
||||
+ )
|
||||
+{
|
||||
+ EFI_STATUS Status;
|
||||
+ UINT32 EpochSeconds;
|
||||
+
|
||||
+ if (Time == NULL) {
|
||||
+ return EFI_INVALID_PARAMETER;
|
||||
+ }
|
||||
+
|
||||
+ Status = mFwProtocol->GetRtc (RpiRtcTime, &EpochSeconds);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ OffsetTimeZoneEpoch (Time, &EpochSeconds, TRUE);
|
||||
+
|
||||
+ EpochToEfiTime (EpochSeconds, Time);
|
||||
+
|
||||
+ return EFI_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ 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 to hardware error.
|
||||
+
|
||||
+**/
|
||||
+EFI_STATUS
|
||||
+EFIAPI
|
||||
+LibSetTime (
|
||||
+ IN EFI_TIME *Time
|
||||
+ )
|
||||
+{
|
||||
+ EFI_STATUS Status;
|
||||
+ UINT32 EpochSeconds;
|
||||
+
|
||||
+ if (Time == NULL || !IsTimeValid (Time)) {
|
||||
+ return EFI_UNSUPPORTED;
|
||||
+ }
|
||||
+
|
||||
+ EpochSeconds = (UINT32)EfiTimeToEpoch (Time);
|
||||
+
|
||||
+ OffsetTimeZoneEpoch (Time, &EpochSeconds, FALSE);
|
||||
+
|
||||
+ Status = mFwProtocol->SetRtc (RpiRtcTime, EpochSeconds);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ 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
|
||||
+LibGetWakeupTime (
|
||||
+ OUT BOOLEAN *Enabled,
|
||||
+ OUT BOOLEAN *Pending,
|
||||
+ OUT EFI_TIME *Time
|
||||
+ )
|
||||
+{
|
||||
+ EFI_STATUS Status;
|
||||
+ UINT32 EpochSeconds;
|
||||
+ UINT32 EnableVal;
|
||||
+ UINT32 PendingVal;
|
||||
+
|
||||
+ if (Time == NULL || Enabled == NULL || Pending == NULL) {
|
||||
+ return EFI_INVALID_PARAMETER;
|
||||
+ }
|
||||
+
|
||||
+ Status = mFwProtocol->GetRtc (RpiRtcAlarmEnable, &EnableVal);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ Status = mFwProtocol->GetRtc (RpiRtcAlarmPending, &PendingVal);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ *Enabled = EnableVal;
|
||||
+ *Pending = PendingVal;
|
||||
+
|
||||
+ if (*Pending) {
|
||||
+ // Acknowledge alarm
|
||||
+ Status = mFwProtocol->SetRtc (RpiRtcAlarmPending, TRUE);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ Status = mFwProtocol->GetRtc (RpiRtcAlarm, &EpochSeconds);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ OffsetTimeZoneEpoch (Time, &EpochSeconds, TRUE);
|
||||
+
|
||||
+ EpochToEfiTime (EpochSeconds, Time);
|
||||
+
|
||||
+ return EFI_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ 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
|
||||
+LibSetWakeupTime (
|
||||
+ IN BOOLEAN Enabled,
|
||||
+ OUT EFI_TIME *Time
|
||||
+ )
|
||||
+{
|
||||
+ EFI_STATUS Status;
|
||||
+ UINT32 EpochSeconds;
|
||||
+
|
||||
+ if (Enabled) {
|
||||
+ if (Time == NULL || !IsTimeValid (Time)) {
|
||||
+ return EFI_INVALID_PARAMETER;
|
||||
+ }
|
||||
+
|
||||
+ EpochSeconds = (UINT32)EfiTimeToEpoch (Time);
|
||||
+
|
||||
+ OffsetTimeZoneEpoch (Time, &EpochSeconds, FALSE);
|
||||
+
|
||||
+ Status = mFwProtocol->SetRtc (RpiRtcAlarm, EpochSeconds);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ Status = mFwProtocol->SetRtc (RpiRtcAlarmEnable, Enabled);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ return EFI_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ Fixup internal data so that EFI can be call in virtual mode.
|
||||
+ Call the passed in Child Notify event and convert any pointers in
|
||||
+ lib to virtual mode.
|
||||
+
|
||||
+ @param[in] Event The Event that is being processed
|
||||
+ @param[in] Context Event Context
|
||||
+
|
||||
+**/
|
||||
+STATIC
|
||||
+VOID
|
||||
+EFIAPI
|
||||
+VirtualAddressChangeNotify (
|
||||
+ IN EFI_EVENT Event,
|
||||
+ IN VOID *Context
|
||||
+ )
|
||||
+{
|
||||
+ EfiConvertPointer (0x0, (VOID **)&mFwProtocol);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ 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
|
||||
+LibRtcInitialize (
|
||||
+ IN EFI_HANDLE ImageHandle,
|
||||
+ IN EFI_SYSTEM_TABLE *SystemTable
|
||||
+ )
|
||||
+{
|
||||
+ EFI_STATUS Status;
|
||||
+ EFI_TIME Time;
|
||||
+ EFI_EVENT VirtualAddressChangeEvent;
|
||||
+
|
||||
+ Status = gBS->LocateProtocol (
|
||||
+ &gRaspberryPiFirmwareProtocolGuid,
|
||||
+ NULL,
|
||||
+ (VOID **)&mFwProtocol);
|
||||
+ ASSERT_EFI_ERROR (Status);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ Status = gBS->CreateEventEx (
|
||||
+ EVT_NOTIFY_SIGNAL,
|
||||
+ TPL_NOTIFY,
|
||||
+ VirtualAddressChangeNotify,
|
||||
+ NULL,
|
||||
+ &gEfiEventVirtualAddressChangeGuid,
|
||||
+ &VirtualAddressChangeEvent);
|
||||
+ ASSERT_EFI_ERROR (Status);
|
||||
+ if (EFI_ERROR (Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // Initial RTC time starts off at Epoch = 0, which is out
|
||||
+ // of UEFI's bounds. Update it to the firmware build time.
|
||||
+ //
|
||||
+ Status = LibGetTime (&Time, NULL);
|
||||
+ if (EFI_ERROR(Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+
|
||||
+ if (!IsTimeValid (&Time)) {
|
||||
+ EpochToEfiTime (BUILD_EPOCH, &Time);
|
||||
+ Status = LibSetTime (&Time);
|
||||
+ if (EFI_ERROR(Status)) {
|
||||
+ return Status;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return EFI_SUCCESS;
|
||||
+}
|
||||
diff --git a/Platform/RaspberryPi/Library/RpiRtcLib/RpiRtcLib.inf b/Platform/RaspberryPi/Library/RpiRtcLib/RpiRtcLib.inf
|
||||
new file mode 100644
|
||||
index 00000000..f271f39c
|
||||
--- /dev/null
|
||||
+++ b/Platform/RaspberryPi/Library/RpiRtcLib/RpiRtcLib.inf
|
||||
@@ -0,0 +1,42 @@
|
||||
+#/** @file
|
||||
+#
|
||||
+# Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
|
||||
+#
|
||||
+# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
+#
|
||||
+#**/
|
||||
+
|
||||
+[Defines]
|
||||
+ INF_VERSION = 0x0001001A
|
||||
+ BASE_NAME = RpiRtcLib
|
||||
+ FILE_GUID = 2c823916-13b7-48f3-bb6d-a8cf438b91fd
|
||||
+ MODULE_TYPE = BASE
|
||||
+ VERSION_STRING = 1.0
|
||||
+ LIBRARY_CLASS = RealTimeClockLib
|
||||
+
|
||||
+[Sources.common]
|
||||
+ RpiRtcLib.c
|
||||
+
|
||||
+[Packages]
|
||||
+ EmbeddedPkg/EmbeddedPkg.dec
|
||||
+ MdePkg/MdePkg.dec
|
||||
+ Platform/RaspberryPi/RaspberryPi.dec
|
||||
+
|
||||
+[LibraryClasses]
|
||||
+ DebugLib
|
||||
+ TimeBaseLib
|
||||
+ UefiBootServicesTableLib
|
||||
+ UefiRuntimeLib
|
||||
+
|
||||
+[Guids]
|
||||
+ gEfiEventVirtualAddressChangeGuid
|
||||
+
|
||||
+[Protocols]
|
||||
+ gRaspberryPiFirmwareProtocolGuid ## CONSUMES
|
||||
+
|
||||
+[Depex]
|
||||
+ gRaspberryPiFirmwareProtocolGuid
|
||||
+
|
||||
+# Current usage of this library expects GCC in a UNIX-like shell environment with the date command
|
||||
+[BuildOptions]
|
||||
+ GCC:*_*_*_CC_FLAGS = -DBUILD_EPOCH=`date +%s`
|
||||
diff --git a/Platform/RaspberryPi/RPi5/RPi5.dsc b/Platform/RaspberryPi/RPi5/RPi5.dsc
|
||||
index f8e08de2..f2a1992e 100644
|
||||
--- a/Platform/RaspberryPi/RPi5/RPi5.dsc
|
||||
+++ b/Platform/RaspberryPi/RPi5/RPi5.dsc
|
||||
@@ -547,7 +547,7 @@
|
||||
EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
|
||||
EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf {
|
||||
<LibraryClasses>
|
||||
- RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
|
||||
+ RealTimeClockLib|Platform/RaspberryPi/Library/RpiRtcLib/RpiRtcLib.inf
|
||||
}
|
||||
EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
|
||||
|
||||
--
|
||||
2.51.2
|
||||
|
||||
Reference in New Issue
Block a user