From nobody Tue Feb 10 23:14:14 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+87199+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87199+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1646210710; cv=none; d=zohomail.com; s=zohoarc; b=XhStLSQxf2kneWLoR3KPFe3cNxMMk1yVxxvW162BtBovxT4rNMnuL5MxdMc9BrI2ASi4qiyrtWN44lPWAvLrUQhz2A1ATV2SwYrSFxreIAwgTIH9JIov3uwnYDIfD5hXTm/uTp3jWwwY2cQ085WTnyLs3ISDQaMum0QBPTzXXIo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1646210710; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=xj5T/ckygeBnT8MEebvCfnq2NpKigf6K9heaAVeVpR4=; b=PdTsQmg6hDVFjIIQY1tlAjRgavP20pFBPUAZ/xpj9mEItxCWPncMoOGJBstvlUE2nEBqjPR0evyLRf2OOgdVwAZEDNxFgF9GwCpJdyQ51+CVGZs1f96v6YLk0wjNaEN0wWnzB87EkRlWryj/K6risPCDHErOi5nbYcRNTylMDtA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+87199+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1646210710607660.4987810515017; Wed, 2 Mar 2022 00:45:10 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id Mt5NYY1788612xVJIDqev9yY; Wed, 02 Mar 2022 00:45:10 -0800 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.5363.1646210705274587895 for ; Wed, 02 Mar 2022 00:45:08 -0800 X-Received: from localhost.localdomain (unknown [10.2.5.185]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxn89_Lh9i7TkBAA--.6283S9; Wed, 02 Mar 2022 16:44:51 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Subject: [edk2-devel] [edk2-platforms][PATCH V1 07/15] Platform/Loongson: Add StableTimerLib. Date: Wed, 2 Mar 2022 03:44:39 -0500 Message-Id: <20220302084447.2991355-8-lixianglai@loongson.cn> In-Reply-To: <20220302084447.2991355-1-lixianglai@loongson.cn> References: <20220302084447.2991355-1-lixianglai@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Dxn89_Lh9i7TkBAA--.6283S9 X-Coremail-Antispam: 1UD129KBjvJXoW3WrWUXw1DuF43KF15JrW3Awb_yoWDGr4kpF sxZa47Gr48Gr15A345Ja15KFy5AwsxArZ8WF45Crn7A3yDA3s3Ww1ktF40qFyfZrW3Wr92 q3y2ga1UuF4rX3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ Precedence: Bulk List-Unsubscribe: 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,lixianglai@loongson.cn X-Gm-Message-State: jWDu5M2rzXpqDyTHev0BP6N0x1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1646210710; bh=TQ2AbyWcSv+j9qdwsGrhUOyThO4QpkUoIRMnGpvG16U=; h=Date:From:Reply-To:Subject:To; b=I6rKcoZKIvOSlcgr+iyro/w+4hZkuanGy/5UBAhOeJP34Zham8bE5hZfU6ObUZs3gMg QDuE6R9UeKtBVmXk24/T1Pck61ELNl2Ozh/7Zv5cJg0a+3emx8IdFgTGOjdCaBgZo6ZLu ubSdNiKuUJA663RCwaxz7zHp5H0hDSN11pw= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1646210712536100010 Content-Type: text/plain; charset="utf-8" This library provides a delay interface and a timing interface. Signed-off-by: xianglai li --- .../Include/Library/StableTimer.h | 42 +++ .../Library/StableTimerLib/Count.S | 26 ++ .../Library/StableTimerLib/TimerLib.c | 262 ++++++++++++++++++ .../Library/StableTimerLib/TimerLib.inf | 28 ++ 4 files changed, 358 insertions(+) create mode 100644 Platform/Loongson/LoongArchQemuPkg/Include/Library/Stab= leTimer.h create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/StableTimerL= ib/Count.S create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/StableTimerL= ib/TimerLib.c create mode 100644 Platform/Loongson/LoongArchQemuPkg/Library/StableTimerL= ib/TimerLib.inf diff --git a/Platform/Loongson/LoongArchQemuPkg/Include/Library/StableTimer= .h b/Platform/Loongson/LoongArchQemuPkg/Include/Library/StableTimer.h new file mode 100644 index 0000000000..bd6a1eb90f --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Include/Library/StableTimer.h @@ -0,0 +1,42 @@ +/** @file + + Copyright (c) 2021 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Csr - Cpu Status Register + - Calc - Calculation + - Freq - frequency +**/ + +#ifndef STABLE_TIMER_H_ +#define STABLE_TIMER_H_ +#include "Library/Cpu.h" + +/** + Gets the timer count value. + + @param[] VOID + + @retval timer count value. +**/ +UINTN +EFIAPI +CsrReadTime ( + VOID + ); + +/** + Calculate the timer frequency. + + @param[] VOID + + @retval Timer frequency. +**/ +UINT32 +EFIAPI +CalcConstFreq ( + VOID + ); +#endif diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/Coun= t.S b/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/Count.S new file mode 100644 index 0000000000..42f878caf8 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/Count.S @@ -0,0 +1,26 @@ +#-------------------------------------------------------------------------= ----- +# +# Count for LoongArch +# +# Copyright (c) 2021 Loongson Technology Corporation Limited. All rights r= eserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#-------------------------------------------------------------------------= ----- + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "Library/Cpu.h" +#include "LoongArchAsmMacro.h" +# +# Set cpu interrupts +# @param A0 The interrupt number +# +ASM_FUNC(CpuSetIP) + csrrd T0, LOONGARCH_CSR_ECFG + or T0, T0, A0 + csrwr T0, LOONGARCH_CSR_ECFG + jirl ZERO, RA,0 + diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/Time= rLib.c b/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/TimerLib= .c new file mode 100644 index 0000000000..21e3749ee6 --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/TimerLib.c @@ -0,0 +1,262 @@ +/** @file + Generic LoongArch implementation of TimerLib.h + + Copyright (c) 2021 Loongson Technology Corporation Limited. All rights r= eserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Freq - Frequency + - Csr - Cpu Status Register + - calc - calculate +**/ + +#include +#include +#include +#include +#include "Library/StableTimer.h" +#include "Library/Cpu.h" + +UINT32 StableTimerFreq =3D 0; + +/** + Gets the timer count value. + + @param[] VOID + + @retval timer count value. +**/ +UINTN +EFIAPI +CsrReadTime ( + VOID + ) +{ + UINTN Value =3D 0; + __asm__ __volatile__( + " rdtime.d %0, $r0\n" + : "=3Dr" (Value)); + return Value; +} + +/** + Calculate the timer frequency. + + @param[] VOID + + @retval Timer frequency. +**/ +UINT32 +EFIAPI +CalcConstFreq ( + VOID + ) +{ + UINT32 Result; + UINT32 BaseFreq; + UINT32 ClockMultiplier; + UINT32 ClockDivide; + + LOONGARCH_GET_CPUCFG (BaseFreq, LOONGARCH_CPUCFG4); + LOONGARCH_GET_CPUCFG (Result, LOONGARCH_CPUCFG5); + ClockMultiplier =3D Result & 0xffff; + ClockDivide =3D (Result >> 16) & 0xffff; + + if ((!BaseFreq) + || (!ClockMultiplier) + || (!ClockDivide)) + { + return 0; + } + else { + return (BaseFreq * ClockMultiplier / ClockDivide); + } +} +/** + Get the timer frequency. + + @param[] VOID + + @retval Timer frequency. +**/ +UINT32 +EFIAPI +GetFreq ( + VOID + ) +{ + if (StableTimerFreq) { + } else { + StableTimerFreq =3D CalcConstFreq (); + } + + 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; + UINTN Ticks; + UINTN Start; + UINTN End; + + Count =3D GetFreq (); + Count =3D (Count * MicroSeconds) / 1000000; + Start =3D CsrReadTime (); + End =3D Start + Count; + + do { + Ticks =3D CsrReadTime (); + } 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 =3D=3D 0) { + MicroSeconds =3D NanoSeconds/1000; + }else { + MicroSeconds =3D 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 CsrReadTime (); +} +/** + 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 s= tarts + with immediately after is it rolls over is returned in StartValue. If + EndValue is not NULL, then the value that the performance counter end wi= th + immediately before it rolls over is returned in EndValue. The 64-bit + frequency of the performance counter in Hz is always returned. If StartV= alue + is less than EndValue, then the performance counter counts up. If StartV= alue + is greater than EndValue, then the performance counter counts down. For + example, a 64-bit free running counter that counts up would have a Start= Value + 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 bef= ore + it rolls over. + + @return The frequency in Hz. + +**/ +UINT64 +EFIAPI +GetPerformanceCounterProperties ( + OUT UINT64 *StartValue, OPTIONAL + OUT UINT64 *EndValue OPTIONAL + ) +{ + if (StartValue !=3D NULL) { + *StartValue =3D BIT2; + } + + if (EndValue !=3D NULL) { + *EndValue =3D BIT48 - 1; + } + + return GetFreq (); +} + +/** + 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 cou= nter. + + @return The elapsed time in nanoseconds. + +**/ +UINT64 +EFIAPI +GetTimeInNanoSecond ( + IN UINT64 Ticks + ) +{ + UINT64 Frequency; + UINT64 NanoSeconds; + UINT64 Remainder; + INTN Shift; + + Frequency =3D GetPerformanceCounterProperties (NULL, NULL); + + // + // Ticks + // Time =3D --------- x 1,000,000,000 + // Frequency + // + NanoSeconds =3D MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remai= nder), 1000000000u); + + // + // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit. + // Since 2^29 < 1,000,000,000 =3D 0x3B9ACA00 < 2^30, Remainder should < = 2^(64-30) =3D 2^34, + // i.e. highest bit set in Remainder should <=3D 33. + // + Shift =3D MAX (0, HighBitSet64 (Remainder) - 33); + Remainder =3D RShiftU64 (Remainder, (UINTN) Shift); + Frequency =3D RShiftU64 (Frequency, (UINTN) Shift); + NanoSeconds +=3D DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u)= , Frequency, NULL); + + return NanoSeconds; +} diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/Time= rLib.inf b/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/TimerL= ib.inf new file mode 100644 index 0000000000..fef0fac08c --- /dev/null +++ b/Platform/Loongson/LoongArchQemuPkg/Library/StableTimerLib/TimerLib.inf @@ -0,0 +1,28 @@ +## @file +# Generic LoongArch implementation of TimerLib.h +# +# Copyright (c) 2021 Loongson Technology Corporation Limited. All rights = reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D TimerLib + FILE_GUID =3D 740389C7-CC44-4A2F-88DC-89D97D312E= 7C + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D TimerLib + +[Sources.common] + TimerLib.c + Count.S + +[Packages] + Platform/Loongson/LoongArchQemuPkg/Loongson.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + DebugLib + IoLib --=20 2.27.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#87199): https://edk2.groups.io/g/devel/message/87199 Mute This Topic: https://groups.io/mt/89497228/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-