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 F3995AC0ABD for ; Mon, 6 Nov 2023 03:28:14 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=aBuiOLzFOF2Xwy7kqbezg/HKGc+YgAznjxOCsqAhlGo=; 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=1699241293; v=1; b=KZ/xV64rtMpdVXvGb5RpbrkjhJ3Db0oSVBI9LXjkS8cFCRgRIr0FNTcycAFOXQ51xfTAW4L2 vGD09A8Ab1co2uGeAkc0EAIKUwg6GJQKqMXxRtt2Y6gypVi5LCNnymPi+OOiFcSLjK2WMr0BLHM UbUKeRU1h6sk5Kf60gOLVEEU= X-Received: by 127.0.0.2 with SMTP id mTMtYY7687511xsyw0T9LtXI; Sun, 05 Nov 2023 19:28:13 -0800 X-Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.47059.1699241292448229726 for ; Sun, 05 Nov 2023 19:28:13 -0800 X-Received: from loongson.cn (unknown [10.2.9.245]) by gateway (Coremail) with SMTP id _____8BxY_BHXUhlGjc3AA--.42770S3; Mon, 06 Nov 2023 11:28:07 +0800 (CST) X-Received: from code-server.gen (unknown [10.2.9.245]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxvdxFXUhlIhI6AA--.60938S2; Mon, 06 Nov 2023 11:28:05 +0800 (CST) From: "Chao Li" To: devel@edk2.groups.io Cc: Eric Dong , Ray Ni , Rahul Kumar , Gerd Hoffmann Subject: [edk2-devel] [PATCH v2 09/30] UefiCpuPkg: Add LoongArch64 CPU Timer library Date: Mon, 6 Nov 2023 11:28:03 +0800 Message-Id: <20231106032803.2283705-1-lichao@loongson.cn> In-Reply-To: <20231106032521.2251143-1-lichao@loongson.cn> References: <20231106032521.2251143-1-lichao@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf8CxvdxFXUhlIhI6AA--.60938S2 X-CM-SenderInfo: xolfxt3r6o00pqjv00gofq/1tbiAQAGCGVFqihSvgA2s3 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: zrLrO21fuhRGzUmDlhbTROamx7686176AA= 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="KZ/xV64r"; 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 Add the LoongArch64 CPU Timer library, using CPUCFG 0x4 and 0x5 for Stable Counter frequency. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 Cc: Eric Dong Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Signed-off-by: Chao Li --- .../BaseLoongArch64CpuTimerLib.inf | 30 +++ .../BaseLoongArch64CpuTimerLib.uni | 15 ++ .../BaseLoongArch64CpuTimerLib/CpuTimerLib.c | 226 ++++++++++++++++++ UefiCpuPkg/UefiCpuPkg.dsc | 3 + 4 files changed, 274 insertions(+) create mode 100644 UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTimerLib.inf create mode 100644 UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTimerLib.uni create mode 100644 UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/CpuTimerLib.c diff --git a/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTimerLib.inf b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTimerLib.inf new file mode 100644 index 0000000000..c00c215aec --- /dev/null +++ b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTimerLib.inf @@ -0,0 +1,30 @@ +## @file +# Base CPU Timer Library +# +# Provides base timer support using CPUCFG 0x4 and 0x5 stable counter frequency. +# +# Copyright (c) 2023, Loongson Technology Corporation Limited. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseLoongArch64CpuTimerLib + FILE_GUID = 740389C7-CC44-4A2F-88DC-89D97D312E7C + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = TimerLib + MODULE_UNI_FILE = BaseLoongArch64CpuTimerLib.uni + +[Sources.common] + CpuTimerLib.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + PcdLib + DebugLib diff --git a/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTimerLib.uni b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTimerLib.uni new file mode 100644 index 0000000000..72d38ec679 --- /dev/null +++ b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTimerLib.uni @@ -0,0 +1,15 @@ +// /** @file +// Base CPU Timer Library +// +// Provides base timer support using CPUCFG 0x4 and 0x5 stable counter frequency. +// +// Copyright (c) 2023, Loongson Technology Corporation Limited. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "LOONGARCH CPU Timer Library" + +#string STR_MODULE_DESCRIPTION #language en-US "Provides basic timer support using CPUCFG 0x4 and 0x5 stable counter frequency." diff --git a/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/CpuTimerLib.c b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/CpuTimerLib.c new file mode 100644 index 0000000000..349b881cbc --- /dev/null +++ b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/CpuTimerLib.c @@ -0,0 +1,226 @@ +/** @file + CPUCFG 0x4 and 0x5 for Stable Counter frequency instance of Timer Library. + + Copyright (c) 2023, Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include + +/** + Calculate clock frequency using CPUCFG 0x4 and 0x5 registers. + + @param VOID. + + @return The frequency in Hz. + +**/ +UINT32 +EFIAPI +CalcConstFreq ( + VOID + ) +{ + UINT32 BaseFreq; + UINT32 ClockMultiplier; + UINT32 ClockDivide; + CPUCFG_REG4_INFO_DATA CCFreq; + CPUCFG_REG5_INFO_DATA CpucfgReg5Data; + UINT32 StableTimerFreq; + + // + // Get the the crystal frequency corresponding to the constant + // frequency timer and the clock used by the timer. + // + AsmCpucfg (CPUCFG_REG4_INFO, &CCFreq.Uint32); + + // + // Get the multiplication factor and frequency division factor + // corresponding to the constant frequency timer and the clock + // used by the timer. + // + AsmCpucfg (CPUCFG_REG5_INFO, &CpucfgReg5Data.Uint32); + + BaseFreq = CCFreq.Bits.CC_FREQ; + ClockMultiplier = CpucfgReg5Data.Bits.CC_MUL & 0xFFFFULL; + ClockDivide = CpucfgReg5Data.Bits.CC_DIV & 0xFFFFULL; + + if (!BaseFreq || !ClockMultiplier || !ClockDivide) { + DEBUG ((DEBUG_ERROR, "LoongArch Stable Timer is not available in the CPU, hence this library cannot be used.\n")); + StableTimerFreq = 0; + ASSERT (0); + } else { + StableTimerFreq = (BaseFreq * ClockMultiplier / ClockDivide); + } + + return StableTimerFreq; +} + +/** + Stalls the CPU for at least the given number of microseconds. + + Stalls the CPU for the number of microseconds specified by MicroSeconds. + + @param MicroSeconds The minimum number of microseconds to delay. + + @return MicroSeconds + +**/ +UINTN +EFIAPI +MicroSecondDelay ( + IN UINTN MicroSeconds + ) +{ + UINTN Count, Ticks, Start, End; + + Count = (CalcConstFreq () * MicroSeconds) / 1000000; + Start = AsmReadStableCounter (); + End = Start + Count; + + do { + Ticks = AsmReadStableCounter (); + } while (Ticks < End); + + return MicroSeconds; +} + +/** + Stalls the CPU for at least the given number of nanoseconds. + + Stalls the CPU for the number of nanoseconds specified by NanoSeconds. + + @param NanoSeconds The minimum number of nanoseconds to delay. + + @return NanoSeconds + +**/ +UINTN +EFIAPI +NanoSecondDelay ( + IN UINTN NanoSeconds + ) +{ + UINT32 MicroSeconds; + + if (NanoSeconds % 1000 == 0) { + MicroSeconds = NanoSeconds/1000; + } else { + MicroSeconds = NanoSeconds/1000 + 1; + } + + MicroSecondDelay (MicroSeconds); + + return NanoSeconds; +} + +/** + Retrieves the current value of a 64-bit free running performance counter. + + Retrieves the current value of a 64-bit free running performance counter. The + counter can either count up by 1 or count down by 1. If the physical + performance counter counts by a larger increment, then the counter values + must be translated. The properties of the counter can be retrieved from + GetPerformanceCounterProperties(). + + @return The current value of the free running performance counter. + +**/ +UINT64 +EFIAPI +GetPerformanceCounter ( + VOID + ) +{ + return AsmReadStableCounter (); +} + +/** + Retrieves the 64-bit frequency in Hz and the range of performance counter + values. + + If StartValue is not NULL, then the value that the performance counter starts + with immediately after is it rolls over is returned in StartValue. If + EndValue is not NULL, then the value that the performance counter end with + immediately before it rolls over is returned in EndValue. The 64-bit + frequency of the performance counter in Hz is always returned. If StartValue + is less than EndValue, then the performance counter counts up. If StartValue + is greater than EndValue, then the performance counter counts down. For + example, a 64-bit free running counter that counts up would have a StartValue + of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter + that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0. + + @param StartValue The value the performance counter starts with when it + rolls over. + @param EndValue The value that the performance counter ends with before + it rolls over. + + @return The frequency in Hz. + +**/ +UINT64 +EFIAPI +GetPerformanceCounterProperties ( + OUT UINT64 *StartValue OPTIONAL, + OUT UINT64 *EndValue OPTIONAL + ) +{ + if (StartValue != NULL) { + *StartValue = BIT2; + } + + if (EndValue != NULL) { + *EndValue = BIT48 - 1; + } + + return CalcConstFreq (); +} + +/** + Converts elapsed ticks of performance counter to time in nanoseconds. + + This function converts the elapsed ticks of running performance counter to + time value in unit of nanoseconds. + + @param Ticks The number of elapsed ticks of running performance counter. + + @return The elapsed time in nanoseconds. + +**/ +UINT64 +EFIAPI +GetTimeInNanoSecond ( + IN UINT64 Ticks + ) +{ + UINT64 Frequency; + UINT64 NanoSeconds; + UINT64 Remainder; + INTN Shift; + + Frequency = GetPerformanceCounterProperties (NULL, NULL); + + // + // Ticks + // Time = --------- x 1,000,000,000 + // Frequency + // + NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u); + + // + // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit. + // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34, + // i.e. highest bit set in Remainder should <= 33. + // + Shift = MAX (0, HighBitSet64 (Remainder) - 33); + Remainder = RShiftU64 (Remainder, (UINTN)Shift); + Frequency = RShiftU64 (Frequency, (UINTN)Shift); + NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL); + + return NanoSeconds; +} diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 074fd77461..8e34a9cd6b 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -205,5 +205,8 @@ UefiCpuPkg/CpuTimerDxeRiscV64/CpuTimerDxeRiscV64.inf UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf +[Components.LOONGARCH64] + UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTimerLib.inf + [BuildOptions] *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -- 2.27.0 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#110713): https://edk2.groups.io/g/devel/message/110713 Mute This Topic: https://groups.io/mt/102413862/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-