From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f54.google.com (mail-pj1-f54.google.com [209.85.216.54]) by mx.groups.io with SMTP id smtpd.web11.1854.1662484160753503252 for ; Tue, 06 Sep 2022 10:09:20 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@ventanamicro.com header.s=google header.b=M4RrPrbt; spf=pass (domain: ventanamicro.com, ip: 209.85.216.54, mailfrom: sunilvl@ventanamicro.com) Received: by mail-pj1-f54.google.com with SMTP id x1-20020a17090ab00100b001fda21bbc90so15634556pjq.3 for ; Tue, 06 Sep 2022 10:09:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=g2S/6iPGhEf+7xuezbpWIMbVuE7TQWPgp88F7Hicbk4=; b=M4RrPrbtQKGvImDFtXi0qUg62LC+UOT/viv9vHun1jpH7QSHpCV0wgqzkOnQWAH66z +Q6Rw0di3a40XXxY3U1fsOST8xvKV9mfzTLMN4lS4iyRuY+e0TrvjPNFfJoHOaYxmfR5 p50EzAwbGRwv2xW8rpQCr1C01Mp9t++Wxl1LFlxrsdZW56yTB9yrGOvCbohWQ5KBy4GM 4s4zZ598t+NEChd705cvL3gioBmqhSKxm3iPP3BO7PR9WitxDMM+ODTnNqy2TJr3RDvC qjIABA715gvLyADRHg8/mVX/4zAfDTTkf/tggXWR+hCkndyHLY6WpOHu1yAAzZJqznQp 4Zvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=g2S/6iPGhEf+7xuezbpWIMbVuE7TQWPgp88F7Hicbk4=; b=gX1NMsom3X8HoDeEEXmnt7Z5XstX2tuqS2I4HVZHnCwUBP0mfa69HnsT+cjL9J/0GE wceSRFX/XS6bEg1PbcpaQBvhdzjnY6JuPoHoWW8Y28Zo6Q02O6t3o4nKCe7+9qLIxPTd nW3L7+XzGbVCROl3hlb2HNfj15MaQMJjL4Hv3rjFbsmFZUkBFZfAvdYIyH4A2BigPEMc k3IZD+6JqdgMwba3aV5kdS/ucO88kLOOmJqksI0myqU8MrSem+lOpzU31yEX0tw7Skf7 RxBRs0LjctqCJPxmp0bNcrglK+fXVu3g0U6cyXriO7R8aTxUzg3LUfBHOTaOJUrlF2pw ac8A== X-Gm-Message-State: ACgBeo1NCEuEvdqGej9tPg994TdeJz1MivqceCdB3KYyjosT6oRrJCzm OSVa8F5VQzPdq78muGPJCaNbCOgTw6wGYkOy X-Google-Smtp-Source: AA6agR76yMvpmkFs8pEblp04akOeqepxl54Zj0OKzFsQSaPfgdwnns7uWDK1mAN9l2m+tO7ouOGnQg== X-Received: by 2002:a17:90a:8911:b0:1fa:c8f7:1450 with SMTP id u17-20020a17090a891100b001fac8f71450mr25059932pjn.123.1662484159931; Tue, 06 Sep 2022 10:09:19 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([49.206.11.92]) by smtp.gmail.com with ESMTPSA id b17-20020a170903229100b00176be258f41sm3806567plh.91.2022.09.06.10.09.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Sep 2022 10:09:19 -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 , Ard Biesheuvel , Heinrich Schuchardt , Anup Patel , Sunil V L Subject: [RFC PATCH 07/17] MdePkg: Add ArchTimerLib library Date: Tue, 6 Sep 2022 22:38:27 +0530 Message-Id: <20220906170837.491525-8-sunilvl@ventanamicro.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220906170837.491525-1-sunilvl@ventanamicro.com> References: <20220906170837.491525-1-sunilvl@ventanamicro.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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/ArchTimerLib.uni | 14 + .../ArchTimerLib/RiscV64/CpuTimerLib.c | 299 ++++++++++++++++++ 3 files changed, 353 insertions(+) create mode 100644 MdePkg/Library/ArchTimerLib/ArchTimerLib.inf create mode 100644 MdePkg/Library/ArchTimerLib/ArchTimerLib.uni create mode 100644 MdePkg/Library/ArchTimerLib/RiscV64/CpuTimerLib.c diff --git a/MdePkg/Library/ArchTimerLib/ArchTimerLib.inf b/MdePkg/Library/= ArchTimerLib/ArchTimerLib.inf new file mode 100644 index 0000000000..b61ae58d01 --- /dev/null +++ b/MdePkg/Library/ArchTimerLib/ArchTimerLib.inf @@ -0,0 +1,40 @@ +## @file=0D +# Timer Library Instance which needs a constructor for the architecture.=0D +#=0D +# Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. A= ll rights reserved.
=0D +# Copyright (c) 2022, Ventana Micro System Inc. All rights reserved.
= =0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x0001001b=0D + BASE_NAME =3D ArchTimerLib=0D + FILE_GUID =3D D3CF51A9-1CEA-4776-A8AB-CCFD14D7DAAF=0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D TimerLib=0D + MODULE_UNI_FILE =3D ArchTimerLib.uni=0D + CONSTRUCTOR =3D ArchTimerLibConstructor=0D +=0D +[Sources.RISCV64]=0D + RiscV64/CpuTimerLib.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + MdeModulePkg/MdeModulePkg.dec=0D + UefiCpuPkg/UefiCpuPkg.dec=0D + EmbeddedPkg/EmbeddedPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + DebugLib=0D + FdtLib=0D + HobLib=0D +=0D +[Pcd]=0D + gUefiCpuPkgTokenSpaceGuid.PcdRiscVTimerFrequencyInHz ## CONSUMES=0D +=0D +[Guids]=0D + gFdtHobGuid=0D diff --git a/MdePkg/Library/ArchTimerLib/ArchTimerLib.uni b/MdePkg/Library/= ArchTimerLib/ArchTimerLib.uni new file mode 100644 index 0000000000..1c900bea42 --- /dev/null +++ b/MdePkg/Library/ArchTimerLib/ArchTimerLib.uni @@ -0,0 +1,14 @@ +// /** @file=0D +// Base CPU Timer Library=0D +//=0D +// Provides basic timer support using architecture specific methods.=0D +//=0D +// Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
= =0D +//=0D +// SPDX-License-Identifier: BSD-2-Clause-Patent=0D +//=0D +// **/=0D +=0D +#string STR_MODULE_ABSTRACT #language en-US "CPU Timer Library= "=0D +=0D +#string STR_MODULE_DESCRIPTION #language en-US "Provides basic ti= mer support using architecture specific methods"=0D diff --git a/MdePkg/Library/ArchTimerLib/RiscV64/CpuTimerLib.c b/MdePkg/Lib= rary/ArchTimerLib/RiscV64/CpuTimerLib.c new file mode 100644 index 0000000000..a81ac8c37c --- /dev/null +++ b/MdePkg/Library/ArchTimerLib/RiscV64/CpuTimerLib.c @@ -0,0 +1,299 @@ +/** @file=0D + RISC-V instance of Timer Library.=0D +=0D + Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. Al= l rights reserved.
=0D + Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
= =0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +=0D +STATIC UINT32 mTimeBaseFrequency;=0D +STATIC BOOLEAN mTimeBaseFreqInitialized;=0D +=0D +UINT32=0D +InternalGetTimerFrequency(=0D + VOID=0D + )=0D +{=0D + return mTimeBaseFrequency;=0D +}=0D +=0D +=0D +/**=0D + Stalls the CPU for at least the given number of ticks.=0D +=0D + Stalls the CPU for at least the given number of ticks. It's invoked by=0D + MicroSecondDelay() and NanoSecondDelay().=0D +=0D + @param Delay A period of time to delay in ticks.=0D +=0D +**/=0D +VOID=0D +InternalRiscVTimerDelay (=0D + IN UINT32 Delay=0D + )=0D +{=0D + UINT32 Ticks;=0D + UINT32 Times;=0D +=0D + Times =3D Delay >> (RISCV_TIMER_COMPARE_BITS - 2);=0D + Delay &=3D ((1 << (RISCV_TIMER_COMPARE_BITS - 2)) - 1);=0D + do {=0D + //=0D + // The target timer count is calculated here=0D + //=0D + Ticks =3D csr_read(CSR_TIME) + Delay;=0D + Delay =3D 1 << (RISCV_TIMER_COMPARE_BITS - 2);=0D + while (((Ticks - csr_read(CSR_TIME)) & (1 << (RISCV_TIMER_COMPARE_BITS= - 1))) =3D=3D 0) {=0D + CpuPause ();=0D + }=0D + } while (Times-- > 0);=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 + InternalRiscVTimerDelay (=0D + (UINT32)DivU64x32 (=0D + MultU64x32 (=0D + MicroSeconds,=0D + InternalGetTimerFrequency()=0D + ),=0D + 1000000u=0D + )=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 + InternalRiscVTimerDelay (=0D + (UINT32)DivU64x32 (=0D + MultU64x32 (=0D + NanoSeconds,=0D + InternalGetTimerFrequency()=0D + ),=0D + 1000000000u=0D + )=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 (UINT64)csr_read (CSR_TIME);=0D +}=0D +=0D +/**return=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 0;=0D + }=0D +=0D + if (EndValue !=3D NULL) {=0D + *EndValue =3D 32 - 1;=0D + }=0D +=0D + return InternalGetTimerFrequency();=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 NanoSeconds;=0D + UINT32 Remainder;=0D +=0D + //=0D + // Ticks=0D + // Time =3D --------- x 1,000,000,000=0D + // Frequency=0D + //=0D + NanoSeconds =3D MultU64x32 (DivU64x32Remainder (Ticks, InternalGetTimerF= requency(), &Remainder), 1000000000u);=0D +=0D + //=0D + // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder = * 1,000,000,000)=0D + // will not overflow 64-bit.=0D + //=0D + NanoSeconds +=3D DivU64x32 (MultU64x32 ((UINT64)Remainder, 1000000000u),= InternalGetTimerFrequency());=0D +=0D + return NanoSeconds;=0D +}=0D +=0D +STATIC=0D +RETURN_STATUS=0D +EFIAPI=0D +FdtInitializeTimerFrequency (=0D + VOID=0D + )=0D +{=0D + VOID *Hob;=0D + VOID *Fdt;=0D + INT32 CpusNode, Len;=0D + const fdt32_t *Prop;=0D +=0D + Hob =3D GetFirstGuidHob (&gFdtHobGuid);=0D + if ((Hob =3D=3D NULL) || (GET_GUID_HOB_DATA_SIZE (Hob) !=3D sizeof (UINT= 64))) {=0D + DEBUG ((DEBUG_ERROR, "%a: No FDT Hob found\n", __FUNCTION__));=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + Fdt =3D (VOID *)(UINTN)*(UINT64 *)GET_GUID_HOB_DATA (Hob);=0D +=0D + if (fdt_check_header (Fdt) !=3D 0) {=0D + DEBUG ((=0D + DEBUG_ERROR,=0D + "%a: No DTB found @ 0x%p\n",=0D + __FUNCTION__,=0D + Fdt=0D + ));=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + // The "cpus" node resides at the the root of the DT. Fetch it.=0D + CpusNode =3D fdt_path_offset (Fdt, "/cpus");=0D + if (CpusNode < 0) {=0D + DEBUG ((DEBUG_ERROR, "%a: Invalid /cpus node\n", __FUNCTION__));=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + Prop =3D fdt_getprop((void *)Fdt, CpusNode, "timebase-frequency", &Len);= =0D + if (!Prop) {=0D + DEBUG ((DEBUG_ERROR, "%a: timebase-frequency propertynot found\n", __F= UNCTION__));=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + mTimeBaseFrequency =3D fdt32_to_cpu(*Prop);=0D + DEBUG((DEBUG_INFO, "%a: Timer Frequency (DT) is set to 0x%x\n", __FUNCTI= ON__, mTimeBaseFrequency));=0D +=0D + return EFI_SUCCESS;=0D +}=0D +/**=0D + Initializes the Timer Frequency by reading it from the DTB=0D +=0D +**/=0D +RETURN_STATUS=0D +EFIAPI=0D +ArchTimerLibConstructor (=0D + VOID=0D + )=0D +{=0D + EFI_STATUS Status;=0D +=0D + /*=0D + * Initialize only once=0D + */=0D + if (mTimeBaseFreqInitialized) {=0D + return EFI_SUCCESS;=0D + }=0D +=0D + mTimeBaseFreqInitialized =3D 1;=0D +=0D + Status =3D FdtInitializeTimerFrequency();=0D +=0D + if (EFI_ERROR(Status)) {=0D + mTimeBaseFrequency =3D PcdGet32 (PcdRiscVTimerFrequencyInHz);=0D + DEBUG((DEBUG_INFO, "%a: Timer Frequency (PCD) is set to 0x%x\n", __FUN= CTION__, mTimeBaseFrequency));=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D --=20 2.25.1