From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.177]) by mx.groups.io with SMTP id smtpd.web11.6313.1662549128214841152 for ; Wed, 07 Sep 2022 04:12:08 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@ventanamicro.com header.s=google header.b=DvufHcW8; spf=pass (domain: ventanamicro.com, ip: 209.85.214.177, mailfrom: sunilvl@ventanamicro.com) Received: by mail-pl1-f177.google.com with SMTP id p18so14159130plr.8 for ; Wed, 07 Sep 2022 04:12:08 -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=v20odOrqDqpZAEyrlLnjMIUnKiQIpEbtKt5ZR10briI=; b=DvufHcW8hUhDQeGZbZ0TdjyuYcqfpG9RWBCo2UJaFDdaiOY+BveS3WipZFgKMt3OoW eRTT6BJ+2yIgTYFhWPqZlo0qe8lPRlSbAhD5xCq4+6+nDCyWpqjd5AJLg2CugrYRHIZa O23MQf/iVn5UFBe5jo/mv0GuD/vANK0NsZCJ1uQD8Hs4PTDKGX8kiauBr5f8c/gFaGM6 pcZnjIZcDLb6zuNttT4E//dKMKeqtazZ0C6ZJSViLdKvA6sLITLchjD17yqwPdHyLYH1 EoO2tXihs4HBhCXNyw4I3g1wW//3sOruhU43W4LftzCMsYeChvyOg4FVqKYVC9hJA9VA zSFg== 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=v20odOrqDqpZAEyrlLnjMIUnKiQIpEbtKt5ZR10briI=; b=Zk5HVmix5pFEXqGTHmnWZEmtpAQKIatfihJnN4p5I88IPbix6/6QzKcY7Y2xxx7fXf UcmpdG9ufUtvIRtddL8VKBkdFIzYb7meRL3JpwD5UQCQ7rzNdLr4tBk9MNrISuT83SoB E4G6t/GacsdvExwWnnFO2KokR4BY4tZRa0swhrpGTXI7SKDdGdnsrmK+NwhrwxyzYwAj 3sODApyFR6S2FsRIDwwoOfZ+rHord73pftSsyArEXoRGDS2dmg9DlIwz0LIzqhnEzfrC Y+9CUuZagMQZPcabMMJKO4nZaCoNgYnfStXwAfTW3PncWqqCFLBThf5bHHRLxSIlChRN SV7g== X-Gm-Message-State: ACgBeo0e89oPosVpu+10RuJfwXMFNTBsRdLKmYxDZC2U3O+9P7oZV2ML /rtXUMIta1Na7Vj6zq6iiUFzO8iC5FAMD9IW X-Google-Smtp-Source: AA6agR7CQsxLrjtrOIYuemYi2eY/akxs+R0mTTXbf4rpPhptuL1WWei1W02pygq37xUUW0x3TwuCew== X-Received: by 2002:a17:902:ef50:b0:171:516d:d2ce with SMTP id e16-20020a170902ef5000b00171516dd2cemr3267853plx.171.1662549127286; Wed, 07 Sep 2022 04:12:07 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([49.206.11.92]) by smtp.gmail.com with ESMTPSA id y5-20020aa79ae5000000b0052b84ca900csm12208518pfp.62.2022.09.07.04.12.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Sep 2022 04:12:06 -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: [RFC PATCH V2 07/19] MdePkg: Add ArchTimerLib library Date: Wed, 7 Sep 2022 16:41:13 +0530 Message-Id: <20220907111125.539698-8-sunilvl@ventanamicro.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220907111125.539698-1-sunilvl@ventanamicro.com> References: <20220907111125.539698-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/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=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/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=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 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=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 --=20 2.25.1