]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg: Add BaseRiscV64CpuTimerLib library
authorSunil V L <sunilvl@ventanamicro.com>
Wed, 5 Oct 2022 06:02:50 +0000 (11:32 +0530)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 16 Feb 2023 05:53:28 +0000 (05:53 +0000)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

Add the RISC-V instance of the TimerLib.

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

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Daniel Schaefer <git@danielschaefer.me>
Cc: Abner Chang <abner.chang@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>
Acked-by: Ray Ni <ray.ni@Intel.com>
UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/BaseRiscV64CpuTimerLib.inf [new file with mode: 0644]
UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/BaseRiscV64CpuTimerLib.uni [new file with mode: 0644]
UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c [new file with mode: 0644]
UefiCpuPkg/UefiCpuPkg.dsc

diff --git a/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/BaseRiscV64CpuTimerLib.inf b/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/BaseRiscV64CpuTimerLib.inf
new file mode 100644 (file)
index 0000000..3d5eaa4
--- /dev/null
@@ -0,0 +1,33 @@
+## @file\r
+# RISC-V Base CPU Timer Library Instance\r
+#\r
+#  Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+#  Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.<BR>\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x0001001B\r
+  BASE_NAME                      = BaseRisV64CpuTimerLib\r
+  FILE_GUID                      = B635A600-EA24-4199-88E8-5761EEA96A51\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = TimerLib\r
+  MODULE_UNI_FILE                = BaseRisV64CpuTimerLib.uni\r
+\r
+[Sources]\r
+  CpuTimerLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  PcdLib\r
+  DebugLib\r
+\r
+[Pcd]\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency  ## CONSUMES\r
diff --git a/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/BaseRiscV64CpuTimerLib.uni b/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/BaseRiscV64CpuTimerLib.uni
new file mode 100644 (file)
index 0000000..bb061f9
--- /dev/null
@@ -0,0 +1,14 @@
+// /** @file\r
+// Base CPU Timer Library for RISC-V\r
+//\r
+// Copyright (c) 2023, Ventana Micro Systems Inc. All rights reserved.<BR>\r
+//\r
+// SPDX-License-Identifier: BSD-2-Clause-Patent\r
+//\r
+// **/\r
+\r
+\r
+#string STR_MODULE_ABSTRACT             #language en-US "RISC-V CPU Timer Library"\r
+\r
+#string STR_MODULE_DESCRIPTION          #language en-US "Provides basic timer support for RISC-V."\r
+\r
diff --git a/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c b/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c
new file mode 100644 (file)
index 0000000..9c8efc0
--- /dev/null
@@ -0,0 +1,199 @@
+/** @file\r
+  RISC-V instance of Timer Library.\r
+\r
+  Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Register/RiscV64/RiscVImpl.h>\r
+\r
+/**\r
+  Stalls the CPU for at least the given number of ticks.\r
+\r
+  Stalls the CPU for at least the given number of ticks. It's invoked by\r
+  MicroSecondDelay() and NanoSecondDelay().\r
+\r
+  @param  Delay     A period of time to delay in ticks.\r
+\r
+**/\r
+VOID\r
+InternalRiscVTimerDelay (\r
+  IN UINT32  Delay\r
+  )\r
+{\r
+  UINT32  Ticks;\r
+  UINT32  Times;\r
+\r
+  Times  = Delay >> (RISCV_TIMER_COMPARE_BITS - 2);\r
+  Delay &= ((1 << (RISCV_TIMER_COMPARE_BITS - 2)) - 1);\r
+  do {\r
+    //\r
+    // The target timer count is calculated here\r
+    //\r
+    Ticks = RiscVReadTimer () + Delay;\r
+    Delay = 1 << (RISCV_TIMER_COMPARE_BITS - 2);\r
+    while (((Ticks - RiscVReadTimer ()) & (1 << (RISCV_TIMER_COMPARE_BITS - 1))) == 0) {\r
+      CpuPause ();\r
+    }\r
+  } while (Times-- > 0);\r
+}\r
+\r
+/**\r
+  Stalls the CPU for at least the given number of microseconds.\r
+\r
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.\r
+\r
+  @param  MicroSeconds  The minimum number of microseconds to delay.\r
+\r
+  @return MicroSeconds\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+MicroSecondDelay (\r
+  IN UINTN  MicroSeconds\r
+  )\r
+{\r
+  InternalRiscVTimerDelay (\r
+    (UINT32)DivU64x32 (\r
+              MultU64x32 (\r
+                MicroSeconds,\r
+                PcdGet64 (PcdCpuCoreCrystalClockFrequency)\r
+                ),\r
+              1000000u\r
+              )\r
+    );\r
+  return MicroSeconds;\r
+}\r
+\r
+/**\r
+  Stalls the CPU for at least the given number of nanoseconds.\r
+\r
+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.\r
+\r
+  @param  NanoSeconds The minimum number of nanoseconds to delay.\r
+\r
+  @return NanoSeconds\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+NanoSecondDelay (\r
+  IN UINTN  NanoSeconds\r
+  )\r
+{\r
+  InternalRiscVTimerDelay (\r
+    (UINT32)DivU64x32 (\r
+              MultU64x32 (\r
+                NanoSeconds,\r
+                PcdGet64 (PcdCpuCoreCrystalClockFrequency)\r
+                ),\r
+              1000000000u\r
+              )\r
+    );\r
+  return NanoSeconds;\r
+}\r
+\r
+/**\r
+  Retrieves the current value of a 64-bit free running performance counter.\r
+\r
+  Retrieves the current value of a 64-bit free running performance counter. The\r
+  counter can either count up by 1 or count down by 1. If the physical\r
+  performance counter counts by a larger increment, then the counter values\r
+  must be translated. The properties of the counter can be retrieved from\r
+  GetPerformanceCounterProperties().\r
+\r
+  @return The current value of the free running performance counter.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+GetPerformanceCounter (\r
+  VOID\r
+  )\r
+{\r
+  return (UINT64)RiscVReadTimer ();\r
+}\r
+\r
+/**return\r
+  Retrieves the 64-bit frequency in Hz and the range of performance counter\r
+  values.\r
+\r
+  If StartValue is not NULL, then the value that the performance counter starts\r
+  with immediately after is it rolls over is returned in StartValue. If\r
+  EndValue is not NULL, then the value that the performance counter end with\r
+  immediately before it rolls over is returned in EndValue. The 64-bit\r
+  frequency of the performance counter in Hz is always returned. If StartValue\r
+  is less than EndValue, then the performance counter counts up. If StartValue\r
+  is greater than EndValue, then the performance counter counts down. For\r
+  example, a 64-bit free running counter that counts up would have a StartValue\r
+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter\r
+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.\r
+\r
+  @param  StartValue  The value the performance counter starts with when it\r
+                      rolls over.\r
+  @param  EndValue    The value that the performance counter ends with before\r
+                      it rolls over.\r
+\r
+  @return The frequency in Hz.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+GetPerformanceCounterProperties (\r
+  OUT      UINT64 *StartValue, OPTIONAL\r
+  OUT      UINT64                    *EndValue     OPTIONAL\r
+  )\r
+{\r
+  if (StartValue != NULL) {\r
+    *StartValue = 0;\r
+  }\r
+\r
+  if (EndValue != NULL) {\r
+    *EndValue = 32 - 1;\r
+  }\r
+\r
+  return PcdGet64 (PcdCpuCoreCrystalClockFrequency);\r
+}\r
+\r
+/**\r
+  Converts elapsed ticks of performance counter to time in nanoseconds.\r
+\r
+  This function converts the elapsed ticks of running performance counter to\r
+  time value in unit of nanoseconds.\r
+\r
+  @param  Ticks     The number of elapsed ticks of running performance counter.\r
+\r
+  @return The elapsed time in nanoseconds.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+GetTimeInNanoSecond (\r
+  IN      UINT64  Ticks\r
+  )\r
+{\r
+  UINT64  NanoSeconds;\r
+  UINT32  Remainder;\r
+\r
+  //\r
+  //          Ticks\r
+  // Time = --------- x 1,000,000,000\r
+  //        Frequency\r
+  //\r
+  NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, PcdGet64 (PcdCpuCoreCrystalClockFrequency), &Remainder), 1000000000u);\r
+\r
+  //\r
+  // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)\r
+  // will not overflow 64-bit.\r
+  //\r
+  NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder, 1000000000u), PcdGet64 (PcdCpuCoreCrystalClockFrequency));\r
+\r
+  return NanoSeconds;\r
+}\r
index 35e66d93efa6646341c788a6c82574ae01aa6b47..c511403842b8f88ca0ec23908b85be3a78b8830f 100644 (file)
 \r
 [Components.RISCV64]\r
   UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf\r
+  UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/BaseRiscV64CpuTimerLib.inf\r
 \r
 [BuildOptions]\r
   *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES\r