From nobody Tue Feb 10 17:46:23 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+93560+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+93560+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1662693145; cv=none; d=zohomail.com; s=zohoarc; b=Xt0D/pyGGfEJUFuoXh+M+JfDQg8R/Qkj7LT/xzypNt0M7ffAlu3cZ2CwfBTE4VUqKFtfypeTywv/j2rzTBmC5EnLPHrYbrpz309tdyFouzxrV7/2v5jAswGMloiIPR0Q3tNUPcENsEztAm+mVdmFbfNA9GxxvPL7KyHEU0yOqcA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1662693145; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=APzogm8nx+N7xqLtruRyIUEt+K129GmVX3U4qLEi8KA=; b=cFu4HlBJlWkdVMs6eKaugoY0CCXczt+/Jh7L9tmLvrX1A9OnUvpMocj3W9/hWAEiQJP4txwmGv9UM5Wo2ANgbYK25QZhMIR8IUHoBuVZ8i3F/v3kQ08oh9f2LxPh5Bv0ViNSW/j/fVhaI5hu/R619+hjAc5K29H6gmODpEjnohA= 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+93560+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1662693145281124.68801970160814; Thu, 8 Sep 2022 20:12:25 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id ziSlYY1788612xHdS4YlTREs; Thu, 08 Sep 2022 20:12:24 -0700 X-Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web08.2377.1662693140777495479 for ; Thu, 08 Sep 2022 20:12:21 -0700 X-Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxXWsMrxpjRP8UAA--.23346S8; Fri, 09 Sep 2022 11:12:15 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: maobibo@loongson.cn Subject: [edk2-devel] [edk2-platforms][PATCH V1 06/16] Platform/Loongson: Add StableTimerLib. Date: Fri, 9 Sep 2022 11:12:02 +0800 Message-Id: <9a53979093043d4da800cab803be9791e9af463c.1662691771.git.lixianglai@loongson.cn> In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8BxXWsMrxpjRP8UAA--.23346S8 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: TyTbQyt7neQIA2stvPqz2byex1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1662693144; bh=ATQu3G1n2rPDtj9gZnbApI/Ar5uA66E1jnJMfvqYXiE=; h=Cc:Date:From:Reply-To:Subject:To; b=IC6eDqvCiew+SkliZs24DWn6ufFi1LYu3qqctM87voa7+uYz2ZZvWDTwtWLS7rlhQE4 pv2eAPaxaJ09RNpECyq6HtaGta0eJ5eywOjHTfmFEfP79BrZ8mmZXd0y8nF5AkGFp+dhh fhz2xAkAYQ0eNlPw+UDYavGS+OKXq4EF/h8= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1662693146720100033 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.31.1 -=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 (#93560): https://edk2.groups.io/g/devel/message/93560 Mute This Topic: https://groups.io/mt/93565582/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-