From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web12.444.1648174609807961786 for ; Thu, 24 Mar 2022 19:16:50 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: loongson.cn, ip: 114.242.206.163, mailfrom: lixianglai@loongson.cn) Received: from localhost.localdomain (unknown [10.2.10.197]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dx3xMIJj1irWAPAA--.15467S8; Fri, 25 Mar 2022 10:16:48 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: maobibo@loongson.cn Subject: [edk2-platforms][PATCH V2 06/16] Platform/Loongson: Add StableTimerLib. Date: Fri, 25 Mar 2022 10:16:10 +0800 Message-Id: X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Dx3xMIJj1irWAPAA--.15467S8 X-Coremail-Antispam: 1UD129KBjvJXoW3WrWUXw1DuF43KF15JrW3Awb_yoWDGr4kpF sxZa47Gr48Gr15A345Ja15KFy5AwsxArZ8WF45Crn7A3yDA3s3Ww1ktF40qFyfZrW3Wr92 q3y2ga1UuF4rX3DanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUBm14x267AKxVW5JVWrJwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26r4j6ryUM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_Ar0_tr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F 4UJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26F4U JVW0owAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7V C0I7IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j 6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwCY02Avz4vE-syl42 xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWU GwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1Y6r17MIIYrxkI7VAKI4 8JMIIF0xvE2Ix0cI8IcVAFwI0_JFI_Gr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4U MIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I 8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjfU8eOJUUUUU X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ Content-Transfer-Encoding: quoted-printable 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=0D +=0D + Copyright (c) 2021 Loongson Technology Corporation Limited. All rights r= eserved.
=0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D + @par Glossary:=0D + - Csr - Cpu Status Register=0D + - Calc - Calculation=0D + - Freq - frequency=0D +**/=0D +=0D +#ifndef STABLE_TIMER_H_=0D +#define STABLE_TIMER_H_=0D +#include "Library/Cpu.h"=0D +=0D +/**=0D + Gets the timer count value.=0D +=0D + @param[] VOID=0D +=0D + @retval timer count value.=0D +**/=0D +UINTN=0D +EFIAPI=0D +CsrReadTime (=0D + VOID=0D + );=0D +=0D +/**=0D + Calculate the timer frequency.=0D +=0D + @param[] VOID=0D +=0D + @retval Timer frequency.=0D +**/=0D +UINT32=0D +EFIAPI=0D +CalcConstFreq (=0D + VOID=0D + );=0D +#endif=0D 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 @@ +#-------------------------------------------------------------------------= -----=0D +#=0D +# Count for LoongArch=0D +#=0D +# Copyright (c) 2021 Loongson Technology Corporation Limited. All rights r= eserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +#-------------------------------------------------------------------------= -----=0D +=0D +#ifndef __ASSEMBLY__=0D +#define __ASSEMBLY__=0D +#endif=0D +=0D +#include "Library/Cpu.h"=0D +#include "LoongArchAsmMacro.h"=0D +#=0D +# Set cpu interrupts=0D +# @param A0 The interrupt number=0D +#=0D +ASM_FUNC(CpuSetIP)=0D + csrrd T0, LOONGARCH_CSR_ECFG=0D + or T0, T0, A0=0D + csrwr T0, LOONGARCH_CSR_ECFG=0D + jirl ZERO, RA,0=0D +=0D 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=0D + Generic LoongArch implementation of TimerLib.h=0D +=0D + Copyright (c) 2021 Loongson Technology Corporation Limited. All rights r= eserved.
=0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D + @par Glossary:=0D + - Freq - Frequency=0D + - Csr - Cpu Status Register=0D + - calc - calculate=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include "Library/StableTimer.h"=0D +#include "Library/Cpu.h"=0D +=0D +UINT32 StableTimerFreq =3D 0;=0D +=0D +/**=0D + Gets the timer count value.=0D +=0D + @param[] VOID=0D +=0D + @retval timer count value.=0D +**/=0D +UINTN=0D +EFIAPI=0D +CsrReadTime (=0D + VOID=0D + )=0D +{=0D + UINTN Value =3D 0;=0D + __asm__ __volatile__(=0D + " rdtime.d %0, $r0\n"=0D + : "=3Dr" (Value));=0D + return Value;=0D +}=0D +=0D +/**=0D + Calculate the timer frequency.=0D +=0D + @param[] VOID=0D +=0D + @retval Timer frequency.=0D +**/=0D +UINT32=0D +EFIAPI=0D +CalcConstFreq (=0D + VOID=0D + )=0D +{=0D + UINT32 Result;=0D + UINT32 BaseFreq;=0D + UINT32 ClockMultiplier;=0D + UINT32 ClockDivide;=0D +=0D + LOONGARCH_GET_CPUCFG (BaseFreq, LOONGARCH_CPUCFG4);=0D + LOONGARCH_GET_CPUCFG (Result, LOONGARCH_CPUCFG5);=0D + ClockMultiplier =3D Result & 0xffff;=0D + ClockDivide =3D (Result >> 16) & 0xffff;=0D +=0D + if ((!BaseFreq)=0D + || (!ClockMultiplier)=0D + || (!ClockDivide))=0D + {=0D + return 0;=0D + }=0D + else {=0D + return (BaseFreq * ClockMultiplier / ClockDivide);=0D + }=0D +}=0D +/**=0D + Get the timer frequency.=0D +=0D + @param[] VOID=0D +=0D + @retval Timer frequency.=0D +**/=0D +UINT32=0D +EFIAPI=0D +GetFreq (=0D + VOID=0D + )=0D +{=0D + if (StableTimerFreq) {=0D + } else {=0D + StableTimerFreq =3D CalcConstFreq ();=0D + }=0D +=0D + return StableTimerFreq;=0D +}=0D +=0D +/**=0D + Stalls the CPU for at least the given number of microseconds.=0D +=0D + Stalls the CPU for the number of microseconds specified by MicroSeconds.= =0D +=0D + @param MicroSeconds The minimum number of microseconds to delay.=0D +=0D + @return MicroSeconds=0D +=0D +**/=0D +UINTN=0D +EFIAPI=0D +MicroSecondDelay (=0D + IN UINTN MicroSeconds=0D + )=0D +{=0D +=0D + UINTN Count;=0D + UINTN Ticks;=0D + UINTN Start;=0D + UINTN End;=0D +=0D + Count =3D GetFreq ();=0D + Count =3D (Count * MicroSeconds) / 1000000;=0D + Start =3D CsrReadTime ();=0D + End =3D Start + Count;=0D +=0D + do {=0D + Ticks =3D CsrReadTime ();=0D + } while (Ticks < End);=0D +=0D + return MicroSeconds;=0D +}=0D +=0D +/**=0D + Stalls the CPU for at least the given number of nanoseconds.=0D +=0D + Stalls the CPU for the number of nanoseconds specified by NanoSeconds.=0D +=0D + @param NanoSeconds The minimum number of nanoseconds to delay.=0D +=0D + @return NanoSeconds=0D +=0D +**/=0D +UINTN=0D +EFIAPI=0D +NanoSecondDelay (=0D + IN UINTN NanoSeconds=0D + )=0D +{=0D + UINT32 MicroSeconds;=0D +=0D + if (NanoSeconds % 1000 =3D=3D 0) {=0D + MicroSeconds =3D NanoSeconds/1000;=0D + }else {=0D + MicroSeconds =3D NanoSeconds/1000 + 1;=0D + }=0D + MicroSecondDelay (MicroSeconds);=0D +=0D + return NanoSeconds;=0D +}=0D +=0D +/**=0D + Retrieves the current value of a 64-bit free running performance counter= .=0D +=0D + Retrieves the current value of a 64-bit free running performance counter= . The=0D + counter can either count up by 1 or count down by 1. If the physical=0D + performance counter counts by a larger increment, then the counter value= s=0D + must be translated. The properties of the counter can be retrieved from= =0D + GetPerformanceCounterProperties ().=0D +=0D + @return The current value of the free running performance counter.=0D +=0D +**/=0D +UINT64=0D +EFIAPI=0D +GetPerformanceCounter (=0D + VOID=0D + )=0D +{=0D + return CsrReadTime ();=0D +}=0D +/**=0D + Retrieves the 64-bit frequency in Hz and the range of performance counte= r=0D + values.=0D +=0D + If StartValue is not NULL, then the value that the performance counter s= tarts=0D + with immediately after is it rolls over is returned in StartValue. If=0D + EndValue is not NULL, then the value that the performance counter end wi= th=0D + immediately before it rolls over is returned in EndValue. The 64-bit=0D + frequency of the performance counter in Hz is always returned. If StartV= alue=0D + is less than EndValue, then the performance counter counts up. If StartV= alue=0D + is greater than EndValue, then the performance counter counts down. For= =0D + example, a 64-bit free running counter that counts up would have a Start= Value=0D + of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counte= r=0D + that counts down would have a StartValue of 0xFFFFFF and an EndValue of = 0.=0D +=0D + @param StartValue The value the performance counter starts with when i= t=0D + rolls over.=0D + @param EndValue The value that the performance counter ends with bef= ore=0D + it rolls over.=0D +=0D + @return The frequency in Hz.=0D +=0D +**/=0D +UINT64=0D +EFIAPI=0D +GetPerformanceCounterProperties (=0D + OUT UINT64 *StartValue, OPTIONAL=0D + OUT UINT64 *EndValue OPTIONAL=0D + )=0D +{=0D + if (StartValue !=3D NULL) {=0D + *StartValue =3D BIT2;=0D + }=0D +=0D + if (EndValue !=3D NULL) {=0D + *EndValue =3D BIT48 - 1;=0D + }=0D +=0D + return GetFreq ();=0D +}=0D +=0D +/**=0D + Converts elapsed ticks of performance counter to time in nanoseconds.=0D +=0D + This function converts the elapsed ticks of running performance counter = to=0D + time value in unit of nanoseconds.=0D +=0D + @param Ticks The number of elapsed ticks of running performance cou= nter.=0D +=0D + @return The elapsed time in nanoseconds.=0D +=0D +**/=0D +UINT64=0D +EFIAPI=0D +GetTimeInNanoSecond (=0D + IN UINT64 Ticks=0D + )=0D +{=0D + UINT64 Frequency;=0D + UINT64 NanoSeconds;=0D + UINT64 Remainder;=0D + INTN Shift;=0D +=0D + Frequency =3D GetPerformanceCounterProperties (NULL, NULL);=0D +=0D + //=0D + // Ticks=0D + // Time =3D --------- x 1,000,000,000=0D + // Frequency=0D + //=0D + NanoSeconds =3D MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remai= nder), 1000000000u);=0D +=0D + //=0D + // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.=0D + // Since 2^29 < 1,000,000,000 =3D 0x3B9ACA00 < 2^30, Remainder should < = 2^(64-30) =3D 2^34,=0D + // i.e. highest bit set in Remainder should <=3D 33.=0D + //=0D + Shift =3D MAX (0, HighBitSet64 (Remainder) - 33);=0D + Remainder =3D RShiftU64 (Remainder, (UINTN) Shift);=0D + Frequency =3D RShiftU64 (Frequency, (UINTN) Shift);=0D + NanoSeconds +=3D DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u)= , Frequency, NULL);=0D +=0D + return NanoSeconds;=0D +}=0D 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=0D +# Generic LoongArch implementation of TimerLib.h=0D +#=0D +# Copyright (c) 2021 Loongson Technology Corporation Limited. All rights = reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D TimerLib=0D + FILE_GUID =3D 740389C7-CC44-4A2F-88DC-89D97D312E= 7C=0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D TimerLib=0D +=0D +[Sources.common]=0D + TimerLib.c=0D + Count.S=0D +=0D +[Packages]=0D + Platform/Loongson/LoongArchQemuPkg/Loongson.dec=0D + MdePkg/MdePkg.dec=0D +=0D +[LibraryClasses]=0D + DebugLib=0D + IoLib=0D --=20 2.31.1