PcAtChipsetPkg AcpiTimerLib: Get more accurate TSC Frequency
Minimize the code overhead between the two TSC reads by adding new internal API to calculate TSC Frequency instead of reusing MicroSecondDelay (). Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Liming Gao <liming.gao@intel.com> Cc: Paul A Lohr <paul.a.lohr@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
ACPI Timer implements one instance of Timer Library.
|
||||
|
||||
Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
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
|
||||
@@ -16,6 +16,26 @@
|
||||
#include <Library/TimerLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
|
||||
/**
|
||||
Calculate TSC frequency.
|
||||
|
||||
The TSC counting frequency is determined by comparing how far it counts
|
||||
during a 100us period as determined by the ACPI timer. The ACPI timer is
|
||||
used because it counts at a known frequency.
|
||||
The TSC is sampled, followed by waiting for ACPI_TIMER_FREQUENCY / 10000
|
||||
clocks of the ACPI timer, or 100us. The TSC is then sampled again. The
|
||||
difference multiplied by 10000 is the TSC frequency. There will be a small
|
||||
error because of the overhead of reading the ACPI timer. An attempt is
|
||||
made to determine and compensate for this error.
|
||||
|
||||
@return The number of TSC counts per second.
|
||||
|
||||
**/
|
||||
UINT64
|
||||
InternalCalculateTscFrequency (
|
||||
VOID
|
||||
);
|
||||
|
||||
//
|
||||
// Cached performance counter frequency
|
||||
//
|
||||
@@ -34,15 +54,8 @@ InternalGetPerformanceCounterFrequency (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
BOOLEAN InterruptState;
|
||||
UINT64 Count;
|
||||
|
||||
if (mPerformanceCounterFrequency == 0) {
|
||||
InterruptState = SaveAndDisableInterrupts ();
|
||||
Count = GetPerformanceCounter ();
|
||||
MicroSecondDelay (100);
|
||||
mPerformanceCounterFrequency = MultU64x32 (GetPerformanceCounter () - Count, 10000);
|
||||
SetInterruptState (InterruptState);
|
||||
mPerformanceCounterFrequency = InternalCalculateTscFrequency ();
|
||||
}
|
||||
return mPerformanceCounterFrequency;
|
||||
}
|
||||
|
Reference in New Issue
Block a user