/** Stalls the CPU for at least the given number of ticks. Stalls the CPU for at least the given number of ticks. It's invoked by MicroSecondDelay() and NanoSecondDelay(). @param Delay A period of time to delay in ticks. **/ VOID EFIAPI InternalX86Delay ( IN UINT32 Delay ) { INT32 Ticks; UINT32 Times; UINT32 InitCount; UINT32 StartTick; // // In case Delay is too larger, separate it into several small delay slot. // Devided Delay by half value of Init Count is to avoid Delay close to // the Init Count, timeout maybe missing if the time consuming between 2 // GetApicTimerCurrentCount() invoking is larger than the time gap between // Delay and the Init Count. // InitCount = GetApicTimerInitCount (); Times = Delay / (InitCount / 2); Delay = Delay % (InitCount / 2); // // Get Start Tick and do delay // StartTick = GetApicTimerCurrentCount (); do { // // Wait until time out by Delay value // do { CpuPause (); // // Get Ticks from Start to Current. // Ticks = StartTick - GetApicTimerCurrentCount (); // // Ticks < 0 means Timer wrap-arounds happens. // if (Ticks < 0) { Ticks += InitCount; } } while ((UINT32)Ticks < Delay); // // Update StartTick and Delay for next delay slot // StartTick -= (StartTick > Delay) ? Delay : (Delay - InitCount); Delay = InitCount / 2; } while (Times-- > 0); }
/** Stalls the CPU for at least the given number of ticks. Stalls the CPU for at least the given number of ticks. It's invoked by MicroSecondDelay() and NanoSecondDelay(). @param Delay A period of time to delay in ticks. **/ VOID EFIAPI InternalX86Delay ( IN UINT32 Delay ) { INT32 Ticks; UINT32 Times; UINT32 InitCount; UINT32 StartTick; BOOLEAN IsOverTurn; // // The target timer count is calculated here // InitCount = GetApicTimerInitCount (); Times = Delay / InitCount; Delay = Delay % InitCount; do { // // Get Start Tick // IsOverTurn = FALSE; StartTick = GetApicTimerCurrentCount (); // // Wait until time out // do { CpuPause (); // // Get Ticks from Start to Current. // Ticks = StartTick - GetApicTimerCurrentCount (); // // Ticks < 0 means OverTurn happens. // if (Ticks < 0 || IsOverTurn) { Ticks += InitCount; IsOverTurn = TRUE; } } while ((UINT32) Ticks <= Delay); // // Wait next round Delay // Delay = InitCount; } while (Times-- > 0); }
/** Check if the timer is time out. @param[in] TimerCycle Timer initial count. @param[in] Timer The start timer from the begin. @param[in] TimeoutTicker Ticker number need time out. @return TRUE Timer time out occurs. @retval FALSE Timer does not time out. **/ BOOLEAN IsDebugTimerTimeout ( IN UINT32 TimerCycle, IN UINT32 Timer, IN UINT32 TimeoutTicker ) { UINT64 CurrentTimer; UINT64 Delta; CurrentTimer = GetApicTimerCurrentCount (); // // This timer counter counts down. Check for roll over condition. // If CurrentTimer is equal to Timer, it does not mean that roll over // happened. // if (CurrentTimer <= Timer) { Delta = Timer - CurrentTimer; } else { // // Handle one roll-over. // Delta = TimerCycle - (CurrentTimer - Timer) + 1; } return (BOOLEAN) (Delta >= TimeoutTicker); }
/** Check if the timer is time out. @param[in] TimerCycle Timer total count. @param[in] Timer The start timer from the begin. @param[in] TimeoutTicker Ticker number need time out. @return TRUE Timer time out occurs. @retval FALSE Timer does not time out. **/ BOOLEAN IsDebugTimerTimeout ( IN UINT32 TimerCycle, IN UINT32 Timer, IN UINT32 TimeoutTicker ) { UINT64 CurrentTimer; UINT64 Delta; CurrentTimer = GetApicTimerCurrentCount (); // // This timer counter counts down. Check for roll over condition. // if (CurrentTimer < Timer) { Delta = Timer - CurrentTimer; } else { // // Handle one roll-over. // Delta = TimerCycle - (CurrentTimer - Timer); } return (BOOLEAN) (Delta >= TimeoutTicker); }
/** Retrieves the current value of a 64-bit free running performance counter. The counter can either count up by 1 or count down by 1. If the physical performance counter counts by a larger increment, then the counter values must be translated. The properties of the counter can be retrieved from GetPerformanceCounterProperties(). @return The current value of the free running performance counter. **/ UINT64 EFIAPI GetPerformanceCounter ( VOID ) { return (UINT64)GetApicTimerCurrentCount (); }