X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdePkg%2FLibrary%2FBaseTimerLibLocalApic%2FIpf%2FIpfTimerLib.c;h=65b58bc54945ec96ff2187c5ad50020505ef2fcf;hp=652cc7e6e49a4f1b22e8efb60821a27c6b693bcf;hb=3401c092e4e98b97bcf86d9aa2500d5ee7b3b8cf;hpb=878ddf1fc3540a715f63594ed22b6929e881afb4 diff --git a/MdePkg/Library/BaseTimerLibLocalApic/Ipf/IpfTimerLib.c b/MdePkg/Library/BaseTimerLibLocalApic/Ipf/IpfTimerLib.c index 652cc7e6e4..65b58bc549 100644 --- a/MdePkg/Library/BaseTimerLibLocalApic/Ipf/IpfTimerLib.c +++ b/MdePkg/Library/BaseTimerLibLocalApic/Ipf/IpfTimerLib.c @@ -18,25 +18,38 @@ **/ -UINT64 -ReadItc ( - VOID - ); - -typedef struct { - UINT64 Status; - UINT64 r9; - UINT64 r10; - UINT64 r11; -} PAL_PROC_RETURN; - -PAL_PROC_RETURN -CallPalProcStatic ( - IN UINT64 Arg1, - IN UINT64 Arg2, - IN UINT64 Arg3, - IN UINT64 Arg4 - ); + + + +/** + Performs a delay measured as number of ticks. + + An internal function to perform a delay measured as number of ticks. It's + invoked by MicroSecondDelay() and NanoSecondDelay(). + + @param Delay Number of ticks to delay. + +**/ +STATIC +VOID +InternalIpfDelay ( + IN INT64 Delay + ) +{ + INT64 Ticks; + + // + // The target timer count is calculated here + // + Ticks = IpfReadItc () + Delay; + + // + // Wait until time out + // Delay > 2^63 could not be handled by this function + // Timer wrap-arounds are handled correctly by this function + // + while (Ticks - IpfReadItc () >= 0); +} /** Stalls the CPU for at least the given number of microseconds. @@ -45,7 +58,7 @@ CallPalProcStatic ( @param MicroSeconds The minimum number of microseconds to delay. - @return The ticks delayed actually. + @return MicroSeconds **/ UINTN @@ -54,13 +67,12 @@ MicroSecondDelay ( IN UINTN MicroSeconds ) { - UINT64 Ticks; - UINT64 Delay; - - Ticks = GetPerformanceCounter (); - Delay = GetPerformanceCounterProperties (NULL, NULL) * MicroSeconds / 1000000; - while (Ticks + Delay < GetPerformanceCounter ()); - return (UINTN)Delay; + InternalIpfDelay ( + GetPerformanceCounterProperties (NULL, NULL) * + MicroSeconds / + 1000000 + ); + return MicroSeconds; } /** @@ -70,7 +82,7 @@ MicroSecondDelay ( @param NanoSeconds The minimum number of nanoseconds to delay. - @return The ticks delayed actually. + @return NanoSeconds **/ UINTN @@ -79,13 +91,12 @@ NanoSecondDelay ( IN UINTN NanoSeconds ) { - UINT64 Ticks; - UINT64 Delay; - - Ticks = GetPerformanceCounter (); - Delay = GetPerformanceCounterProperties (NULL, NULL) * NanoSeconds / 1000000000; - while (Ticks + Delay < GetPerformanceCounter ()); - return (UINTN)Delay; + InternalIpfDelay ( + GetPerformanceCounterProperties (NULL, NULL) * + NanoSeconds / + 1000000000 + ); + return NanoSeconds; } /** @@ -106,7 +117,7 @@ GetPerformanceCounter ( VOID ) { - return ReadItc (); + return IpfReadItc (); } /** @@ -135,21 +146,27 @@ GetPerformanceCounter ( UINT64 EFIAPI GetPerformanceCounterProperties ( - IN UINT64 *StartValue, - IN UINT64 *EndValue + OUT UINT64 *StartValue, OPTIONAL + OUT UINT64 *EndValue OPTIONAL ) { PAL_PROC_RETURN PalRet; UINT64 BaseFrequence; - PalRet = CallPalProcStatic (13, 0, 0, 0); + PalRet = PalCallStatic (NULL, 13, 0, 0, 0); ASSERT (PalRet.Status == 0); BaseFrequence = PalRet.r9; - PalRet = CallPalProcStatic (14, 0, 0, 0); + PalRet = PalCallStatic (NULL, 14, 0, 0, 0); ASSERT (PalRet.Status == 0); - *StartValue = 0; - *EndValue = (UINT64)(-1); + if (StartValue != NULL) { + *StartValue = 0; + } + + if (EndValue != NULL) { + *EndValue = (UINT64)(-1); + } + return BaseFrequence * (PalRet.r11 >> 32) / (UINT32)PalRet.r11; }