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 6A81478003C for ; Fri, 12 Jan 2024 09:16:01 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=y9rLmCR2PYF8ACBW1Qty5vxYAnfXKG5YsM4k1/Kp4/U=; c=relaxed/simple; d=groups.io; h=Message-ID:Date:MIME-Version:User-Agent:Subject:To:Cc:References:From:In-Reply-To:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Type; s=20140610; t=1705050960; v=1; b=jN36aQTWbAFgUyARhJBgR04F9LzfHQXHJsV/JgvQ91tY4xiBxIqOIzvgxVighpve9XXmcWj2 Bh5HVmFtI1av7AwwaIRYv+vJSZOz3OrrnC+Di+ivbSVvnPWHNJNNB6A4oDZ4+VFqSRqQxPiK6Rc j9k29DGkGmCEXEwd+aariiM4= X-Received: by 127.0.0.2 with SMTP id YHXeYY7687511xPBq1hhXNXq; Fri, 12 Jan 2024 01:16:00 -0800 X-Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web11.3539.1705050957601245170 for ; Fri, 12 Jan 2024 01:15:59 -0800 X-Received: from loongson.cn (unknown [10.40.24.149]) by gateway (Coremail) with SMTP id _____8BxWepHA6FlloEEAA--.4929S3; Fri, 12 Jan 2024 17:15:52 +0800 (CST) X-Received: from [10.40.24.149] (unknown [10.40.24.149]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Ax691BA6FlVboTAA--.51598S3; Fri, 12 Jan 2024 17:15:46 +0800 (CST) Message-ID: <875260ce-d6cc-4d43-af32-a57484cdf8e9@loongson.cn> Date: Fri, 12 Jan 2024 17:15:45 +0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [edk2-devel] [PATCH v7 11/37] UefiCpuPkg: Add LoongArch64 CPU Timer library To: devel@edk2.groups.io, ray.ni@intel.com Cc: "Dong, Eric" , "Kumar, Rahul R" , Gerd Hoffmann References: <20240112082153.3284189-1-lichao@loongson.cn> <20240112082348.3288089-1-lichao@loongson.cn> From: "Chao Li" In-Reply-To: X-CM-TRANSID: AQAAf8Ax691BA6FlVboTAA--.51598S3 X-CM-SenderInfo: xolfxt3r6o00pqjv00gofq/1tbiAQAOCGWgj6kIsgABsf X-Coremail-Antispam: 1Uk129KBj93XoW3Zr43tr4fGry7Jw47uw4ftFc_yoWkAr4kpF 4qyFsrGr1xXr4fZrWUJ34jgF98Aan7CFyrGF4Ykr4qyw4DJws7Wan7trWqqFyxu3ya9r4F qrWjga13uFWkGagCm3ZEXasCq-sJn29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJUUUyCb4IE77IF4wAF F20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r 1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0Y4vE2Ix0cI8IcVAF wI0_JFI_Gr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Jr0_Gr1l84ACjcxK6I8E87Iv67 AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq 07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx1lYx0E2Ix0cI8IcVAFwI0_Jrv_JF 1lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvEwIxGrwCj r7xvwVCIw2I0I7xG6c02F41l42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr 1lx2IqxVAqx4xG67AKxVWUGVWUWwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE 14v26r126r1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7 IYx2IY6xkF7I0E14v26r1j6r4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E 87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r1j6r4UYxBIdaVFxhVjvjDU0x ZFpf9x07ULdb8UUUUU= 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: WK63FYCWlAYzhNR5Ta8Mj1nrx7686176AA= Content-Type: multipart/alternative; boundary="------------a7gJ95djMRLuBtHQDEFYVxaM" X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=jN36aQTW; 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 --------------a7gJ95djMRLuBtHQDEFYVxaM Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable Hi Ray, Thanks, Chao On 2024/1/12 16:51, Ni, Ray wrote: > Chao, > Do you mind putting the lib content under UefiCpuPkg/Library/CpuTimerLib/= LoongArch64/? > > It also follows the guidelines and avoid creating too many folders under = Library folder. No, I don't mind, do you means put the drivers or libraries under the=20 UefiCpuPkg into current corresponding folders to avoid the folder=20 explosion? If so, I agree, and recommend other ARCH's also follow this rule= . I have a question, how to deal with the '.inf' files? The current '.inf'=20 files only works with IA32 or X64, if our add other ARCH, the '.inf'=20 files will change a lot. Do you mind? I would suggest that if our want=20 them to hold more ARCHs, the '.inf' files should prepared ready first=20 and then add the other ARCHs to their folders would be better. What you=20 think? > > Thanks, > Ray >> -----Original Message----- >> From: Chao Li >> Sent: Friday, January 12, 2024 4:24 PM >> To:devel@edk2.groups.io >> Cc: Dong, Eric; Ni, Ray; Kumar, >> Rahul R; Gerd Hoffmann >> Subject: [PATCH v7 11/37] UefiCpuPkg: Add LoongArch64 CPU Timer library >> >> Add the LoongArch64 CPU Timer library, 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 >> Acked-by: Ray Ni >> --- >> .../BaseLoongArch64CpuTimerLib.inf | 29 ++ >> .../BaseLoongArch64CpuTimerLib.uni | 15 ++ >> .../BaseLoongArch64CpuTimerLib/CpuTimerLib.c | 251 >> ++++++++++++++++++ >> UefiCpuPkg/UefiCpuPkg.dsc | 3 + >> 4 files changed, 298 insertions(+) >> create mode 100644 >> UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTim >> erLib.inf >> create mode 100644 >> UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTim >> erLib.uni >> create mode 100644 >> UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/CpuTimerLib.c >> >> diff --git >> a/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuT >> imerLib.inf >> b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuT >> imerLib.inf >> new file mode 100644 >> index 0000000000..8648cc2a57 >> --- /dev/null >> +++ >> b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuT >> imerLib.inf >> @@ -0,0 +1,29 @@ >> +## @file >> +# Base CPU Timer Library >> +# >> +# Provides base timer support using CPUCFG 0x4 and 0x5 stable counter >> frequency. >> +# >> +# Copyright (c) 2024, Loongson Technology Corporation Limited. All rig= hts >> reserved.
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent >> +# >> +## >> + >> +[Defines] >> + INF_VERSION =3D 0x00010029 >> + BASE_NAME =3D BaseLoongArch64CpuTimerLib >> + FILE_GUID =3D 740389C7-CC44-4A2F-88DC-89D97D3= 12E7C >> + MODULE_TYPE =3D BASE >> + VERSION_STRING =3D 1.0 >> + LIBRARY_CLASS =3D TimerLib >> + MODULE_UNI_FILE =3D BaseLoongArch64CpuTimerLib.uni >> + >> +[Sources] >> + CpuTimerLib.c >> + >> +[Packages] >> + MdePkg/MdePkg.dec >> + >> +[LibraryClasses] >> + BaseLib >> + DebugLib >> + SafeIntLib >> diff --git >> a/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuT >> imerLib.uni >> b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuT >> imerLib.uni >> new file mode 100644 >> index 0000000000..f66e96e972 >> --- /dev/null >> +++ >> b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuT >> imerLib.uni >> @@ -0,0 +1,15 @@ >> +// /** @file >> +// Base CPU Timer Library >> +// >> +// Provides base timer support using CPUCFG 0x4 and 0x5 stable counter >> frequency. >> +// >> +// Copyright (c) 2024, Loongson Technology Corporation Limited. All rig= hts >> 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..a5ae8d0185 >> --- /dev/null >> +++ b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/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; >> +} >> diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc >> index 28eed85bce..a977884c3d 100644 >> --- a/UefiCpuPkg/UefiCpuPkg.dsc >> +++ b/UefiCpuPkg/UefiCpuPkg.dsc >> @@ -207,5 +207,8 @@ >> UefiCpuPkg/CpuTimerDxeRiscV64/CpuTimerDxeRiscV64.inf >> UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf >> >> +[Components.LOONGARCH64] >> + >> UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTim >> erLib.inf >> + >> [BuildOptions] >> *_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES >> -- >> 2.27.0 > > >=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 (#113701): https://edk2.groups.io/g/devel/message/113701 Mute This Topic: https://groups.io/mt/103679445/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- --------------a7gJ95djMRLuBtHQDEFYVxaM Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

Hi Ray,


=
Thanks,
Chao
On 2024/1/12 16:51, Ni, Ray wrote:
Chao,
Do you mind putting the lib content under UefiCpuPkg/Library/CpuTimerLib/Lo=
ongArch64/?

It also follows the guidelines and avoid creating too many folders under Li=
brary folder.

No, I don't mind, do you means put the drivers or libraries under the UefiCpuPkg into current corresponding folders to avoid the folder explosion? If so, I agree, and recommend other ARCH's also follow this rule.

I have a question, how to deal with the '.inf' files? The current '.inf' files only works with IA32 or X64, if our add other ARCH, the '.inf' files will change a lot. Do you mind? I would suggest that if our want them to hold more ARCHs, the '.inf' files should prepared ready first and then add the other ARCHs to their folders would be better. What you think?


Thanks,
Ray
-----Original Message-----
From: Chao Li <lichao@loongson.cn>
Sent: Friday, January 12, 2024 4:24 PM
To: devel@edk2.groups.io
Cc: Dong, Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; =
Kumar,
Rahul R <rahul.r.kumar@intel.com>; Gerd Hoffmann <kraxel@redhat.com&=
gt;
Subject: [PATCH v7 11/37] UefiCpuPkg: Add LoongArch64 CPU Timer library

Add the LoongArch64 CPU Timer library, using CPUCFG 0x4 and 0x5 for
Stable Counter frequency.

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

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Chao Li <lichao@loongson.cn>
Acked-by: Ray Ni <ray.ni@intel.com>
---
 .../BaseLoongArch64CpuTimerLib.inf            |  29 ++
 .../BaseLoongArch64CpuTimerLib.uni            |  15 ++
 .../BaseLoongArch64CpuTimerLib/CpuTimerLib.c  | 251
++++++++++++++++++
 UefiCpuPkg/UefiCpuPkg.dsc                     |   3 +
 4 files changed, 298 insertions(+)
 create mode 100644
UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTim
erLib.inf
 create mode 100644
UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTim
erLib.uni
 create mode 100644
UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/CpuTimerLib.c

diff --git
a/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuT
imerLib.inf
b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuT
imerLib.inf
new file mode 100644
index 0000000000..8648cc2a57
--- /dev/null
+++
b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuT
imerLib.inf
@@ -0,0 +1,29 @@
+## @file
+#  Base CPU Timer Library
+#
+#  Provides base timer support using CPUCFG 0x4 and 0x5 stable counter
frequency.
+#
+#  Copyright (c) 2024, Loongson Technology Corporation Limited. All rights
reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                       =3D 0x00010029
+  BASE_NAME                         =3D BaseLoongArch64CpuTimerLib
+  FILE_GUID                         =3D 740389C7-CC44-4A2F-88DC-89D97D312E=
7C
+  MODULE_TYPE                       =3D BASE
+  VERSION_STRING                    =3D 1.0
+  LIBRARY_CLASS                     =3D TimerLib
+  MODULE_UNI_FILE                   =3D BaseLoongArch64CpuTimerLib.uni
+
+[Sources]
+  CpuTimerLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  SafeIntLib
diff --git
a/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuT
imerLib.uni
b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuT
imerLib.uni
new file mode 100644
index 0000000000..f66e96e972
--- /dev/null
+++
b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuT
imerLib.uni
@@ -0,0 +1,15 @@
+// /** @file
+// Base CPU Timer Library
+//
+// Provides base timer support using CPUCFG 0x4 and 0x5 stable counter
frequency.
+//
+// Copyright (c) 2024, Loongson Technology Corporation Limited. All rights
reserved.<BR>
+//
+// 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..a5ae8d0185
--- /dev/null
+++ b/UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/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
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 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;
+}
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 28eed85bce..a977884c3d 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -207,5 +207,8 @@
   UefiCpuPkg/CpuTimerDxeRiscV64/CpuTimerDxeRiscV64.inf
   UefiCpuPkg/CpuDxeRiscV64/CpuDxeRiscV64.inf

+[Components.LOONGARCH64]
+
UefiCpuPkg/Library/BaseLoongArch64CpuTimerLib/BaseLoongArch64CpuTim
erLib.inf
+
 [BuildOptions]
   *_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES
--
2.27.0




_._,_._,_

Groups.io Links:

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

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

_._,_._,_
--------------a7gJ95djMRLuBtHQDEFYVxaM--