mirror of https://github.com/acidanthera/audk.git
Removed the assumption on APIC timer initial Count is all 1s and updated it to handle the long delay that timer initial count.
Signed-off-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14604 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
3eb695cfb7
commit
253fcc8bdc
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
This library uses the local APIC library so that it supports x2APIC mode.
|
This library uses the local APIC library so that it supports x2APIC mode.
|
||||||
|
|
||||||
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -55,22 +55,49 @@ InternalX86Delay (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
INT32 Ticks;
|
INT32 Ticks;
|
||||||
UINT32 PowerOfTwoCounter;
|
UINT32 Times;
|
||||||
|
UINT32 InitCount;
|
||||||
|
UINT32 StartTick;
|
||||||
|
|
||||||
//
|
//
|
||||||
// The target timer count is calculated here
|
// 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.
|
||||||
//
|
//
|
||||||
Ticks = GetApicTimerCurrentCount () - Delay;
|
InitCount = GetApicTimerInitCount ();
|
||||||
|
Times = Delay / (InitCount / 2);
|
||||||
|
Delay = Delay % (InitCount / 2);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Wait until time out
|
// Get Start Tick and do delay
|
||||||
// Delay > 2^31 could not be handled by this function
|
|
||||||
// Timer wrap-arounds are handled correctly by this function
|
|
||||||
//
|
//
|
||||||
PowerOfTwoCounter = GetPowerOfTwo32 (GetApicTimerInitCount ());
|
StartTick = GetApicTimerCurrentCount ();
|
||||||
while (((UINT32)(GetApicTimerCurrentCount () - Ticks) & PowerOfTwoCounter) == 0) {
|
do {
|
||||||
CpuPause ();
|
//
|
||||||
}
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -181,10 +208,6 @@ GetPerformanceCounterProperties (
|
||||||
{
|
{
|
||||||
if (StartValue != NULL) {
|
if (StartValue != NULL) {
|
||||||
*StartValue = (UINT64)GetApicTimerInitCount ();
|
*StartValue = (UINT64)GetApicTimerInitCount ();
|
||||||
//
|
|
||||||
// make sure StartValue is all 1s from High Bit
|
|
||||||
//
|
|
||||||
ASSERT ((*StartValue & (*StartValue + 1)) == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EndValue != NULL) {
|
if (EndValue != NULL) {
|
||||||
|
|
Loading…
Reference in New Issue