Commit 1eb6e582 authored by James Bottomley's avatar James Bottomley

More Separation

- add do_timer_overflow() function for coping with tick overflow
- make find_smp_config() gated by its own define
- bug fixes and corrections
parent 3736e29e
...@@ -418,7 +418,8 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then ...@@ -418,7 +418,8 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
fi fi
if [ "$CONFIG_X86_LOCAL_APIC" = "y" ]; then if [ "$CONFIG_X86_LOCAL_APIC" = "y" ]; then
define_bool CONFIG_X86_EXTRA_IRQS y define_bool CONFIG_X86_EXTRA_IRQS y
define_bool CONFIG_X86_FIND_SMP_CONFIG y
fi fi
endmenu endmenu
...@@ -426,8 +427,8 @@ endmenu ...@@ -426,8 +427,8 @@ endmenu
source lib/Config.in source lib/Config.in
if [ "$CONFIG_SMP" = "y" ]; then if [ "$CONFIG_SMP" = "y" ]; then
define_bool CONFIG_X86_SMP y define_bool CONFIG_X86_SMP y
define_bool CONFIG_X86_HT y define_bool CONFIG_X86_HT y
fi fi
define_bool CONFIG_X86_BIOS_REBOOT y define_bool CONFIG_X86_BIOS_REBOOT y
...@@ -16,3 +16,46 @@ static inline void do_timer_interrupt_hook(struct pt_regs *regs) ...@@ -16,3 +16,46 @@ static inline void do_timer_interrupt_hook(struct pt_regs *regs)
smp_local_timer_interrupt(regs); smp_local_timer_interrupt(regs);
#endif #endif
} }
/* you can safely undefine this if you don't have the Neptune chipset */
#define BUGGY_NEPTUN_TIMER
static inline int do_timer_overflow(int count)
{
int i;
spin_lock(&i8259A_lock);
/*
* This is tricky when I/O APICs are used;
* see do_timer_interrupt().
*/
i = inb(0x20);
spin_unlock(&i8259A_lock);
/* assumption about timer being IRQ0 */
if (i & 0x01) {
/*
* We cannot detect lost timer interrupts ...
* well, that's why we call them lost, don't we? :)
* [hmm, on the Pentium and Alpha we can ... sort of]
*/
count -= LATCH;
} else {
#ifdef BUGGY_NEPTUN_TIMER
/*
* for the Neptun bug we know that the 'latch'
* command doesnt latch the high and low value
* of the counter atomically. Thus we have to
* substract 256 from the counter
* ... funny, isnt it? :)
*/
count -= 256;
#else
printk("do_slow_gettimeoffset(): hardware timer problem?\n");
#endif
}
return count;
}
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/arch_hooks.h>
/* This structure holds MCA information. Each (plug-in) adapter has /* This structure holds MCA information. Each (plug-in) adapter has
* eight POS registers. Then the machine may have integrated video and * eight POS registers. Then the machine may have integrated video and
......
...@@ -852,7 +852,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -852,7 +852,7 @@ void __init setup_arch(char **cmdline_p)
reserve_bootmem(PAGE_SIZE, PAGE_SIZE); reserve_bootmem(PAGE_SIZE, PAGE_SIZE);
#endif #endif
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_FIND_SMP_CONFIG
/* /*
* Find and reserve possible boot-time SMP configuration: * Find and reserve possible boot-time SMP configuration:
*/ */
......
...@@ -56,6 +56,9 @@ ...@@ -56,6 +56,9 @@
#include <linux/config.h> #include <linux/config.h>
#include <asm/arch_hooks.h> #include <asm/arch_hooks.h>
extern spinlock_t i8259A_lock;
#include "do_timer.h" #include "do_timer.h"
/* /*
...@@ -117,8 +120,6 @@ static inline unsigned long do_fast_gettimeoffset(void) ...@@ -117,8 +120,6 @@ static inline unsigned long do_fast_gettimeoffset(void)
spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED; spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
EXPORT_SYMBOL(i8253_lock); EXPORT_SYMBOL(i8253_lock);
extern spinlock_t i8259A_lock;
#ifndef CONFIG_X86_TSC #ifndef CONFIG_X86_TSC
/* This function must be called with interrupts disabled /* This function must be called with interrupts disabled
...@@ -199,47 +200,11 @@ static unsigned long do_slow_gettimeoffset(void) ...@@ -199,47 +200,11 @@ static unsigned long do_slow_gettimeoffset(void)
* (see c't 95/10 page 335 for Neptun bug.) * (see c't 95/10 page 335 for Neptun bug.)
*/ */
/* you can safely undefine this if you don't have the Neptune chipset */
#define BUGGY_NEPTUN_TIMER
if( jiffies_t == jiffies_p ) { if( jiffies_t == jiffies_p ) {
if( count > count_p ) { if( count > count_p ) {
/* the nutcase */ /* the nutcase */
count = do_timer_overflow(count);
int i;
spin_lock(&i8259A_lock);
/*
* This is tricky when I/O APICs are used;
* see do_timer_interrupt().
*/
i = inb(0x20);
spin_unlock(&i8259A_lock);
/* assumption about timer being IRQ0 */
if (i & 0x01) {
/*
* We cannot detect lost timer interrupts ...
* well, that's why we call them lost, don't we? :)
* [hmm, on the Pentium and Alpha we can ... sort of]
*/
count -= LATCH;
} else {
#ifdef BUGGY_NEPTUN_TIMER
/*
* for the Neptun bug we know that the 'latch'
* command doesnt latch the high and low value
* of the counter atomically. Thus we have to
* substract 256 from the counter
* ... funny, isnt it? :)
*/
count -= 256;
#else
printk("do_slow_gettimeoffset(): hardware timer problem?\n");
#endif
}
} }
} else } else
jiffies_p = jiffies_t; jiffies_p = jiffies_t;
......
...@@ -22,3 +22,29 @@ static inline void do_timer_interrupt_hook(struct pt_regs *regs) ...@@ -22,3 +22,29 @@ static inline void do_timer_interrupt_hook(struct pt_regs *regs)
smp_local_timer_interrupt(regs); smp_local_timer_interrupt(regs);
#endif #endif
} }
static inline int do_timer_overflow(int count)
{
int i;
spin_lock(&i8259A_lock);
/*
* This is tricky when I/O APICs are used;
* see do_timer_interrupt().
*/
i = inb(0x20);
spin_unlock(&i8259A_lock);
/* assumption about timer being IRQ0 */
if (i & 0x01) {
/*
* We cannot detect lost timer interrupts ...
* well, that's why we call them lost, don't we? :)
* [hmm, on the Pentium and Alpha we can ... sort of]
*/
count -= LATCH;
} else {
printk("do_slow_gettimeoffset(): hardware timer problem?\n");
}
return count;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment