diff options
author | Jan Beulich <JBeulich@novell.com> | 2005-06-23 03:08:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-23 12:45:09 -0400 |
commit | 7fbb4f6e6873593a2defb8f66512f55d08d88106 (patch) | |
tree | 7946f3ca697a5981d4599162572201213f3782f5 /arch/i386 | |
parent | ca05fea6db5259c6d62e517c41d448a4249175f4 (diff) |
[PATCH] adjust i386 watchdog tick calculation
Get the i386 watchdog tick calculation into a state where it can also be used
on CPUs with frequencies beyond 4GHz, and it consolidates the calculation into
a single place (for potential furture adjustments).
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/kernel/nmi.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 2c0ee9c2d020..da6c46d667cb 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c | |||
@@ -28,8 +28,7 @@ | |||
28 | #include <linux/sysctl.h> | 28 | #include <linux/sysctl.h> |
29 | 29 | ||
30 | #include <asm/smp.h> | 30 | #include <asm/smp.h> |
31 | #include <asm/mtrr.h> | 31 | #include <asm/div64.h> |
32 | #include <asm/mpspec.h> | ||
33 | #include <asm/nmi.h> | 32 | #include <asm/nmi.h> |
34 | 33 | ||
35 | #include "mach_traps.h" | 34 | #include "mach_traps.h" |
@@ -324,6 +323,16 @@ static void clear_msr_range(unsigned int base, unsigned int n) | |||
324 | wrmsr(base+i, 0, 0); | 323 | wrmsr(base+i, 0, 0); |
325 | } | 324 | } |
326 | 325 | ||
326 | static inline void write_watchdog_counter(const char *descr) | ||
327 | { | ||
328 | u64 count = (u64)cpu_khz * 1000; | ||
329 | |||
330 | do_div(count, nmi_hz); | ||
331 | if(descr) | ||
332 | Dprintk("setting %s to -0x%08Lx\n", descr, count); | ||
333 | wrmsrl(nmi_perfctr_msr, 0 - count); | ||
334 | } | ||
335 | |||
327 | static void setup_k7_watchdog(void) | 336 | static void setup_k7_watchdog(void) |
328 | { | 337 | { |
329 | unsigned int evntsel; | 338 | unsigned int evntsel; |
@@ -339,8 +348,7 @@ static void setup_k7_watchdog(void) | |||
339 | | K7_NMI_EVENT; | 348 | | K7_NMI_EVENT; |
340 | 349 | ||
341 | wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); | 350 | wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); |
342 | Dprintk("setting K7_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000)); | 351 | write_watchdog_counter("K7_PERFCTR0"); |
343 | wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1); | ||
344 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 352 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
345 | evntsel |= K7_EVNTSEL_ENABLE; | 353 | evntsel |= K7_EVNTSEL_ENABLE; |
346 | wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); | 354 | wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); |
@@ -361,8 +369,7 @@ static void setup_p6_watchdog(void) | |||
361 | | P6_NMI_EVENT; | 369 | | P6_NMI_EVENT; |
362 | 370 | ||
363 | wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); | 371 | wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); |
364 | Dprintk("setting P6_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000)); | 372 | write_watchdog_counter("P6_PERFCTR0"); |
365 | wrmsr(MSR_P6_PERFCTR0, -(cpu_khz/nmi_hz*1000), 0); | ||
366 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 373 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
367 | evntsel |= P6_EVNTSEL0_ENABLE; | 374 | evntsel |= P6_EVNTSEL0_ENABLE; |
368 | wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); | 375 | wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); |
@@ -402,8 +409,7 @@ static int setup_p4_watchdog(void) | |||
402 | 409 | ||
403 | wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0); | 410 | wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0); |
404 | wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0); | 411 | wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0); |
405 | Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz/nmi_hz*1000)); | 412 | write_watchdog_counter("P4_IQ_COUNTER0"); |
406 | wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1); | ||
407 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 413 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
408 | wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); | 414 | wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); |
409 | return 1; | 415 | return 1; |
@@ -518,7 +524,7 @@ void nmi_watchdog_tick (struct pt_regs * regs) | |||
518 | * other P6 variant */ | 524 | * other P6 variant */ |
519 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 525 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
520 | } | 526 | } |
521 | wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1); | 527 | write_watchdog_counter(NULL); |
522 | } | 528 | } |
523 | } | 529 | } |
524 | 530 | ||