From 16a48731fcbf658569571490cbcc46df8d254bb7 Mon Sep 17 00:00:00 2001 From: xdu2 Date: Thu, 8 Sep 2011 01:34:24 +0000 Subject: [PATCH] MdePkg: Add missing implementation of GetTimeInNanoSecond() to TimerLib library instance DxeTimerLibEsal. Signed-off-by: xdu2 Reviewed-by: mdkinney git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12297 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Library/DxeTimerLibEsal/DxeTimerLibEsal.c | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.c b/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.c index 964f814bb2..8ca3ec6f8b 100644 --- a/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.c +++ b/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.c @@ -177,3 +177,47 @@ GetPerformanceCounterProperties ( return BaseFrequence * (PalRet.r11 >> 32) / (UINT32)PalRet.r11; } + +/** + 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 Frequency; + UINT64 NanoSeconds; + UINT64 Remainder; + INTN Shift; + + Frequency = GetPerformanceCounterProperties (NULL, NULL); + + // + // Ticks + // Time = --------- x 1,000,000,000 + // Frequency + // + NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u); + + // + // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit. + // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34, + // i.e. highest bit set in Remainder should <= 33. + // + Shift = MAX (0, HighBitSet64 (Remainder) - 33); + Remainder = RShiftU64 (Remainder, (UINTN) Shift); + Frequency = RShiftU64 (Frequency, (UINTN) Shift); + NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL); + + return NanoSeconds; +}