From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from zg8tmja2lje4os4yms4ymjma.icoremail.net (zg8tmja2lje4os4yms4ymjma.icoremail.net [206.189.21.223]) by mx.groups.io with SMTP id smtpd.web10.1382.1610700570477842863 for ; Fri, 15 Jan 2021 00:49:30 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: phytium.com.cn, ip: 206.189.21.223, mailfrom: jialing@phytium.com.cn) Received: from localhost.localdomain (unknown [117.136.88.47]) by c1app12 (Coremail) with SMTP id DAINCgDHzpbFVgFgExlyBA--.39669S12; Fri, 15 Jan 2021 16:49:23 +0800 (CST) From: Ling Jia To: devel@edk2.groups.io Cc: Leif Lindholm , Ling , Peng Xie , Yiqi Shu Subject: [PATCH v1 10/10] Silicon/Phytium: Added Rtc driver to Phytium2000-4 Date: Fri, 15 Jan 2021 08:48:02 +0000 Message-Id: <20210115084802.62196-11-jialing@phytium.com.cn> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210115084802.62196-1-jialing@phytium.com.cn> References: <20210115084802.62196-1-jialing@phytium.com.cn> MIME-Version: 1.0 X-CM-TRANSID: DAINCgDHzpbFVgFgExlyBA--.39669S12 X-Coremail-Antispam: 1UD129KBjvAXoW3tw43Kr1ktF1fuF1fWF1DAwb_yoW8Ary7Go WfKrWIq3y8Jr1ru3Wavw1kAr42grnagrs0qw4jvFZ7t3ZrZr1FyFyUt3WjqrW3try7Aw43 KrZxJ3s7AFWaqF4kn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUYE7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s0DM28Irc Ia0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l 84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26F4j6r 4UJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26F4U JVW0owAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7V C0I7IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j 6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwCY02Avz4vE14v_GF yl42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWU JVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7V AKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Gr0_Xr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26F4j 6r4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIx AIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7VUjGNt3UUUUU= = X-Originating-IP: [117.136.88.47] X-CM-SenderInfo: xmldzxdqj61x51wl3zoofrzhdfq/ Content-Transfer-Encoding: quoted-printable From: Ling The PhytiumRealTimeClockLib implemented EFI RealTimeClock runtime services via RTC Lib. Cc: Leif Lindholm Signed-off-by: Ling Jia Signed-off-by: Peng Xie Reviewed-by: Yiqi Shu --- Platform/Phytium/Durian/DurianPkg.dsc = | 3 + Platform/Phytium/Durian/DurianPkg.fdf = | 1 + Silicon/Phytium/Phytium2000-4/Library/PhytiumRealTimeClockLib/PhytiumRealT= imeClockLib.inf | 44 ++ Silicon/Phytium/Phytium2000-4/Library/PhytiumRealTimeClockLib/PhytiumRealT= imeClockLib.h | 24 + Silicon/Phytium/Phytium2000-4/Library/PhytiumRealTimeClockLib/PhytiumRealT= imeClockLib.c | 468 ++++++++++++++++++++ 5 files changed, 540 insertions(+) diff --git a/Platform/Phytium/Durian/DurianPkg.dsc b/Platform/Phytium/Duria= n/DurianPkg.dsc index df43c3d5d23a..dae2ca512a26 100644 --- a/Platform/Phytium/Durian/DurianPkg.dsc +++ b/Platform/Phytium/Durian/DurianPkg.dsc @@ -30,6 +30,8 @@ [LibraryClasses.common] ArmPlatformLib|Silicon/Phytium/Phytium2000-4/Library/PhytiumPlatformLib/= PhytiumPlatformLib.inf=0D LogoLib|Silicon/Phytium/Library/LogoLib/LogoLib.inf=0D =0D + #Phytium2000-4 RTC Driver=0D + RealTimeClockLib|Silicon/Phytium/Phytium2000-4/Library/PhytiumRealTimeCl= ockLib/PhytiumRealTimeClockLib.inf=0D TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf=0D =0D # PL011 UART Driver and Dependency Libraries=0D @@ -180,6 +182,7 @@ [Components.common] }=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/Durian/DurianPkg.fdf b/Platform/Phytium/Duria= n/DurianPkg.fdf index 1a1dde1c64f6..82b2723a8490 100644 --- a/Platform/Phytium/Durian/DurianPkg.fdf +++ b/Platform/Phytium/Durian/DurianPkg.fdf @@ -94,6 +94,7 @@ [FV.FvMain] #INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf=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 diff --git a/Silicon/Phytium/Phytium2000-4/Library/PhytiumRealTimeClockLib/= PhytiumRealTimeClockLib.inf b/Silicon/Phytium/Phytium2000-4/Library/Phytium= RealTimeClockLib/PhytiumRealTimeClockLib.inf new file mode 100644 index 000000000000..8919cbf55a06 --- /dev/null +++ b/Silicon/Phytium/Phytium2000-4/Library/PhytiumRealTimeClockLib/Phytium= RealTimeClockLib.inf @@ -0,0 +1,44 @@ +#/** @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 0x00010019=0D + BASE_NAME =3D PhytiumRealTimeClockLib=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 + PhytiumRealTimeClockLib.c=0D + PhytiumRealTimeClockLib.h=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + EmbeddedPkg/EmbeddedPkg.dec=0D + ArmPlatformPkg/ArmPlatformPkg.dec=0D + Silicon/Phytium/Phytium.dec=0D +=0D +[LibraryClasses]=0D + IoLib=0D + UefiLib=0D + DebugLib=0D + PcdLib=0D + DxeServicesTableLib=0D + TimeBaseLib=0D + UefiRuntimeLib=0D +=0D +[Guids]=0D + gEfiEventVirtualAddressChangeGuid=0D +=0D +[Pcd]=0D + gPhytiumPlatformTokenSpaceGuid.PcdRtcBaseAddress=0D +=0D +[Depex.common.DXE_RUNTIME_DRIVER]=0D + gEfiCpuArchProtocolGuid=0D diff --git a/Silicon/Phytium/Phytium2000-4/Library/PhytiumRealTimeClockLib/= PhytiumRealTimeClockLib.h b/Silicon/Phytium/Phytium2000-4/Library/PhytiumRe= alTimeClockLib/PhytiumRealTimeClockLib.h new file mode 100644 index 000000000000..1015d7bb08bf --- /dev/null +++ b/Silicon/Phytium/Phytium2000-4/Library/PhytiumRealTimeClockLib/Phytium= 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 __XGENE_REAL_TIME_CLOCK_H__=0D +#define __XGENE_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=0D diff --git a/Silicon/Phytium/Phytium2000-4/Library/PhytiumRealTimeClockLib/= PhytiumRealTimeClockLib.c b/Silicon/Phytium/Phytium2000-4/Library/PhytiumRe= alTimeClockLib/PhytiumRealTimeClockLib.c new file mode 100644 index 000000000000..606dd565a64a --- /dev/null +++ b/Silicon/Phytium/Phytium2000-4/Library/PhytiumRealTimeClockLib/Phytium= RealTimeClockLib.c @@ -0,0 +1,468 @@ +/** @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 +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include "PhytiumRealTimeClockLib.h"=0D +=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_= VARIABLE_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 (((Time->TimeZone < -1440) || (Time->TimeZone > 1440))=0D + && (Time->TimeZone !=3D EFI_UNSPECIFIED_TIMEZONE)) {=0D + Time->TimeZone =3D EFI_UNSPECIFIED_TIMEZONE;=0D + }=0D + //=0D + // Adjust for the correct time zone=0D + //=0D + if (Time->TimeZone !=3D EFI_UNSPECIFIED_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 + 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_= VARIABLE_RUNTIME_ACCESS,=0D + Size,=0D + (VOID *)&(Time->Daylight)=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 (Time->TimeZone !=3D EFI_UNSPECIFIED_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_VA= RIABLE_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_VA= RIABLE_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, SIZE_4KB,=0D + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME=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, 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