aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64
diff options
context:
space:
mode:
authorDavid P. Reed <dpreed@reed.com>2007-05-02 13:27:20 -0400
committerAndi Kleen <andi@basil.nowhere.org>2007-05-02 13:27:20 -0400
commit4637a74cf2ac3a3696d385c8624d84de789d1bbe (patch)
tree358cd844b60771697d8cff6b85c5ab7db4b96deb /arch/x86_64
parent9d016dd43b8df0228f1022f483f582eeb52d256e (diff)
[PATCH] x86-64: Avoid overflows during apic timer calibration
- Use 64bit TSC calculations to avoid handling overflow - Use 32bit unsigned arithmetic for the APIC timer. This way overflows are handled correctly. - Fix exit check of loop to account for apic timer counting down Signed-off-by: dpreed@reed.com Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/kernel/apic.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 943ec4d1bd8e..d198f7d82e5a 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -839,14 +839,15 @@ static void setup_APIC_timer(unsigned int clocks)
839 839
840static int __init calibrate_APIC_clock(void) 840static int __init calibrate_APIC_clock(void)
841{ 841{
842 int apic, apic_start, tsc, tsc_start; 842 unsigned apic, apic_start;
843 unsigned long tsc, tsc_start;
843 int result; 844 int result;
844 /* 845 /*
845 * Put whatever arbitrary (but long enough) timeout 846 * Put whatever arbitrary (but long enough) timeout
846 * value into the APIC clock, we just want to get the 847 * value into the APIC clock, we just want to get the
847 * counter running for calibration. 848 * counter running for calibration.
848 */ 849 */
849 __setup_APIC_LVTT(1000000000); 850 __setup_APIC_LVTT(4000000000);
850 851
851 apic_start = apic_read(APIC_TMCCT); 852 apic_start = apic_read(APIC_TMCCT);
852#ifdef CONFIG_X86_PM_TIMER 853#ifdef CONFIG_X86_PM_TIMER
@@ -857,13 +858,13 @@ static int __init calibrate_APIC_clock(void)
857 } else 858 } else
858#endif 859#endif
859 { 860 {
860 rdtscl(tsc_start); 861 rdtscll(tsc_start);
861 862
862 do { 863 do {
863 apic = apic_read(APIC_TMCCT); 864 apic = apic_read(APIC_TMCCT);
864 rdtscl(tsc); 865 rdtscll(tsc);
865 } while ((tsc - tsc_start) < TICK_COUNT && 866 } while ((tsc - tsc_start) < TICK_COUNT &&
866 (apic - apic_start) < TICK_COUNT); 867 (apic_start - apic) < TICK_COUNT);
867 868
868 result = (apic_start - apic) * 1000L * tsc_khz / 869 result = (apic_start - apic) * 1000L * tsc_khz /
869 (tsc - tsc_start); 870 (tsc - tsc_start);