Reviewed-by: Andrei Warkentin <andrei.warken...@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sunil V L
Sent: Saturday, January 28, 2023 1:18 PM
To: devel@edk2.groups.io
Cc: Dong, Eric <eric.d...@intel.com>; Ni, Ray <ray...@intel.com>; Kumar, Rahul 
R <rahul.r.ku...@intel.com>; Daniel Schaefer <g...@danielschaefer.me>; Abner 
Chang <abner.ch...@amd.com>; Gerd Hoffmann <kra...@redhat.com>
Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 08/20] 
UefiCpuPkg/CpuTimerLib: Add RISC-V instance

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

This is mostly copied from
edk2-platforms/Silicon/RISC-V/ProcessorPkg/Library/RiscVTimerLib

Cc: Eric Dong <eric.d...@intel.com>
Cc: Ray Ni <ray...@intel.com>
Cc: Rahul Kumar <rahul1.ku...@intel.com>
Cc: Daniel Schaefer <g...@danielschaefer.me>
Cc: Abner Chang <abner.ch...@amd.com>
Cc: Gerd Hoffmann <kra...@redhat.com>
Signed-off-by: Sunil V L <suni...@ventanamicro.com>
Acked-by: Abner Chang <abner.ch...@amd.com>
---
 UefiCpuPkg/UefiCpuPkg.dsc                                 |   1 +
 UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf |  32 ++++
 UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c      | 199 
++++++++++++++++++++
 3 files changed, 232 insertions(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 
8f2be6cd1b05..2df02bf75a35 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -199,6 +199,7 @@ [Components.RISCV64]
   UefiCpuPkg/CpuTimerDxe/CpuTimerDxe.inf
   
UefiCpuPkg/Library/CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
   UefiCpuPkg/CpuDxe/CpuDxeRiscV64.inf
+  UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
 
 [BuildOptions]
   *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES diff --git 
a/UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf 
b/UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
new file mode 100644
index 000000000000..c920e8e098b5
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuTimerLib/BaseRiscV64CpuTimerLib.inf
@@ -0,0 +1,32 @@
+## @file
+# RISC-V Base CPU Timer Library Instance # #  Copyright (c) 2016 - 
+2019, Hewlett Packard Enterprise Development LP. All rights 
+reserved.<BR> #  Copyright (c) 2022, Ventana Micro Systems Inc. All 
+rights reserved.<BR> # #  SPDX-License-Identifier: BSD-2-Clause-Patent 
+# ##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = BaseRisV64CpuTimerLib
+  FILE_GUID                      = B635A600-EA24-4199-88E8-5761EEA96A51
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TimerLib
+
+[Sources]
+  RiscV64/CpuTimerLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  DebugLib
+
+[Pcd]
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency  ## 
+CONSUMES
diff --git a/UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c 
b/UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c
new file mode 100644
index 000000000000..9c8efc0f3530
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuTimerLib/RiscV64/CpuTimerLib.c
@@ -0,0 +1,199 @@
+/** @file
+  RISC-V instance of Timer Library.
+
+  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. 
+ All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Register/RiscV64/RiscVImpl.h>
+
+/**
+  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  = Delay >> (RISCV_TIMER_COMPARE_BITS - 2);
+  Delay &= ((1 << (RISCV_TIMER_COMPARE_BITS - 2)) - 1);
+  do {
+    //
+    // The target timer count is calculated here
+    //
+    Ticks = RiscVReadTimer () + Delay;
+    Delay = 1 << (RISCV_TIMER_COMPARE_BITS - 2);
+    while (((Ticks - RiscVReadTimer ()) & (1 << (RISCV_TIMER_COMPARE_BITS - 
1))) == 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,
+                PcdGet64 (PcdCpuCoreCrystalClockFrequency)
+                ),
+              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,
+                PcdGet64 (PcdCpuCoreCrystalClockFrequency)
+                ),
+              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)RiscVReadTimer ();
+}
+
+/**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 starts  with immediately after is it rolls over is returned in 
+ StartValue. If  EndValue is not NULL, then the value that the 
+ performance counter end with  immediately before it rolls over is 
+ returned in EndValue. The 64-bit  frequency of the performance counter 
+ in Hz is always returned. If StartValue  is less than EndValue, then 
+ the performance counter counts up. If StartValue  is greater than 
+ EndValue, then the performance counter counts down. For  example, a 
+ 64-bit free running counter that counts up would have a StartValue  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 before
+                      it rolls over.
+
+  @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+  OUT      UINT64 *StartValue, OPTIONAL
+  OUT      UINT64                    *EndValue     OPTIONAL
+  )
+{
+  if (StartValue != NULL) {
+    *StartValue = 0;
+  }
+
+  if (EndValue != NULL) {
+    *EndValue = 32 - 1;
+  }
+
+  return PcdGet64 (PcdCpuCoreCrystalClockFrequency);
+}
+
+/**
+  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  NanoSeconds;
+  UINT32  Remainder;
+
+  //
+  //          Ticks
+  // Time = --------- x 1,000,000,000
+  //        Frequency
+  //
+  NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, PcdGet64 
+ (PcdCpuCoreCrystalClockFrequency), &Remainder), 1000000000u);
+
+  //
+  // Frequency < 0x100000000, so Remainder < 0x100000000, then 
+ (Remainder * 1,000,000,000)  // will not overflow 64-bit.
+  //
+  NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder, 
+ 1000000000u), PcdGet64 (PcdCpuCoreCrystalClockFrequency));
+
+  return NanoSeconds;
+}
--
2.38.0








-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#99675): https://edk2.groups.io/g/devel/message/99675
Mute This Topic: https://groups.io/mt/96593504/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to