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 EABC1D800D7 for ; Wed, 31 Jan 2024 05:30:44 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=vu3hRj72AL/0hOKzWfJMwPZaBqf4FBt96n5/Eakbvt0=; c=relaxed/simple; d=groups.io; h=Message-ID:Date:MIME-Version:User-Agent:Subject:From:To:Cc:Reply-To:References:In-Reply-To:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Type; s=20140610; t=1706679043; v=1; b=tS0LTt1hbLIcFrBRQuzweSr765tmfnhamAszkH6ZimkAGWPqkryivSBODOS0uKWnGdMuWEmf 5P3rLqcKaJsB7naNPe5d5JitIX03psRZfCGTcRTs/4eS4UvalhVikmy04Chyn/e72J8qeri7UAR gD3kmOhsT71AegYtafOZHAlY= X-Received: by 127.0.0.2 with SMTP id EIRyYY7687511xHpbrYA9fqi; Tue, 30 Jan 2024 21:30:43 -0800 X-Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.8112.1706679042322350621 for ; Tue, 30 Jan 2024 21:30:42 -0800 X-Received: from loongson.cn (unknown [10.40.24.149]) by gateway (Coremail) with SMTP id _____8Bxyuh52rllKskIAA--.6932S3; Wed, 31 Jan 2024 13:28:26 +0800 (CST) X-Received: from [10.40.24.149] (unknown [10.40.24.149]) by localhost.localdomain (Coremail) with SMTP id AQAAf8AxHs9z2rllRJcpAA--.29936S3; Wed, 31 Jan 2024 13:28:19 +0800 (CST) Message-ID: Date: Wed, 31 Jan 2024 13:28:19 +0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [edk2-devel] [PATCH v8 11/37] UefiCpuPkg: Add LoongArch64 CPU Timer instance From: "Chao Li" To: devel@edk2.groups.io, Ray Ni , Laszlo Ersek Cc: Eric Dong , Rahul Kumar , Gerd Hoffmann Reply-To: devel@edk2.groups.io,lichao@loongson.cn References: <20240126062715.3099433-1-lichao@loongson.cn> <17ADD1D5A196C454.24595@groups.io> <17AF510405DE784C.15701@groups.io> In-Reply-To: <17AF510405DE784C.15701@groups.io> X-CM-TRANSID: AQAAf8AxHs9z2rllRJcpAA--.29936S3 X-CM-SenderInfo: xolfxt3r6o00pqjv00gofq/1tbiAQANCGW4s2EJfwABs8 X-Coremail-Antispam: 1Uk129KBj93XoW3Gw18uFyDGr4DZw1DAw4UJrc_yoWfJFW3pr 4qyFZrGr10qr1fAry7G3WUKF98Aw4fCry5WF15Ar1qyw4DJrZru3Z7trWqqFyfZr4agw40 qFW2gFs3uFWkJagCm3ZEXasCq-sJn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ34c02F40En4AKxVAvwIkv4cxYr27v73VFW2AGmfu7bjvjm3AaLaJ3UjIY CTnIWjp_UUUY27kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI8IcI k0rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK 021l84ACjcxK6xIIjxv20xvE14v26r1j6r1xM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r 1j6r4UM28EF7xvwVC2z280aVAFwI0_Cr0_Gr1UM28EF7xvwVC2z280aVCY1x0267AKxVW8 Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx1l5I 8CrVAaz4v26cxKscIFY7kG0wAv7VC0I7IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_ Gr0_Cr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcVAKI48JMx8GjcxK6IxK0xIIj40E5I 8CrwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v2 6r106r1rMI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIxkGc2 Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_ Jr0_Gr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r4j6F4UMI IF0xvEx4A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x07URWlkUUUUU = 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 List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: EIDDZDWgexotjBuj49LQPjGCx7686176AA= Content-Type: multipart/alternative; boundary="------------ipqO84ZBD9ra1JTetDlOy8vt" X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=tS0LTt1h; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io; dmarc=none --------------ipqO84ZBD9ra1JTetDlOy8vt Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable Hi Ray and Laszlo, I would very much like to be merged into stable202302, the soft feature=20 deadline is 2024-02-05, so could you please hlep to review this patch as=20 soon as passable? Please... Thanks, Chao On 2024/1/31 11:30, Chao Li wrote: > > Hi Ray, > > Can you please help to review this patch again? > > On 2024/1/26 14:29, Chao Li wrote: >> Add the LoongArch64 CPU Timer instance to CpuTimerLib, using CPUCFG 0x4 >> and 0x5 for Stable Counter frequency. >> >> BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4584 >> >> Cc: Eric Dong >> Cc: Ray Ni >> Cc: Rahul Kumar >> Cc: Gerd Hoffmann >> Signed-off-by: Chao Li >> --- >> .../Library/CpuTimerLib/BaseCpuTimerLib.inf | 9 +- >> .../CpuTimerLib/LoongArch64/CpuTimerLib.c | 251 ++++++++++++++++++ >> 2 files changed, 258 insertions(+), 2 deletions(-) >> create mode 100644 UefiCpuPkg/Library/CpuTimerLib/LoongArch64/CpuTimer= Lib.c >> >> diff --git a/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf b/UefiCp= uPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf >> index de0648de91..7e6152ef7e 100644 >> --- a/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf >> +++ b/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf >> @@ -5,6 +5,7 @@ >> # counter features are provided by the processors time stamp counter. >> # >> # Copyright (c) 2021, Intel Corporation. All rights reserved.
>> +# Copyright (c) 2024, Loongson Technology Corporation Limited. All rig= hts reserved.
>> # SPDX-License-Identifier: BSD-2-Clause-Patent >> # >> ## >> @@ -18,18 +19,22 @@ >> LIBRARY_CLASS =3D TimerLib >> MODULE_UNI_FILE =3D BaseCpuTimerLib.uni >> =20 >> -[Sources] >> +[Sources.IA32, Sources.X64] >> CpuTimerLib.c >> BaseCpuTimerLib.c >> =20 >> +[Sources.LOONGARCH64] >> + LoongArch64/CpuTimerLib.c >> + >> [Packages] >> MdePkg/MdePkg.dec >> UefiCpuPkg/UefiCpuPkg.dec >> =20 >> [LibraryClasses] >> BaseLib >> - PcdLib >> DebugLib >> + PcdLib >> + SafeIntLib >> =20 >> [Pcd] >> gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ## CONSUM= ES >> diff --git a/UefiCpuPkg/Library/CpuTimerLib/LoongArch64/CpuTimerLib.c b/= UefiCpuPkg/Library/CpuTimerLib/LoongArch64/CpuTimerLib.c >> new file mode 100644 >> index 0000000000..a5ae8d0185 >> --- /dev/null >> +++ b/UefiCpuPkg/Library/CpuTimerLib/LoongArch64/CpuTimerLib.c >> @@ -0,0 +1,251 @@ >> +/** @file >> + CPUCFG 0x4 and 0x5 for Stable Counter frequency instance of Timer Lib= rary. >> + >> + Copyright (c) 2024, Loongson Technology Corporation Limited. All righ= ts reserved.
>> + >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> +**/ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +/** >> + Calculate clock frequency using CPUCFG 0x4 and 0x5 registers. >> + >> + @param VOID. >> + >> + @return The frequency in Hz. >> + >> +**/ >> +STATIC >> +UINT64 >> +CalcConstFreq ( >> + VOID >> + ) >> +{ >> + UINT32 BaseFreq; >> + UINT64 ClockMultiplier; >> + UINT32 ClockDivide; >> + CPUCFG_REG4_INFO_DATA CcFreq; >> + CPUCFG_REG5_INFO_DATA CpucfgReg5Data; >> + UINT64 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 =3D CcFreq.Bits.CC_FREQ; >> + ClockMultiplier =3D CpucfgReg5Data.Bits.CC_MUL & 0xFFFF; >> + ClockDivide =3D CpucfgReg5Data.Bits.CC_DIV & 0xFFFF; >> + >> + if ((BaseFreq =3D=3D 0x0) || (ClockMultiplier =3D=3D 0x0) || (ClockDi= vide =3D=3D 0x0)) { >> + DEBUG (( >> + DEBUG_ERROR, >> + "LoongArch Stable Timer is not available in the CPU, hence this l= ibrary cannot be used.\n" >> + )); >> + ASSERT (FALSE); >> + CpuDeadLoop (); >> + } >> + >> + StableTimerFreq =3D ((ClockMultiplier * BaseFreq) / ClockDivide); >> + >> + if (StableTimerFreq =3D=3D 0x0) { >> + ASSERT (FALSE); >> + } >> + >> + return StableTimerFreq; >> +} >> + >> +/** >> + Stalls the CPU for at least the given number of microseconds. >> + >> + Stalls the CPU for the number of microseconds specified by MicroSecon= ds. >> + >> + @param MicroSeconds The minimum number of microseconds to delay. >> + >> + @return MicroSeconds >> + >> +**/ >> +UINTN >> +EFIAPI >> +MicroSecondDelay ( >> + IN UINTN MicroSeconds >> + ) >> +{ >> + UINT64 CurrentTicks, ExceptedTicks, Remaining; >> + RETURN_STATUS Status; >> + >> + Status =3D SafeUint64Mult (MicroSeconds, CalcConstFreq (), &Remaining= ); >> + ASSERT_RETURN_ERROR (Status); >> + >> + ExceptedTicks =3D DivU64x32 (Remaining, 1000000U); >> + CurrentTicks =3D AsmReadStableCounter (); >> + ExceptedTicks +=3D CurrentTicks; >> + >> + do { >> + CurrentTicks =3D AsmReadStableCounter (); >> + } while (CurrentTicks < ExceptedTicks); >> + >> + 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 >> + ) >> +{ >> + UINTN MicroSeconds; >> + >> + // Round up to 1us Tick Number >> + MicroSeconds =3D NanoSeconds / 1000; >> + MicroSeconds +=3D ((NanoSeconds % 1000) =3D=3D 0) ? 0 : 1; >> + >> + MicroSecondDelay (MicroSeconds); >> + >> + return NanoSeconds; >> +} >> + >> +/** >> + Retrieves the current value of a 64-bit free running Stable Counter. >> + >> + The LoongArch defines a constant frequency timer, whose main body is = a >> + 64-bit counter called StableCounter. StableCounter is set to 0 after >> + reset, and then increments by 1 every counting clock cycle. When the >> + count reaches all 1s, it automatically wraps around to 0 and continue= s >> + to increment. >> + The properties of the Stable Counter can be retrieved from >> + GetPerformanceCounterProperties(). >> + >> + @return The current value of the Stable Counter. >> + >> +**/ >> +UINT64 >> +EFIAPI >> +GetPerformanceCounter ( >> + VOID >> + ) >> +{ >> + // >> + // Just return the value of Stable Counter. >> + // >> + return AsmReadStableCounter (); >> +} >> + >> +/** >> + Retrieves the 64-bit frequency in Hz and the range of Stable Counter >> + values. >> + >> + If StartValue is not NULL, then the value that the stbale counter sta= rts >> + with immediately after is it rolls over is returned in StartValue. If >> + EndValue is not NULL, then the value that the stable counter end with >> + immediately before it rolls over is returned in EndValue. The 64-bit >> + frequency of the system frequency in Hz is always returned. >> + >> + @param StartValue The value the stable counter starts with when it >> + rolls over. >> + @param EndValue The value that the stable counter ends with befor= e >> + 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 0; >> + } >> + >> + if (EndValue !=3D NULL) { >> + *EndValue =3D 0xFFFFFFFFFFFFFFFFULL; >> + } >> + >> + return CalcConstFreq (); >> +} >> + >> +/** >> + Converts elapsed ticks of performance counter to time in nanoseconds. >> + >> + This function converts the elapsed ticks of running performance count= er 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; >> + RETURN_STATUS Status; >> + >> + Frequency =3D GetPerformanceCounterProperties (NULL, NULL); >> + >> + // >> + // Ticks >> + // Time =3D --------- x 1,000,000,000 >> + // Frequency >> + // >> + Status =3D SafeUint64Mult ( >> + DivU64x64Remainder (Ticks, Frequency, &Remainder), >> + 1000000000u, >> + &NanoSeconds >> + ); >> + >> + // >> + // 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); >> + >> + Status =3D SafeUint64Add ( >> + NanoSeconds, >> + DivU64x64Remainder ( >> + MultU64x32 (Remainder, 1000000000u), >> + Frequency, >> + NULL >> + ), >> + &NanoSeconds >> + ); >> + ASSERT_RETURN_ERROR (Status); >> + >> + return NanoSeconds; >> +} >=20 -=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 (#114860): https://edk2.groups.io/g/devel/message/114860 Mute This Topic: https://groups.io/mt/104070166/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- --------------ipqO84ZBD9ra1JTetDlOy8vt Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

Hi Ray and Laszlo,

I would very much like to be merged into stable202302, the soft feature deadline is 2024-02-05, so could you please hlep to review this patch as soon as passable? Please...


=
Thanks,
Chao
On 2024/1/31 11:30, Chao Li wrote:

Hi Ray,

Can you please help to review this patch again?

On 2024/1/26 14:29, Chao Li wrote:
Add the LoongArch64 CPU Time=
r instance to CpuTimerLib, using CPUCFG 0x4
and 0x5 for Stable Counter frequency.

BZ: https://bugzilla.tianocore.org/show_bug.cg=
i?id=3D4584

Cc: Eric Dong <er=
ic.dong@intel.com>
Cc: Ray Ni <ray.n=
i@intel.com>
Cc: Rahul Kumar <=
;rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <krax=
el@redhat.com>
Signed-off-by: Chao Li <lic=
hao@loongson.cn>
---
 .../Library/CpuTimerLib/BaseCpuTimerLib.inf   |   9 +-
 .../CpuTimerLib/LoongArch64/CpuTimerLib.c     | 251 ++++++++++++++++++
 2 files changed, 258 insertions(+), 2 deletions(-)
 create mode 100644 UefiCpuPkg/Library/CpuTimerLib/LoongArch64/CpuTimerLib.=
c

diff --git a/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf b/UefiCpuPk=
g/Library/CpuTimerLib/BaseCpuTimerLib.inf
index de0648de91..7e6152ef7e 100644
--- a/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf
+++ b/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf
@@ -5,6 +5,7 @@
 #  counter features are provided by the processors time stamp counter.
 #
 #  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2024, Loongson Technology Corporation Limited. All rights=
 reserved.<BR>
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 ##
@@ -18,18 +19,22 @@
   LIBRARY_CLASS                  =3D TimerLib
   MODULE_UNI_FILE                =3D BaseCpuTimerLib.uni
=20
-[Sources]
+[Sources.IA32, Sources.X64]
   CpuTimerLib.c
   BaseCpuTimerLib.c
=20
+[Sources.LOONGARCH64]
+  LoongArch64/CpuTimerLib.c
+
 [Packages]
   MdePkg/MdePkg.dec
   UefiCpuPkg/UefiCpuPkg.dec
=20
 [LibraryClasses]
   BaseLib
-  PcdLib
   DebugLib
+  PcdLib
+  SafeIntLib
=20
 [Pcd]
   gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency  ## CONSUMES
diff --git a/UefiCpuPkg/Library/CpuTimerLib/LoongArch64/CpuTimerLib.c b/Uef=
iCpuPkg/Library/CpuTimerLib/LoongArch64/CpuTimerLib.c
new file mode 100644
index 0000000000..a5ae8d0185
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuTimerLib/LoongArch64/CpuTimerLib.c
@@ -0,0 +1,251 @@
+/** @file
+  CPUCFG 0x4 and 0x5 for Stable Counter frequency instance of Timer Librar=
y.
+
+  Copyright (c) 2024, Loongson Technology Corporation Limited. All rights =
reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/SafeIntLib.h>
+#include <Library/TimerLib.h>
+#include <Register/LoongArch64/Cpucfg.h>
+
+/**
+  Calculate clock frequency using CPUCFG 0x4 and 0x5 registers.
+
+  @param  VOID.
+
+  @return The frequency in Hz.
+
+**/
+STATIC
+UINT64
+CalcConstFreq (
+  VOID
+  )
+{
+  UINT32                 BaseFreq;
+  UINT64                 ClockMultiplier;
+  UINT32                 ClockDivide;
+  CPUCFG_REG4_INFO_DATA  CcFreq;
+  CPUCFG_REG5_INFO_DATA  CpucfgReg5Data;
+  UINT64                 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        =3D CcFreq.Bits.CC_FREQ;
+  ClockMultiplier =3D CpucfgReg5Data.Bits.CC_MUL & 0xFFFF;
+  ClockDivide     =3D CpucfgReg5Data.Bits.CC_DIV & 0xFFFF;
+
+  if ((BaseFreq =3D=3D 0x0) || (ClockMultiplier =3D=3D 0x0) || (ClockDivid=
e =3D=3D 0x0)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "LoongArch Stable Timer is not available in the CPU, hence this libr=
ary cannot be used.\n"
+      ));
+    ASSERT (FALSE);
+    CpuDeadLoop ();
+  }
+
+  StableTimerFreq =3D ((ClockMultiplier * BaseFreq) / ClockDivide);
+
+  if (StableTimerFreq =3D=3D 0x0) {
+    ASSERT (FALSE);
+  }
+
+  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
+  )
+{
+  UINT64         CurrentTicks, ExceptedTicks, Remaining;
+  RETURN_STATUS  Status;
+
+  Status =3D SafeUint64Mult (MicroSeconds, CalcConstFreq (), &Remainin=
g);
+  ASSERT_RETURN_ERROR (Status);
+
+  ExceptedTicks  =3D DivU64x32 (Remaining, 1000000U);
+  CurrentTicks   =3D AsmReadStableCounter ();
+  ExceptedTicks +=3D CurrentTicks;
+
+  do {
+    CurrentTicks =3D AsmReadStableCounter ();
+  } while (CurrentTicks < ExceptedTicks);
+
+  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
+  )
+{
+  UINTN  MicroSeconds;
+
+  // Round up to 1us Tick Number
+  MicroSeconds  =3D NanoSeconds / 1000;
+  MicroSeconds +=3D ((NanoSeconds % 1000) =3D=3D 0) ? 0 : 1;
+
+  MicroSecondDelay (MicroSeconds);
+
+  return NanoSeconds;
+}
+
+/**
+  Retrieves the current value of a 64-bit free running Stable Counter.
+
+  The LoongArch defines a constant frequency timer, whose main body is a
+  64-bit counter called StableCounter. StableCounter is set to 0 after
+  reset, and then increments by 1 every counting clock cycle. When the
+  count reaches all 1s, it automatically wraps around to 0 and continues
+  to increment.
+  The properties of the Stable Counter can be retrieved from
+  GetPerformanceCounterProperties().
+
+  @return The current value of the Stable Counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+  VOID
+  )
+{
+  //
+  // Just return the value of Stable Counter.
+  //
+  return AsmReadStableCounter ();
+}
+
+/**
+  Retrieves the 64-bit frequency in Hz and the range of Stable Counter
+  values.
+
+  If StartValue is not NULL, then the value that the stbale counter starts
+  with immediately after is it rolls over is returned in StartValue. If
+  EndValue is not NULL, then the value that the stable counter end with
+  immediately before it rolls over is returned in EndValue. The 64-bit
+  frequency of the system frequency in Hz is always returned.
+
+  @param  StartValue  The value the stable counter starts with when it
+                      rolls over.
+  @param  EndValue    The value that the stable 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 !=3D NULL) {
+    *StartValue =3D 0;
+  }
+
+  if (EndValue !=3D NULL) {
+    *EndValue =3D 0xFFFFFFFFFFFFFFFFULL;
+  }
+
+  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 cou=
nter.
+
+  @return The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+  IN UINT64  Ticks
+  )
+{
+  UINT64         Frequency;
+  UINT64         NanoSeconds;
+  UINT64         Remainder;
+  INTN           Shift;
+  RETURN_STATUS  Status;
+
+  Frequency =3D GetPerformanceCounterProperties (NULL, NULL);
+
+  //
+  //          Ticks
+  // Time =3D --------- x 1,000,000,000
+  //        Frequency
+  //
+  Status =3D SafeUint64Mult (
+             DivU64x64Remainder (Ticks, Frequency, &Remainder),
+             1000000000u,
+             &NanoSeconds
+             );
+
+  //
+  // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.
+  // Since 2^29 < 1,000,000,000 =3D 0x3B9ACA00 < 2^30, Remainder sho=
uld < 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);
+
+  Status =3D SafeUint64Add (
+             NanoSeconds,
+             DivU64x64Remainder (
+               MultU64x32 (Remainder, 1000000000u),
+               Frequency,
+               NULL
+               ),
+             &NanoSeconds
+             );
+  ASSERT_RETURN_ERROR (Status);
+
+  return NanoSeconds;
+}
=20
_._,_._,_

Groups.io Links:

=20 You receive all messages sent to this group. =20 =20

View/Reply Online (#114860) | =20 | Mute= This Topic | New Topic
Your Subscriptio= n | Contact Group Owner | Unsubscribe [rebecca@openfw.io]

_._,_._,_
--------------ipqO84ZBD9ra1JTetDlOy8vt--