patch-2.4.0-test2 linux/arch/i386/kernel/time.c
Next file: linux/arch/i386/kernel/traps.c
Previous file: linux/arch/i386/kernel/smpboot.c
Back to the patch index
Back to the overall index
- Lines: 113
- Date:
Mon Jun 19 18:39:17 2000
- Orig file:
v2.4.0-test1/linux/arch/i386/kernel/time.c
- Orig date:
Sun Mar 19 18:35:30 2000
diff -u --recursive --new-file v2.4.0-test1/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
@@ -114,10 +114,12 @@
#define TICK_SIZE tick
-#ifndef CONFIG_X86_TSC
-
spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
+extern spinlock_t i8259A_lock;
+
+#ifndef CONFIG_X86_TSC
+
/* This function must be called with interrupts disabled
* It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs
*
@@ -176,6 +178,7 @@
jiffies_t = jiffies;
count |= inb_p(0x40) << 8;
+ spin_unlock(&i8253_lock);
/*
* avoiding timer inconsistencies (they are rare, but they happen)...
@@ -194,10 +197,18 @@
if( count > count_p ) {
/* the nutcase */
- outb_p(0x0A, 0x20);
+ int i;
- /* assumption about timer being IRQ1 */
- if( inb(0x20) & 0x01 ) {
+ 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? :)
@@ -222,7 +233,6 @@
}
} else
jiffies_p = jiffies_t;
- spin_unlock(&i8253_lock);
count_p = count;
@@ -365,12 +375,30 @@
/* last time the cmos clock got updated */
static long last_rtc_update = 0;
+int timer_ack = 0;
+
/*
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick
*/
static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
+#ifdef CONFIG_X86_IO_APIC
+ if (timer_ack) {
+ /*
+ * Subtle, when I/O APICs are used we have to ack timer IRQ
+ * manually to reset the IRR bit for do_slow_gettimeoffset().
+ * This will also deassert NMI lines for the watchdog if run
+ * on an 82489DX-based system.
+ */
+ spin_lock(&i8259A_lock);
+ outb(0x0c, 0x20);
+ /* Ack the IRQ; AEOI will end it automatically. */
+ inb(0x20);
+ spin_unlock(&i8259A_lock);
+ }
+#endif
+
#ifdef CONFIG_VISWS
/* Clear the interrupt */
co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR);
@@ -459,19 +487,12 @@
rdtscl(last_tsc_low);
-#if 0 /*
- * SUBTLE: this is not necessary from here because it's implicit in the
- * write xtime_lock.
- */
spin_lock(&i8253_lock);
-#endif
outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */
count |= inb(0x40) << 8;
-#if 0
spin_unlock(&i8253_lock);
-#endif
count = ((LATCH-1) - count) * TICK_SIZE;
delay_at_last_interrupt = (count + LATCH/2) / LATCH;
@@ -667,7 +688,7 @@
dodgy_tsc();
- if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) {
+ if (cpu_has_tsc) {
unsigned long tsc_quotient = calibrate_tsc();
if (tsc_quotient) {
fast_gettimeoffset_quotient = tsc_quotient;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)