Fix an off-by-one error in AcpiGetTimerDuration().

Delta calculation has an off-by-one error when there is a rollover.
For example, when StartTicks is 0x00FFFFFF and EndTicks is 0x00000000
(for 24-bit timer), DeltaTicks should be 1 (one) but it was 0 (zero).
This commit is contained in:
Jung-uk Kim 2017-08-31 18:10:53 -04:00
parent faa9fdfbd0
commit b4fd33f3c2

View File

@ -283,7 +283,7 @@ AcpiGetTimerDuration (
UINT32 *TimeElapsed)
{
ACPI_STATUS Status;
UINT32 DeltaTicks;
UINT64 DeltaTicks;
UINT64 Quotient;
@ -302,34 +302,33 @@ AcpiGetTimerDuration (
return_ACPI_STATUS (AE_SUPPORT);
}
if (StartTicks == EndTicks)
{
*TimeElapsed = 0;
return_ACPI_STATUS (AE_OK);
}
/*
* Compute Tick Delta:
* Handle (max one) timer rollovers on 24-bit versus 32-bit timers.
*/
if (StartTicks < EndTicks)
{
DeltaTicks = EndTicks - StartTicks;
}
else if (StartTicks > EndTicks)
DeltaTicks = EndTicks;
if (StartTicks > EndTicks)
{
if ((AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER) == 0)
{
/* 24-bit Timer */
DeltaTicks = (((0x00FFFFFF - StartTicks) + EndTicks) & 0x00FFFFFF);
DeltaTicks |= (UINT64) 1 << 24;
}
else
{
/* 32-bit Timer */
DeltaTicks = (0xFFFFFFFF - StartTicks) + EndTicks;
DeltaTicks |= (UINT64) 1 << 32;
}
}
else /* StartTicks == EndTicks */
{
*TimeElapsed = 0;
return_ACPI_STATUS (AE_OK);
}
DeltaTicks -= StartTicks;
/*
* Compute Duration (Requires a 64-bit multiply and divide):
@ -337,7 +336,7 @@ AcpiGetTimerDuration (
* TimeElapsed (microseconds) =
* (DeltaTicks * ACPI_USEC_PER_SEC) / ACPI_PM_TIMER_FREQUENCY;
*/
Status = AcpiUtShortDivide (((UINT64) DeltaTicks) * ACPI_USEC_PER_SEC,
Status = AcpiUtShortDivide (DeltaTicks * ACPI_USEC_PER_SEC,
ACPI_PM_TIMER_FREQUENCY, &Quotient, NULL);
*TimeElapsed = (UINT32) Quotient;