]> 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 caf8a7c14a02266a92f487bbd918eacf242f6fb7..132abb2c04c0ae6d4d0b3bec92939d2a2b9d42cf 100644 (file)
@@ -1,18 +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
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php.\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\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
@@ -60,7 +55,7 @@ NanoSecondDelay (
   EMU_THUNK_PROTOCOL      *Thunk;\r
 \r
   //\r
-  // Locate EmuThunkPpi for \r
+  // Locate EmuThunkPpi for\r
   //\r
   Status = PeiServicesLocatePpi (\r
               &gEmuThunkPpiGuid,\r
@@ -68,7 +63,7 @@ NanoSecondDelay (
               NULL,\r
               (VOID **) &ThunkPpi\r
              );\r
-  if (!EFI_ERROR (Status)) {   \r
+  if (!EFI_ERROR (Status)) {\r
     Thunk  = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk ();\r
     Thunk->Sleep (NanoSeconds * 100);\r
     return NanoSeconds;\r
@@ -99,7 +94,7 @@ GetPerformanceCounter (
   EMU_THUNK_PROTOCOL      *Thunk;\r
 \r
   //\r
-  // Locate EmuThunkPpi for \r
+  // Locate EmuThunkPpi for\r
   //\r
   Status = PeiServicesLocatePpi (\r
               &gEmuThunkPpiGuid,\r
@@ -107,7 +102,7 @@ GetPerformanceCounter (
               NULL,\r
               (VOID **) &ThunkPpi\r
              );\r
-  if (!EFI_ERROR (Status)) {   \r
+  if (!EFI_ERROR (Status)) {\r
     Thunk  = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk ();\r
     return  Thunk->QueryPerformanceCounter ();\r
   }\r
@@ -150,7 +145,7 @@ GetPerformanceCounterProperties (
   EMU_THUNK_PROTOCOL      *Thunk;\r
 \r
   //\r
-  // Locate EmuThunkPpi for \r
+  // Locate EmuThunkPpi for\r
   //\r
   Status = PeiServicesLocatePpi (\r
               &gEmuThunkPpiGuid,\r
@@ -165,10 +160,54 @@ GetPerformanceCounterProperties (
     if (EndValue != NULL) {\r
       *EndValue = (UINT64)-1LL;\r
     }\r
-    \r
+\r
     Thunk  = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk ();\r
     return  Thunk->QueryPerformanceFrequency ();\r
   }\r
 \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