]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmulatorPkg/Library/PeiTimerLib/PeiTimerLib.c
EmulatorPkg/TimerLib: Add missing GetTimeInNanoSecond function
[mirror_edk2.git] / EmulatorPkg / Library / PeiTimerLib / PeiTimerLib.c
index cce46fb366e185e3559d56d68759c85cea2987bf..132abb2c04c0ae6d4d0b3bec92939d2a2b9d42cf 100644 (file)
@@ -1,12 +1,13 @@
 /** @file\r
   A non-functional instance of the Timer Library.\r
 \r
-  Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>\r
   SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include <PiPei.h>\r
+#include <Library/BaseLib.h>\r
 #include <Library/TimerLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/PeiServicesLib.h>\r
@@ -166,3 +167,47 @@ GetPerformanceCounterProperties (
 \r
   return 0;\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  Frequency;\r
+  UINT64  NanoSeconds;\r
+  UINT64  Remainder;\r
+  INTN    Shift;\r
+\r
+  Frequency = GetPerformanceCounterProperties (NULL, NULL);\r
+\r
+  //\r
+  //          Ticks\r
+  // Time = --------- x 1,000,000,000\r
+  //        Frequency\r
+  //\r
+  NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u);\r
+\r
+  //\r
+  // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.\r
+  // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34,\r
+  // i.e. highest bit set in Remainder should <= 33.\r
+  //\r
+  Shift = MAX (0, HighBitSet64 (Remainder) - 33);\r
+  Remainder = RShiftU64 (Remainder, (UINTN) Shift);\r
+  Frequency = RShiftU64 (Frequency, (UINTN) Shift);\r
+  NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL);\r
+\r
+  return NanoSeconds;\r
+}\r