From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from zg8tmtyylji0my4xnjqunzqa.icoremail.net (zg8tmtyylji0my4xnjqunzqa.icoremail.net [162.243.164.74]) by mx.groups.io with SMTP id smtpd.web12.5028.1631180989494475391 for ; Thu, 09 Sep 2021 02:49:49 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: phytium.com.cn, ip: 162.243.164.74, mailfrom: jialing@phytium.com.cn) Received: from prodtpl.icoremail.net (unknown [10.12.1.20]) by hzbj-icmmx-1 (Coremail) with SMTP id AQAAfwCHUK2A2DlhOorNAw--.54595S2; Thu, 09 Sep 2021 17:48:48 +0800 (CST) Received: from localhost.localdomain (unknown [223.104.131.170]) by mail (Coremail) with SMTP id AQAAfwBXEie32DlhvRIAAA--.679S5; Thu, 09 Sep 2021 17:49:45 +0800 (CST) From: "Ling Jia" To: devel@edk2.groups.io Cc: Leif Lindholm , Ling Jia Subject: [PATCH v5 09/10] Silicon/Phytium: Added Rtc driver to FT2000/4 Date: Thu, 9 Sep 2021 17:49:37 +0800 Message-Id: <20210909094938.5998-4-jialing@phytium.com.cn> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210909094938.5998-1-jialing@phytium.com.cn> References: <20210909094938.5998-1-jialing@phytium.com.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAfwBXEie32DlhvRIAAA--.679S5 X-CM-SenderInfo: xmldzxdqj61x51wl3zoofrzhdfq/ Authentication-Results: hzbj-icmmx-1; spf=neutral smtp.mail=jialing@ph ytium.com.cn; X-Coremail-Antispam: 1Uk129KBjvAXoWfGF1UuFy3XFWkZF4xZw4UXFb_yoW8ArWkKo WfGrWIq3y8Gr1rua4ftw1kArW2grZagan0qr4jvFZ7KanrZr1SyFyUt3W2qry3tr9rAw43 KrWfJ3s7AFWaqFs7n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3UbIjqfuFe4nvWSU8nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UU UUUUUUU== Content-Transfer-Encoding: quoted-printable The RealTimeClockLib implemented EFI RealTimeClock runtime services via RTC Lib. Signed-off-by: Ling Jia Reviewed-by: Leif Lindholm --- Silicon/Phytium/PhytiumCommonPkg/PhytiumCommonPkg.dec = | 1 + Platform/Phytium/DurianPkg/DurianPkg.dsc = | 6 + Platform/Phytium/DurianPkg/DurianPkg.fdf = | 2 + Silicon/Phytium/FT2000-4Pkg/Library/RealTimeClockLib/RealTimeClockLib.inf = | 39 ++ Silicon/Phytium/FT2000-4Pkg/Library/RealTimeClockLib/RealTimeClockLib.h = | 24 + Silicon/Phytium/FT2000-4Pkg/Library/RealTimeClockLib/RealTimeClockLib.c = | 462 ++++++++++++++++++++ 6 files changed, 534 insertions(+) diff --git a/Silicon/Phytium/PhytiumCommonPkg/PhytiumCommonPkg.dec b/Silico= n/Phytium/PhytiumCommonPkg/PhytiumCommonPkg.dec index 2686ba3cc3..4c6c5c5f11 100644 --- a/Silicon/Phytium/PhytiumCommonPkg/PhytiumCommonPkg.dec +++ b/Silicon/Phytium/PhytiumCommonPkg/PhytiumCommonPkg.dec @@ -45,6 +45,7 @@ gPhytiumPlatformTokenSpaceGuid.PcdSpiFlashSize|0x0|UINT64|0x00000005=0D gPhytiumPlatformTokenSpaceGuid.PcdSpiControllerBase|0x0|UINT64|0x0000000= 6=0D gPhytiumPlatformTokenSpaceGuid.PcdSpiControllerSize|0x0|UINT64|0x0000000= 7=0D + gPhytiumPlatformTokenSpaceGuid.PcdRtcBaseAddress|0x0|UINT32|0x00000008=0D =0D [Protocols]=0D gSpiMasterProtocolGuid =3D { 0xdf093560, 0xf955, 0x11ea, { 0x96, 0x42, 0= x43, 0x9d, 0x80, 0xdd, 0x0b, 0x7c}}=0D diff --git a/Platform/Phytium/DurianPkg/DurianPkg.dsc b/Platform/Phytium/Du= rianPkg/DurianPkg.dsc index 99034365d3..9579f8e9b7 100644 --- a/Platform/Phytium/DurianPkg/DurianPkg.dsc +++ b/Platform/Phytium/DurianPkg/DurianPkg.dsc @@ -29,6 +29,10 @@ # Phytium Platform library=0D ArmPlatformLib|Silicon/Phytium/FT2000-4Pkg/Library/PlatformLib/PlatformL= ib.inf=0D =0D + #FT2000-4Pkg RTC Driver=0D + RealTimeClockLib|Silicon/Phytium/FT2000-4Pkg/Library/RealTimeClockLib/Re= alTimeClockLib.inf=0D + TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf=0D +=0D # PL011 UART Driver and Dependency Libraries=0D SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortL= ib.inf=0D PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartCloc= kLib.inf=0D @@ -168,6 +172,8 @@ NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf=0D }=0D MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf=0D + EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf=0D + EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf=0D =0D #=0D # Common Arm Timer and Gic Components=0D diff --git a/Platform/Phytium/DurianPkg/DurianPkg.fdf b/Platform/Phytium/Du= rianPkg/DurianPkg.fdf index 67458458dd..242f647ca1 100644 --- a/Platform/Phytium/DurianPkg/DurianPkg.fdf +++ b/Platform/Phytium/DurianPkg/DurianPkg.fdf @@ -93,6 +93,8 @@ READ_LOCK_STATUS =3D TRUE #=0D INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf=0D INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf=0D + INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf=0D + INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf=0D INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf=0D =0D INF Silicon/Phytium/FT2000-4Pkg/Drivers/SpiDxe/SpiDxe.inf=0D diff --git a/Silicon/Phytium/FT2000-4Pkg/Library/RealTimeClockLib/RealTimeC= lockLib.inf b/Silicon/Phytium/FT2000-4Pkg/Library/RealTimeClockLib/RealTime= ClockLib.inf new file mode 100644 index 0000000000..09a06d53ae --- /dev/null +++ b/Silicon/Phytium/FT2000-4Pkg/Library/RealTimeClockLib/RealTimeClockLib= .inf @@ -0,0 +1,39 @@ +#/** @file=0D +# Phytium RealTime Clock Library file.=0D +#=0D +# Copyright (C) 2020, Phytium Technology Co, Ltd. All rights reserved.=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +#**/=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x0001001b=0D + BASE_NAME =3D RealTimeClockLib=0D + FILE_GUID =3D fb320c94-40fe-11eb-b990-171865af292c= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D RealTimeClockLib=0D +=0D +[Sources.common]=0D + RealTimeClockLib.c=0D + RealTimeClockLib.h=0D +=0D +[Packages]=0D + ArmPlatformPkg/ArmPlatformPkg.dec=0D + EmbeddedPkg/EmbeddedPkg.dec=0D + MdePkg/MdePkg.dec=0D + Silicon/Phytium/PhytiumCommonPkg/PhytiumCommonPkg.dec=0D +=0D +[LibraryClasses]=0D + DebugLib=0D + DxeServicesTableLib=0D + IoLib=0D + TimeBaseLib=0D + UefiRuntimeLib=0D +=0D +[Guids]=0D + gEfiEventVirtualAddressChangeGuid=0D +=0D +[Pcd]=0D + gPhytiumPlatformTokenSpaceGuid.PcdRtcBaseAddress=0D diff --git a/Silicon/Phytium/FT2000-4Pkg/Library/RealTimeClockLib/RealTimeC= lockLib.h b/Silicon/Phytium/FT2000-4Pkg/Library/RealTimeClockLib/RealTimeCl= ockLib.h new file mode 100644 index 0000000000..41ce002dc3 --- /dev/null +++ b/Silicon/Phytium/FT2000-4Pkg/Library/RealTimeClockLib/RealTimeClockLib= .h @@ -0,0 +1,24 @@ +/** @file=0D + Phytium RealTime Clock Header.=0D +=0D + Copyright (C) 2020, Phytium Technology Co Ltd. All rights reserved.
= =0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef REAL_TIME_CLOCK_H_=0D +#define REAL_TIME_CLOCK_H_=0D +=0D +#define RTC_CMR 0x4=0D +#define RTC_AES_SEL 0x8=0D +#define RTC_CCR 0xC=0D +#define RTC_STAT 0x10=0D +#define RTC_RSTAT 0x14=0D +#define RTC_EOI 0x18=0D +#define RTC_CDR_LOW 0x20=0D +#define RTC_CCVR 0x24=0D +#define RTC_CLR_LOW 0x28=0D +#define RTC_CLR 0x2C=0D +=0D +#endif // REAL_TIME_CLOCK_H_=0D diff --git a/Silicon/Phytium/FT2000-4Pkg/Library/RealTimeClockLib/RealTimeC= lockLib.c b/Silicon/Phytium/FT2000-4Pkg/Library/RealTimeClockLib/RealTimeCl= ockLib.c new file mode 100644 index 0000000000..1c88958e3b --- /dev/null +++ b/Silicon/Phytium/FT2000-4Pkg/Library/RealTimeClockLib/RealTimeClockLib= .c @@ -0,0 +1,462 @@ +/** @file=0D + Implement EFI RealTimeClock runtime services via RTC Lib.=0D +=0D + Copyright (C) 2020, Phytium Technology Co Ltd. All rights reserved.
= =0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include "RealTimeClockLib.h"=0D +=0D +STATIC EFI_EVENT mRtcVirtualAddrChangeEvent;=0D +STATIC UINTN mRtcBase;=0D +STATIC CONST CHAR16 mTimeZoneVariableName[] =3D L"RtcTimeZone";=0D +STATIC CONST CHAR16 mDaylightVariableName[] =3D L"RtcDaylight";=0D +=0D +/**=0D + Returns the current time and date information, and the time-keeping capa= bilities=0D + of the hardware platform.=0D +=0D + @param Time A pointer to storage to receive a snapsho= t of the current time.=0D + @param Capabilities An optional pointer to a buffer to receiv= e the real time clock=0D + device's capabilities.=0D +=0D + @retval EFI_SUCCESS The operation completed successfully.=0D + @retval EFI_INVALID_PARAMETER Time is NULL.=0D + @retval EFI_DEVICE_ERROR The time could not be retrieved due to ha= rdware error.=0D + @retval EFI_SECURITY_VIOLATION The time could not be retrieved due to an= authentication failure.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +LibGetTime (=0D + OUT EFI_TIME *Time,=0D + OUT EFI_TIME_CAPABILITIES *Capabilities=0D + )=0D +{=0D + UINT32 EpochSeconds;=0D + INT16 TimeZone;=0D + UINT8 Daylight;=0D + UINTN Size;=0D + EFI_STATUS Status;=0D +=0D + // Ensure Time is a valid pointer=0D + if (Time =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + MmioWrite32 (mRtcBase + RTC_AES_SEL, 0x100);=0D + //=0D + //read cdr high 32bit=0D + //=0D + EpochSeconds =3D MmioRead32 (mRtcBase + RTC_CCVR);=0D + MmioRead32 (mRtcBase + RTC_CDR_LOW);=0D + //=0D + // Get the current time zone information from non-volatile storage=0D + //=0D + Size =3D sizeof (TimeZone);=0D + Status =3D EfiGetVariable (=0D + (CHAR16 *)mTimeZoneVariableName,=0D + &gEfiCallerIdGuid,=0D + NULL,=0D + &Size,=0D + (VOID *)&TimeZone=0D + );=0D +=0D + if (EFI_ERROR (Status)) {=0D + ASSERT (Status !=3D EFI_INVALID_PARAMETER);=0D + ASSERT (Status !=3D EFI_BUFFER_TOO_SMALL);=0D + //=0D + // The time zone variable does not exist in non-volatile storage, so c= reate it.=0D + //UTC+8:00=0D + //=0D + Time->TimeZone =3D -480;=0D + //=0D + // Store it=0D + //=0D + Status =3D EfiSetVariable (=0D + (CHAR16 *)mTimeZoneVariableName,=0D + &gEfiCallerIdGuid,=0D + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VA= RIABLE_RUNTIME_ACCESS,=0D + Size,=0D + (VOID *)&(Time->TimeZone)=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D + } else {=0D + //=0D + // Got the time zone=0D + //=0D + Time->TimeZone =3D TimeZone;=0D + //=0D + // Check TimeZone bounds: -1440 to 1440 or 2047=0D + //=0D + if(!IsValidTimeZone(Time->TimeZone)) {=0D + Time->TimeZone =3D EFI_UNSPECIFIED_TIMEZONE;=0D + }=0D + //=0D + // Adjust for the correct time zone=0D + //=0D + if (IsValidTimeZone(Time->TimeZone)) {=0D + EpochSeconds -=3D Time->TimeZone * SEC_PER_MIN;=0D + }=0D + }=0D + //=0D + // Get the current daylight information from non-volatile storage=0D + //=0D + Size =3D sizeof (Daylight);=0D + Status =3D EfiGetVariable (=0D + (CHAR16 *)mDaylightVariableName,=0D + &gEfiCallerIdGuid,=0D + NULL,=0D + &Size,=0D + (VOID *)&Daylight=0D + );=0D +=0D + if (EFI_ERROR (Status)) {=0D + ASSERT (Status !=3D EFI_INVALID_PARAMETER);=0D + ASSERT (Status !=3D EFI_BUFFER_TOO_SMALL);=0D + //=0D + // The daylight variable does not exist in non-volatile storage, so cr= eate it.=0D + //=0D + Time->Daylight =3D 0;=0D + //=0D + // Store it=0D + //=0D + Status =3D EfiSetVariable (=0D + (CHAR16 *)mDaylightVariableName,=0D + &gEfiCallerIdGuid,=0D + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VA= RIABLE_RUNTIME_ACCESS,=0D + Size,=0D + (VOID *)&(Time->Daylight)=0D + );=0D +=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D + } else {=0D + //=0D + // Got the daylight information=0D + //=0D + Time->Daylight =3D Daylight;=0D + //=0D + // Adjust for the correct period=0D + //=0D + if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) =3D=3D EFI_TIME_IN_DAYLIGH= T) {=0D + //=0D + // Convert to adjusted time, i.e. spring forwards one hour=0D + //=0D + EpochSeconds +=3D SEC_PER_HOUR;=0D + }=0D + }=0D +=0D + //=0D + // Convert from internal 32-bit time to UEFI time=0D + //=0D + EpochToEfiTime (EpochSeconds, Time);=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +=0D +/**=0D + Sets the current local time and date information.=0D +=0D + @param[in] Time A pointer to the current time.=0D +=0D + @retval EFI_SUCCESS The operation completed successfully.=0D + @retval EFI_INVALID_PARAMETER A time field is out of range.=0D + @retval EFI_DEVICE_ERROR The time could not be set due due to hardw= are error.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +LibSetTime (=0D + IN EFI_TIME *Time=0D + )=0D +{=0D + UINTN EpochSeconds;=0D + EFI_STATUS Status;=0D + //=0D + // the maximum time span is just over 136 years.=0D + // Time is stored in Unix Epoch format, so it starts in 1970,=0D + // Therefore it can not exceed the year 2106.=0D + //=0D + if ((Time->Year < 1970) || (Time->Year >=3D 2106)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D + EpochSeconds =3D EfiTimeToEpoch (Time);=0D + //=0D + // Adjust for the correct time zone, i.e. convert to UTC time zone=0D + //=0D + if (IsValidTimeZone(Time->TimeZone)) {=0D + EpochSeconds +=3D Time->TimeZone * SEC_PER_MIN;=0D + }=0D + //=0D + // Adjust for the correct period=0D + //=0D + if (((Time->Daylight & EFI_TIME_IN_DAYLIGHT) =3D=3D EFI_TIME_IN_DAYLIGHT= )=0D + && (EpochSeconds > SEC_PER_HOUR)) {=0D + //=0D + // Convert to un-adjusted time, i.e. fall back one hour=0D + //=0D + EpochSeconds -=3D SEC_PER_HOUR;=0D + }=0D + //=0D + // Set the Rtc=0D + //=0D + MmioWrite32 (mRtcBase + RTC_AES_SEL, 0x100);=0D + MmioWrite32 (mRtcBase + RTC_CLR_LOW, 0x0);=0D + MmioWrite32 (mRtcBase + RTC_CLR, (UINT32)EpochSeconds);=0D + //=0D + // Save the current time zone information into non-volatile storage=0D + //=0D + Status =3D EfiSetVariable (=0D + (CHAR16 *)mTimeZoneVariableName,=0D + &gEfiCallerIdGuid,=0D + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARI= ABLE_RUNTIME_ACCESS,=0D + sizeof (Time->TimeZone),=0D + (VOID *)&(Time->TimeZone)=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D + //=0D + // Save the current daylight information into non-volatile storage=0D + //=0D + Status =3D EfiSetVariable (=0D + (CHAR16 *)mDaylightVariableName,=0D + &gEfiCallerIdGuid,=0D + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARI= ABLE_RUNTIME_ACCESS,=0D + sizeof (Time->Daylight),=0D + (VOID *)&(Time->Daylight)=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D + return EFI_SUCCESS;=0D +}=0D +=0D +=0D +/**=0D + Returns the current wakeup alarm clock setting.=0D +=0D + @param[out] Enabled Indicates if the alarm is currently e= nabled or disabled.=0D + @param[out] Pending Indicates if the alarm signal is pend= ing and requires acknowledgement.=0D + @param[out] Time The current alarm setting.=0D +=0D + @retval EFI_SUCCESS The alarm settings were returned.=0D + @retval EFI_INVALID_PARAMETER Any parameter is NULL.=0D + @retval EFI_DEVICE_ERROR The wakeup time could not be retrieve= d due to a hardware error.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +LibGetWakeupTime (=0D + OUT BOOLEAN *Enabled,=0D + OUT BOOLEAN *Pending,=0D + OUT EFI_TIME *Time=0D + )=0D +{=0D + // Not a required feature=0D + return EFI_UNSUPPORTED;=0D +}=0D +=0D +=0D +/**=0D + Sets the system wakeup alarm clock time.=0D +=0D + @param[in] Enabled Enable or disable the wakeup alarm.=0D + @param[out] Time If Enable is TRUE, the time to set th= e wakeup alarm for.=0D +=0D + @retval EFI_SUCCESS If Enable is TRUE, then the wakeup al= arm was enabled. If=0D + Enable is FALSE, then the wakeup alar= m was disabled.=0D + @retval EFI_INVALID_PARAMETER A time field is out of range.=0D + @retval EFI_DEVICE_ERROR The wakeup time could not be set due = to a hardware error.=0D + @retval EFI_UNSUPPORTED A wakeup timer is not supported on th= is platform.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +LibSetWakeupTime (=0D + IN BOOLEAN Enabled,=0D + OUT EFI_TIME *Time=0D + )=0D +{=0D + // Not a required feature=0D + return EFI_UNSUPPORTED;=0D +}=0D +=0D +/**=0D + Fixup internal data so that EFI can be call in virtual mode.=0D + Call the passed in Child Notify event and convert any pointers in=0D + lib to virtual mode.=0D +=0D + @param[in] Event The Event that is being processed=0D + @param[in] Context Event Context=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +LibRtcVirtualNotifyEvent (=0D + IN EFI_EVENT Event,=0D + IN VOID *Context=0D + )=0D +{=0D + //=0D + // Only needed if you are going to support the OS calling RTC functions = in virtual mode.=0D + // You will need to call EfiConvertPointer (). To convert any stored phy= sical addresses=0D + // to virtual address. After the OS transitions to calling in virtual mo= de, all future=0D + // runtime calls will be made in virtual mode.=0D + //=0D + EfiConvertPointer (0x0, (VOID **)&mRtcBase);=0D +=0D + return;=0D +}=0D +=0D +/**=0D + This is the declaration of an EFI image entry point. This can be the ent= ry point to an application=0D + written to this specification, an EFI boot service driver, or an EFI run= time driver.=0D +=0D + @param[in] ImageHandle Handle that identifies the loaded imag= e.=0D + @param[in] SystemTable System Table for this image.=0D +=0D + @retval EFI_SUCCESS The operation completed successfully.= =0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +LibRtcInitialize (=0D + IN EFI_HANDLE ImageHandle,=0D + IN EFI_SYSTEM_TABLE *SystemTable=0D + )=0D +{=0D + EFI_STATUS Status;=0D + EFI_HANDLE Handle;=0D + INT16 TimeZone;=0D + UINTN Size;=0D + EFI_TIME Time;=0D + UINT8 Daylight;=0D + //=0D + // Initialize RTC Base Address=0D + //=0D + mRtcBase =3D PcdGet32 (PcdRtcBaseAddress);=0D + //=0D + // Declare the controller as EFI_MEMORY_RUNTIME=0D + //=0D + Status =3D gDS->AddMemorySpace (=0D + EfiGcdMemoryTypeMemoryMappedIo,=0D + mRtcBase,=0D + SIZE_4KB,=0D + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME=0D + );=0D +=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D + //=0D + //init timezone=0D + //=0D + Size =3D sizeof (TimeZone);=0D + Status =3D EfiGetVariable (=0D + (CHAR16 *)mTimeZoneVariableName,=0D + &gEfiCallerIdGuid,=0D + NULL,=0D + &Size,=0D + (VOID *)&TimeZone=0D + );=0D + if (EFI_ERROR (Status)) {=0D + ASSERT (Status !=3D EFI_INVALID_PARAMETER);=0D + ASSERT (Status !=3D EFI_BUFFER_TOO_SMALL);=0D + //=0D + // The time zone variable does not exist in non-volatile storage, so c= reate it.=0D + //UTC 8:00=0D + //=0D + Time.TimeZone =3D -480;=0D + //=0D + // Store it=0D + //=0D + Status =3D EfiSetVariable (=0D + (CHAR16 *)mTimeZoneVariableName,=0D + &gEfiCallerIdGuid,=0D + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VA= RIABLE_RUNTIME_ACCESS,=0D + Size,=0D + (VOID *)&(Time.TimeZone)=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D + }=0D + //=0D + //daylight init=0D + //=0D + Size =3D sizeof (Daylight);=0D + Status =3D EfiGetVariable (=0D + (CHAR16 *)mDaylightVariableName,=0D + &gEfiCallerIdGuid,=0D + NULL,=0D + &Size,=0D + (VOID *)&Daylight=0D + );=0D + if (EFI_ERROR (Status)) {=0D + ASSERT (Status !=3D EFI_INVALID_PARAMETER);=0D + ASSERT (Status !=3D EFI_BUFFER_TOO_SMALL);=0D + //=0D + // The daylight variable does not exist in non-volatile storage, so cr= eate it.=0D + //=0D + Time.Daylight =3D 0;=0D + //=0D + // Store it=0D + //=0D + Status =3D EfiSetVariable (=0D + (CHAR16 *)mDaylightVariableName,=0D + &gEfiCallerIdGuid,=0D + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VA= RIABLE_RUNTIME_ACCESS,=0D + Size,=0D + (VOID *)&(Time.Daylight)=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D + }=0D +=0D + Status =3D gDS->SetMemorySpaceAttributes (mRtcBase, SIZE_4KB, EFI_MEMORY= _UC | EFI_MEMORY_RUNTIME);=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D + //=0D + // Install the protocol=0D + //=0D + Handle =3D NULL;=0D + Status =3D gBS->InstallMultipleProtocolInterfaces (=0D + &Handle,=0D + &gEfiRealTimeClockArchProtocolGuid,=0D + NULL,=0D + NULL=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D + //=0D + // Register for the virtual address change event=0D + //=0D + Status =3D gBS->CreateEventEx (=0D + EVT_NOTIFY_SIGNAL,=0D + TPL_NOTIFY,=0D + LibRtcVirtualNotifyEvent,=0D + NULL,=0D + &gEfiEventVirtualAddressChangeGuid,=0D + &mRtcVirtualAddrChangeEvent=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D + return Status;=0D +}=0D --=20 2.25.1