From nobody Mon Feb 9 23:16:01 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+93405+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+93405+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1662550632; cv=none; d=zohomail.com; s=zohoarc; b=lD+PAKIXnjur4F8tpOP+IejRDq0RcvU82nGW0H/AT9DFbEC1t/3rRGSfH/BiTV0IE2M09MiU6/7/EdxCM2GliUise+ErRVWPe+u1UBTIKOJZGFpgdAU0KGkG2r1pu8GI8P2HWte6Ml2IYQ/3YGgYwrEZ+ew7DEtxnuzBzbgrq8c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1662550632; 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=Eq/fyAC5ztCK+eUWpzY5S+o9WpeFIUB3WkII6AI2J/o=; b=JywVcNRmIItLay1lgVg2O57fIEi7Ta8ldCAx6Icumwbn8BgF1Q7leMo3zR5+MWAKADl+Qj9E3i4SU3oByjrU7eZXTkjn9eJSp+fiUHFZmBFoOmDMK+cJX5MrbmLXDQFOABJIF3CaNqKx6t4wD6Fs/NgvBqs3MsLD7eP9bhNxVtk= 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+93405+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1662550632306587.4473722093669; Wed, 7 Sep 2022 04:37:12 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id T6AUYY1788612xwckLePLk24; Wed, 07 Sep 2022 04:37:11 -0700 X-Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) by mx.groups.io with SMTP id smtpd.web12.6600.1662550631377451143 for ; Wed, 07 Sep 2022 04:37:11 -0700 X-Received: by mail-pf1-f181.google.com with SMTP id 145so14351356pfw.4 for ; Wed, 07 Sep 2022 04:37:11 -0700 (PDT) X-Gm-Message-State: rXrkGQBa8hcAYcYneLyWSx01x1787277AA= X-Google-Smtp-Source: AA6agR6OPkU8hNo+quEyHECdIPFUzoBVzZETb/am8O3RZrWVBxoZe7Is/FbEUdimit3+HH1ZwA39/A== X-Received: by 2002:a63:fc45:0:b0:434:1ff6:e546 with SMTP id r5-20020a63fc45000000b004341ff6e546mr3045987pgk.327.1662550630473; Wed, 07 Sep 2022 04:37:10 -0700 (PDT) X-Received: from localhost.localdomain ([49.206.11.92]) by smtp.gmail.com with ESMTPSA id 8-20020a17090a000800b001fd77933fb3sm10797230pja.17.2022.09.07.04.37.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Sep 2022 04:37:10 -0700 (PDT) From: "Sunil V L" To: devel@edk2.groups.io Cc: Jian J Wang , Liming Gao , Eric Dong , Ray Ni , Rahul Kumar , Debkumar De , Catharine West , Daniel Schaefer , Abner Chang , Leif Lindholm , Andrew Fish , Ard Biesheuvel , Heinrich Schuchardt , Anup Patel , Sunil V L Subject: [edk2-devel] [RFC PATCH V2 07/19] MdePkg: Add ArchTimerLib library Date: Wed, 7 Sep 2022 17:06:14 +0530 Message-Id: <20220907113626.540065-8-sunilvl@ventanamicro.com> In-Reply-To: <20220907113626.540065-1-sunilvl@ventanamicro.com> References: <20220907113626.540065-1-sunilvl@ventanamicro.com> MIME-Version: 1.0 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,sunilvl@ventanamicro.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1662550631; bh=eBrLRVkS4kPkBX97S7K45SjXjo2OnvXFcsn+wR8I0Es=; h=Cc:Date:From:Reply-To:Subject:To; b=SyIwLoLdTpZCsaQpH5AVbW6yvLO57iuX8voUy/kBZq2TwSJTMCce9Ae0TTTEVzuOWdY sbJEl6s/OJaP93b2X4fnnwgdjqkwNmRt2XOjlPDfSooD7l7zXbB5qccKs/vXDqahIcZrn yuqYGjw8aITFbDKqUH8wJ0PbUCgk/rF95kw= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1662550634508100005 Content-Type: text/plain; charset="utf-8" This library implements the TimerLib.h functionality. This library is similar to CpuTimerLib but needs the library constructor. Signed-off-by: Sunil V L --- MdePkg/Library/ArchTimerLib/ArchTimerLib.inf | 40 +++ MdePkg/Library/ArchTimerLib/RiscV64/CpuTimerLib.c | 299 ++++++++++++++++++= ++ MdePkg/Library/ArchTimerLib/ArchTimerLib.uni | 14 + 3 files changed, 353 insertions(+) diff --git a/MdePkg/Library/ArchTimerLib/ArchTimerLib.inf b/MdePkg/Library/= ArchTimerLib/ArchTimerLib.inf new file mode 100644 index 000000000000..b61ae58d0142 --- /dev/null +++ b/MdePkg/Library/ArchTimerLib/ArchTimerLib.inf @@ -0,0 +1,40 @@ +## @file +# Timer Library Instance which needs a constructor for the architecture. +# +# Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. A= ll rights reserved.
+# Copyright (c) 2022, Ventana Micro System Inc. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x0001001b + BASE_NAME =3D ArchTimerLib + FILE_GUID =3D D3CF51A9-1CEA-4776-A8AB-CCFD14D7DAAF + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D TimerLib + MODULE_UNI_FILE =3D ArchTimerLib.uni + CONSTRUCTOR =3D ArchTimerLibConstructor + +[Sources.RISCV64] + RiscV64/CpuTimerLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + FdtLib + HobLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdRiscVTimerFrequencyInHz ## CONSUMES + +[Guids] + gFdtHobGuid diff --git a/MdePkg/Library/ArchTimerLib/RiscV64/CpuTimerLib.c b/MdePkg/Lib= rary/ArchTimerLib/RiscV64/CpuTimerLib.c new file mode 100644 index 000000000000..a81ac8c37cad --- /dev/null +++ b/MdePkg/Library/ArchTimerLib/RiscV64/CpuTimerLib.c @@ -0,0 +1,299 @@ +/** @file + RISC-V instance of Timer Library. + + Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. Al= l rights reserved.
+ Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +STATIC UINT32 mTimeBaseFrequency; +STATIC BOOLEAN mTimeBaseFreqInitialized; + +UINT32 +InternalGetTimerFrequency( + VOID + ) +{ + return mTimeBaseFrequency; +} + + +/** + Stalls the CPU for at least the given number of ticks. + + Stalls the CPU for at least the given number of ticks. It's invoked by + MicroSecondDelay() and NanoSecondDelay(). + + @param Delay A period of time to delay in ticks. + +**/ +VOID +InternalRiscVTimerDelay ( + IN UINT32 Delay + ) +{ + UINT32 Ticks; + UINT32 Times; + + Times =3D Delay >> (RISCV_TIMER_COMPARE_BITS - 2); + Delay &=3D ((1 << (RISCV_TIMER_COMPARE_BITS - 2)) - 1); + do { + // + // The target timer count is calculated here + // + Ticks =3D csr_read(CSR_TIME) + Delay; + Delay =3D 1 << (RISCV_TIMER_COMPARE_BITS - 2); + while (((Ticks - csr_read(CSR_TIME)) & (1 << (RISCV_TIMER_COMPARE_BITS= - 1))) =3D=3D 0) { + CpuPause (); + } + } while (Times-- > 0); +} + +/** + 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 + ) +{ + InternalRiscVTimerDelay ( + (UINT32)DivU64x32 ( + MultU64x32 ( + MicroSeconds, + InternalGetTimerFrequency() + ), + 1000000u + ) + ); + 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 + ) +{ + InternalRiscVTimerDelay ( + (UINT32)DivU64x32 ( + MultU64x32 ( + NanoSeconds, + InternalGetTimerFrequency() + ), + 1000000000u + ) + ); + 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 (UINT64)csr_read (CSR_TIME); +} + +/**return + 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 0; + } + + if (EndValue !=3D NULL) { + *EndValue =3D 32 - 1; + } + + return InternalGetTimerFrequency(); +} + +/** + 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 NanoSeconds; + UINT32 Remainder; + + // + // Ticks + // Time =3D --------- x 1,000,000,000 + // Frequency + // + NanoSeconds =3D MultU64x32 (DivU64x32Remainder (Ticks, InternalGetTimerF= requency(), &Remainder), 1000000000u); + + // + // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder = * 1,000,000,000) + // will not overflow 64-bit. + // + NanoSeconds +=3D DivU64x32 (MultU64x32 ((UINT64)Remainder, 1000000000u),= InternalGetTimerFrequency()); + + return NanoSeconds; +} + +STATIC +RETURN_STATUS +EFIAPI +FdtInitializeTimerFrequency ( + VOID + ) +{ + VOID *Hob; + VOID *Fdt; + INT32 CpusNode, Len; + const fdt32_t *Prop; + + Hob =3D GetFirstGuidHob (&gFdtHobGuid); + if ((Hob =3D=3D NULL) || (GET_GUID_HOB_DATA_SIZE (Hob) !=3D sizeof (UINT= 64))) { + DEBUG ((DEBUG_ERROR, "%a: No FDT Hob found\n", __FUNCTION__)); + return EFI_NOT_FOUND; + } + + Fdt =3D (VOID *)(UINTN)*(UINT64 *)GET_GUID_HOB_DATA (Hob); + + if (fdt_check_header (Fdt) !=3D 0) { + DEBUG (( + DEBUG_ERROR, + "%a: No DTB found @ 0x%p\n", + __FUNCTION__, + Fdt + )); + return EFI_NOT_FOUND; + } + + // The "cpus" node resides at the the root of the DT. Fetch it. + CpusNode =3D fdt_path_offset (Fdt, "/cpus"); + if (CpusNode < 0) { + DEBUG ((DEBUG_ERROR, "%a: Invalid /cpus node\n", __FUNCTION__)); + return EFI_NOT_FOUND; + } + + Prop =3D fdt_getprop((void *)Fdt, CpusNode, "timebase-frequency", &Len); + if (!Prop) { + DEBUG ((DEBUG_ERROR, "%a: timebase-frequency propertynot found\n", __F= UNCTION__)); + return EFI_NOT_FOUND; + } + + mTimeBaseFrequency =3D fdt32_to_cpu(*Prop); + DEBUG((DEBUG_INFO, "%a: Timer Frequency (DT) is set to 0x%x\n", __FUNCTI= ON__, mTimeBaseFrequency)); + + return EFI_SUCCESS; +} +/** + Initializes the Timer Frequency by reading it from the DTB + +**/ +RETURN_STATUS +EFIAPI +ArchTimerLibConstructor ( + VOID + ) +{ + EFI_STATUS Status; + + /* + * Initialize only once + */ + if (mTimeBaseFreqInitialized) { + return EFI_SUCCESS; + } + + mTimeBaseFreqInitialized =3D 1; + + Status =3D FdtInitializeTimerFrequency(); + + if (EFI_ERROR(Status)) { + mTimeBaseFrequency =3D PcdGet32 (PcdRiscVTimerFrequencyInHz); + DEBUG((DEBUG_INFO, "%a: Timer Frequency (PCD) is set to 0x%x\n", __FUN= CTION__, mTimeBaseFrequency)); + } + + return EFI_SUCCESS; +} diff --git a/MdePkg/Library/ArchTimerLib/ArchTimerLib.uni b/MdePkg/Library/= ArchTimerLib/ArchTimerLib.uni new file mode 100644 index 000000000000..1c900bea42bf --- /dev/null +++ b/MdePkg/Library/ArchTimerLib/ArchTimerLib.uni @@ -0,0 +1,14 @@ +// /** @file +// Base CPU Timer Library +// +// Provides basic timer support using architecture specific methods. +// +// Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "CPU Timer Library" + +#string STR_MODULE_DESCRIPTION #language en-US "Provides basic ti= mer support using architecture specific methods" --=20 2.25.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 (#93405): https://edk2.groups.io/g/devel/message/93405 Mute This Topic: https://groups.io/mt/93522705/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-