X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdePkg%2FLibrary%2FBaseTimerLibLocalApic%2FIpf%2FIpfTimerLib.c;h=65b58bc54945ec96ff2187c5ad50020505ef2fcf;hp=3814534607d924913f90021c0a3281223a804668;hb=cd4903c497c9ace4016efb340d6e9cfd561a9833;hpb=e65e8d103dbadc85c3fe3cce50cd98069a75e72f diff --git a/MdePkg/Library/BaseTimerLibLocalApic/Ipf/IpfTimerLib.c b/MdePkg/Library/BaseTimerLibLocalApic/Ipf/IpfTimerLib.c index 3814534607..65b58bc549 100644 --- a/MdePkg/Library/BaseTimerLibLocalApic/Ipf/IpfTimerLib.c +++ b/MdePkg/Library/BaseTimerLibLocalApic/Ipf/IpfTimerLib.c @@ -18,26 +18,38 @@ **/ -UINT64 -ReadItc ( - VOID - ); - -typedef struct { - UINT64 Status; - UINT64 r9; - UINT64 r10; - UINT64 r11; -} PAL_PROC_RETURN; - -PAL_PROC_RETURN -PalCallStatic ( - IN CONST VOID *PalEntryPoint, - 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. @@ -46,7 +58,7 @@ PalCallStatic ( @param MicroSeconds The minimum number of microseconds to delay. - @return The ticks delayed actually. + @return MicroSeconds **/ UINTN @@ -55,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; } /** @@ -71,7 +82,7 @@ MicroSecondDelay ( @param NanoSeconds The minimum number of nanoseconds to delay. - @return The ticks delayed actually. + @return NanoSeconds **/ UINTN @@ -80,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; } /** @@ -107,7 +117,7 @@ GetPerformanceCounter ( VOID ) { - return ReadItc (); + return IpfReadItc (); } /** @@ -136,8 +146,8 @@ GetPerformanceCounter ( UINT64 EFIAPI GetPerformanceCounterProperties ( - IN UINT64 *StartValue, - IN UINT64 *EndValue + OUT UINT64 *StartValue, OPTIONAL + OUT UINT64 *EndValue OPTIONAL ) { PAL_PROC_RETURN PalRet; @@ -150,7 +160,13 @@ GetPerformanceCounterProperties ( 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; }