From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id DF19F74003A for ; Fri, 17 Nov 2023 10:03:18 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=jRmMb4Fe73PWVnPTsQPvSHAcbuWYdx/HZOttlZUY9jI=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1700215397; v=1; b=hyVV0BiIl2Hs0M89k/aIhOfGUovZBxmnpBix3zvNYnHTPBRW3KVh3yA0zzthZlAYBu+pairz /oiVclamSTZoDZKpgosKgk0s623Iw79Xw0FH4I+WgJCtYVQbn8XbRjDF6XEJu2/HJR1J+U6vnWv YPeBUAIV6mOGnAF5fqs6DKog= X-Received: by 127.0.0.2 with SMTP id h2NWYY7687511xRsjdD5JuXE; Fri, 17 Nov 2023 02:03:17 -0800 X-Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.8714.1700215396610066875 for ; Fri, 17 Nov 2023 02:03:17 -0800 X-Received: from loongson.cn (unknown [10.2.9.245]) by gateway (Coremail) with SMTP id _____8Cx5_FhOldl0cc6AA--.50127S3; Fri, 17 Nov 2023 18:03:13 +0800 (CST) X-Received: from code-server.gen (unknown [10.2.9.245]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Cxjd5fOldlqTpFAA--.23284S2; Fri, 17 Nov 2023 18:03:11 +0800 (CST) From: "Chao Li" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Jiewen Yao , Jordan Justen , Gerd Hoffmann , Baoqi Zhang , Xianglai Li Subject: [edk2-devel] [PATCH v3 32/39] OvmfPkg/LoongArchVirt: Add real time clock library Date: Fri, 17 Nov 2023 18:03:11 +0800 Message-Id: <20231117100311.3610708-1-lichao@loongson.cn> In-Reply-To: <20231117095742.3605778-1-lichao@loongs> References: <20231117095742.3605778-1-lichao@loongs> MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Cxjd5fOldlqTpFAA--.23284S2 X-CM-SenderInfo: xolfxt3r6o00pqjv00gofq/1tbiAQASCGVWzaoGGABVsE X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lichao@loongson.cn List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: y8fx1bVqK4hwWmhmcr0BXLOLx7686176AA= Content-Transfer-Encoding: 8bit X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=hyVV0BiI; dmarc=none; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io This library is provides real time clock for LoongArch virtual machine. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Signed-off-by: Chao Li Co-authored-by: Baoqi Zhang Co-authored-by: Xianglai Li --- .../DxeLsRealTimeClockLib.c | 333 ++++++++++++++++++ .../DxeLsRealTimeClockLib.inf | 42 +++ .../LsRealTimeClockLib/LsRealTimeClock.h | 47 +++ .../PeiLsRealTimeClockLib.c | 31 ++ .../PeiLsRealTimeClockLib.inf | 29 ++ 5 files changed, 482 insertions(+) create mode 100644 OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/DxeLsRealTimeClockLib.c create mode 100644 OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/DxeLsRealTimeClockLib.inf create mode 100644 OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClock.h create mode 100644 OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/PeiLsRealTimeClockLib.c create mode 100644 OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/PeiLsRealTimeClockLib.inf diff --git a/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/DxeLsRealTimeClockLib.c b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/DxeLsRealTimeClockLib.c new file mode 100644 index 0000000000..d634d30fd1 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/DxeLsRealTimeClockLib.c @@ -0,0 +1,333 @@ +/** @file + Implement EFI RealTimeClock runtime services via RTC Lib. + + Copyright (c) 2023 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "LsRealTimeClock.h" + +STATIC BOOLEAN mInitialized = FALSE; +STATIC EFI_EVENT mRtcVirtualAddrChangeEvent; +STATIC UINTN mRtcBase; + +/* + Enable Real-time clock. + + @param VOID + + @retval VOID + */ +VOID +InitRtc ( + VOID + ) +{ + UINTN Val; + EFI_HOB_GUID_TYPE *GuidHob = NULL; + VOID *DataInHob = NULL; + + if (!mInitialized) { + /* Enable rtc */ + GuidHob = GetFirstGuidHob (&mRtcRegisterBaseAddressGuid); + if (GuidHob) { + DataInHob = GET_GUID_HOB_DATA (GuidHob); + mRtcBase = (UINT64)(*(UINTN *)DataInHob); + Val = MmioRead32 (mRtcBase + RTC_CTRL_REG); + Val |= TOY_ENABLE_BIT | OSC_ENABLE_BIT; + MmioWrite32 (mRtcBase + RTC_CTRL_REG, Val); + mInitialized = TRUE; + } else { + DebugPrint (EFI_D_INFO, "RTC register address not found!\n"); + ASSERT (FALSE); + } + } +} + +/** + 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 + ) +{ + UINT32 Val; + + // Ensure Time is a valid pointer + if (Time == NULL) { + return EFI_INVALID_PARAMETER; + } + + Val = MmioRead32 (mRtcBase + TOY_READ1_REG); + Time->Year = Val + 1900; + + Val = MmioRead32 (mRtcBase + TOY_READ0_REG); + Time->Month = (Val >> TOY_MON_SHIFT) & TOY_MON_MASK; + Time->Day = (Val >> TOY_DAY_SHIFT) & TOY_DAY_MASK; + Time->Hour = (Val >> TOY_HOUR_SHIFT) & TOY_HOUR_MASK; + Time->Minute = (Val >> TOY_MIN_SHIFT) & TOY_MIN_MASK; + Time->Second = (Val >> TOY_SEC_SHIFT) & TOY_SEC_MASK; + Time->Nanosecond = 0; + 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 due to hardware error. +**/ +EFI_STATUS +EFIAPI +LibSetTime ( + IN EFI_TIME *Time + ) +{ + UINT32 Val; + + // Initialize the hardware if not already done + + Val = 0; + Val |= (Time->Second << TOY_SEC_SHIFT); + Val |= (Time->Minute << TOY_MIN_SHIFT); + Val |= (Time->Hour << TOY_HOUR_SHIFT); + Val |= (Time->Day << TOY_DAY_SHIFT); + Val |= (Time->Month << TOY_MON_SHIFT); + MmioWrite32 (mRtcBase + TOY_WRITE0_REG, Val); + + Val = Time->Year - 1900; + MmioWrite32 (mRtcBase + TOY_WRITE1_REG, Val); + 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 + ) +{ + // Not a required feature + return EFI_UNSUPPORTED; +} + +/** + 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 + ) +{ + // Not a required feature + return EFI_UNSUPPORTED; +} + +/** + 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 +**/ +VOID +EFIAPI +VirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Only needed if you are going to support the OS calling RTC functions in virtual mode. + // You will need to call EfiConvertPointer (). To convert any stored physical addresses + // to virtual address. After the OS transitions to calling in virtual mode, all future + // runtime calls will be made in virtual mode. + // + EfiConvertPointer (0x0, (VOID **)&mRtcBase); + return; +} + +/** Add the RTC controller address range to the memory map. + + @param [in] ImageHandle The handle to the image. + @param [in] RtcPageBase Base address of the RTC controller. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Flash device not found. +**/ +EFI_STATUS +KvmtoolRtcMapMemory ( + IN EFI_HANDLE ImageHandle, + IN EFI_PHYSICAL_ADDRESS RtcPageBase + ) +{ + EFI_STATUS Status; + + Status = gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + RtcPageBase, + EFI_PAGE_SIZE, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "Failed to add memory space. Status = %r\n", + Status + )); + return Status; + } + + Status = gDS->AllocateMemorySpace ( + EfiGcdAllocateAddress, + EfiGcdMemoryTypeMemoryMappedIo, + 0, + EFI_PAGE_SIZE, + &RtcPageBase, + ImageHandle, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "Failed to allocate memory space. Status = %r\n", + Status + )); + gDS->RemoveMemorySpace ( + RtcPageBase, + EFI_PAGE_SIZE + ); + return Status; + } + + Status = gDS->SetMemorySpaceAttributes ( + RtcPageBase, + EFI_PAGE_SIZE, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "Failed to set memory attributes. Status = %r\n", + Status + )); + + gDS->FreeMemorySpace ( + RtcPageBase, + EFI_PAGE_SIZE + ); + + gDS->RemoveMemorySpace ( + RtcPageBase, + EFI_PAGE_SIZE + ); + } + + return Status; +} + +/** + 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; + + InitRtc (); + Status = KvmtoolRtcMapMemory (ImageHandle, (mRtcBase & ~EFI_PAGE_MASK)); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "Failed to map memory for loongson 7A RTC. Status = %r\n", + Status + )); + return Status; + } + + // + // Register for the virtual address change event + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + VirtualNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mRtcVirtualAddrChangeEvent + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/DxeLsRealTimeClockLib.inf b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/DxeLsRealTimeClockLib.inf new file mode 100644 index 0000000000..3b8a21b25c --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/DxeLsRealTimeClockLib.inf @@ -0,0 +1,42 @@ +## @file +# LoongArch64 CPU Real Time Clock DXE Phase Library. +# +# Copyright (c) 2023 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = LsRealTimeClockLib + FILE_GUID = 9793a3da-1869-4fdf-88b1-c6484341f50b + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = RealTimeClockLib + +# +# VALID_ARCHITECTURES = LOONGARCH64 +# + +[Sources.common] + DxeLsRealTimeClockLib.c + +[Packages] + MdePkg/MdePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + +[LibraryClasses] + IoLib + UefiLib + DebugLib + PcdLib + HobLib + DxeServicesTableLib + UefiRuntimeLib + +[Guids] + gEfiEventVirtualAddressChangeGuid + +[Depex] + TRUE diff --git a/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClock.h b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClock.h new file mode 100644 index 0000000000..fc8663da56 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClock.h @@ -0,0 +1,47 @@ +/** @file + Implement EFI RealTimeClock runtime services via RTC Lib. + + Copyright (c) 2023 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef LS_REAL_TIME_CLOCK_H_ +#define LS_REAL_TIME_CLOCK_H_ + +#define TOY_WRITE0_REG 0x24 +#define TOY_WRITE1_REG 0x28 +#define TOY_READ0_REG 0x2c +#define TOY_READ1_REG 0x30 +#define RTC_CTRL_REG 0x40 + +/* TOY Enable bits */ +#define RTC_ENABLE_BIT (1UL << 13) +#define TOY_ENABLE_BIT (1UL << 11) +#define OSC_ENABLE_BIT (1UL << 8) + +/* + * shift bits and filed mask + */ +#define TOY_MON_MASK 0x3f +#define TOY_DAY_MASK 0x1f +#define TOY_HOUR_MASK 0x1f +#define TOY_MIN_MASK 0x3f +#define TOY_SEC_MASK 0x3f +#define TOY_MSEC_MASK 0xf + +#define TOY_MON_SHIFT 26 +#define TOY_DAY_SHIFT 21 +#define TOY_HOUR_SHIFT 16 +#define TOY_MIN_SHIFT 10 +#define TOY_SEC_SHIFT 4 + +#define RTC_REGISTER_ADDRESS_HOB_GUID \ + { \ + 0x0d7c012b, 0x79c1, 0xfa58, { 0x6f, 0x91, 0xbe, 0x3e, 0xee, 0x46, 0x5f, 0x71 } \ + } + +EFI_GUID mRtcRegisterBaseAddressGuid = RTC_REGISTER_ADDRESS_HOB_GUID; + +#endif // LS_REAL_TIME_CLOCK_H_ diff --git a/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/PeiLsRealTimeClockLib.c b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/PeiLsRealTimeClockLib.c new file mode 100644 index 0000000000..d6f71f66ad --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/PeiLsRealTimeClockLib.c @@ -0,0 +1,31 @@ +/** @file + Implement EFI RealTimeClock PEI phase RTC Lib. + + Copyright (c) 2023 Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include "LsRealTimeClock.h" + +VOID +SaveRtcRegisterAddressHob ( + UINT64 RtcRegisterBase + ) +{ + UINT64 Data64; + + // + // Build location of RTC register base address buffer in HOB + // + Data64 = (UINT64)(UINTN)RtcRegisterBase; + + BuildGuidDataHob ( + &mRtcRegisterBaseAddressGuid, + (VOID *)&Data64, + sizeof (UINT64) + ); +} diff --git a/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/PeiLsRealTimeClockLib.inf b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/PeiLsRealTimeClockLib.inf new file mode 100644 index 0000000000..8b78040331 --- /dev/null +++ b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/PeiLsRealTimeClockLib.inf @@ -0,0 +1,29 @@ +## @file +# LoongArch64 CPU Real Time Clock PEI Phase Library. +# +# Copyright (c) 2023 Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiLsRealTimeClockLib + FILE_GUID = d4358430-15ec-9358-1b12-26dab955e9c6 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = RealTimeClockLib|PEIM + +# +# VALID_ARCHITECTURES = LOONGARCH64 +# + +[Sources.common] + PeiLsRealTimeClockLib.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + HobLib -- 2.27.0 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#111384): https://edk2.groups.io/g/devel/message/111384 Mute This Topic: https://groups.io/mt/102644806/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-