diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index 88340e6626b6..66d53a6a2ce0 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.36 1999/04/14 14:26:35 bde Exp $ + * $Id: apic_vector.s,v 1.37 1999/04/28 01:04:12 luoqi Exp $ */ @@ -324,7 +324,7 @@ log_intr_event: #ifdef CPL_AND_CML -#define INTR(irq_num, vec_name) \ +#define INTR(irq_num, vec_name, maybe_extra_ipending) \ .text ; \ SUPERALIGN_TEXT ; \ /* _XintrNN: entry point used by IDT/HWIs & splz_unpend via _vec[]. */ \ @@ -335,6 +335,8 @@ IDTVEC(vec_name) ; \ movl %ax, %es ; \ movl $KPSEL, %eax ; \ movl %ax, %fs ; \ +; \ + maybe_extra_ipending ; \ ; \ APIC_ITRACE(apic_itrace_enter, irq_num, APIC_ITRACE_ENTER) ; \ lock ; /* MP-safe */ \ @@ -436,7 +438,7 @@ __CONCAT(Xresume,irq_num): ; \ #else /* CPL_AND_CML */ -#define INTR(irq_num, vec_name) \ +#define INTR(irq_num, vec_name, maybe_extra_ipending) \ .text ; \ SUPERALIGN_TEXT ; \ /* _XintrNN: entry point used by IDT/HWIs & splz_unpend via _vec[]. */ \ @@ -447,6 +449,8 @@ IDTVEC(vec_name) ; \ movl %ax, %es ; \ movl $KPSEL, %eax ; \ movl %ax, %fs ; \ +; \ + maybe_extra_ipending ; \ ; \ APIC_ITRACE(apic_itrace_enter, irq_num, APIC_ITRACE_ENTER) ; \ lock ; /* MP-safe */ \ @@ -916,30 +920,31 @@ MCOUNT_LABEL(bintr) FAST_INTR(21,fastintr21) FAST_INTR(22,fastintr22) FAST_INTR(23,fastintr23) - INTR(0,intr0) - INTR(1,intr1) - INTR(2,intr2) - INTR(3,intr3) - INTR(4,intr4) - INTR(5,intr5) - INTR(6,intr6) - INTR(7,intr7) - INTR(8,intr8) - INTR(9,intr9) - INTR(10,intr10) - INTR(11,intr11) - INTR(12,intr12) - INTR(13,intr13) - INTR(14,intr14) - INTR(15,intr15) - INTR(16,intr16) - INTR(17,intr17) - INTR(18,intr18) - INTR(19,intr19) - INTR(20,intr20) - INTR(21,intr21) - INTR(22,intr22) - INTR(23,intr23) +#define CLKINTR_PENDING movl $1,CNAME(clkintr_pending) + INTR(0,intr0, CLKINTR_PENDING) + INTR(1,intr1,) + INTR(2,intr2,) + INTR(3,intr3,) + INTR(4,intr4,) + INTR(5,intr5,) + INTR(6,intr6,) + INTR(7,intr7,) + INTR(8,intr8,) + INTR(9,intr9,) + INTR(10,intr10,) + INTR(11,intr11,) + INTR(12,intr12,) + INTR(13,intr13,) + INTR(14,intr14,) + INTR(15,intr15,) + INTR(16,intr16,) + INTR(17,intr17,) + INTR(18,intr18,) + INTR(19,intr19,) + INTR(20,intr20,) + INTR(21,intr21,) + INTR(22,intr22,) + INTR(23,intr23,) MCOUNT_LABEL(eintr) .data diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c index d9ee00edd9a5..75511f411e12 100644 --- a/sys/amd64/amd64/tsc.c +++ b/sys/amd64/amd64/tsc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.132 1999/04/25 09:00:00 phk Exp $ + * $Id: clock.c,v 1.133 1999/05/09 23:32:29 peter Exp $ */ /* @@ -69,6 +69,7 @@ #include #include #include +#include #if NAPM > 0 #include #include @@ -127,6 +128,7 @@ static void setup_8254_mixed_mode __P((void)); #define TIMER0_MAX_FREQ 20000 int adjkerntz; /* local offset from GMT in seconds */ +int clkintr_pending; int disable_rtc_set; /* disable resettodr() if != 0 */ volatile u_int idelayed; int statclock_disable; @@ -199,24 +201,15 @@ static void clkintr(struct clockframe frame) { if (timecounter->tc_get_timecount == i8254_get_timecount) { - /* - * Maintain i8254_offset and related variables. Optimize - * the usual case where i8254 counter rollover has not been - * detected in i8254_get_timecount() by pretending that we - * read the counter when it rolled over. Otherwise, call - * i8254_get_timecount() to do most of the work. The - * hardware counter must be read to ensure monotonicity - * despite multiple rollovers and misbehaving hardware. - */ - (disable_intr)(); /* XXX avoid clock locking */ - if (i8254_ticked) { - i8254_get_timecount(NULL); + disable_intr(); + if (i8254_ticked) i8254_ticked = 0; - } else { + else { i8254_offset += timer0_max_count; i8254_lastcount = 0; } - (enable_intr)(); /* XXX avoid clock locking */ + clkintr_pending = 0; + enable_intr(); } timer_func(&frame); switch (timer0_state) { @@ -1159,13 +1152,21 @@ i8254_get_timecount(struct timecounter *tc) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); - - count = hardclock_max_count - ((high << 8) | low); - if (count < i8254_lastcount) { + count = timer0_max_count - ((high << 8) | low); + if (count < i8254_lastcount || + (!i8254_ticked && (clkintr_pending || + ((count < 20 || (!(ef & PSL_I) && count < timer0_max_count / 2u)) && +#ifdef APIC_IO +#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */ + /* XXX this assumes that apic_8254_intr is < 24. */ + (lapic_irr1 & (1 << apic_8254_intr)))) +#else + (inb(IO_ICU1) & 1))) +#endif + )) { i8254_ticked = 1; - i8254_offset += hardclock_max_count; + i8254_offset += timer0_max_count; } - i8254_lastcount = count; count += i8254_offset; CLOCK_UNLOCK(); diff --git a/sys/amd64/isa/atpic_vector.S b/sys/amd64/isa/atpic_vector.S index 446030303231..453f9d553b84 100644 --- a/sys/amd64/isa/atpic_vector.S +++ b/sys/amd64/isa/atpic_vector.S @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: icu_vector.s,v 1.10 1999/04/14 14:26:36 bde Exp $ + * $Id: icu_vector.s,v 1.11 1999/04/28 01:04:13 luoqi Exp $ */ /* @@ -106,7 +106,7 @@ IDTVEC(vec_name) ; \ MEXITCOUNT ; \ jmp _doreti -#define INTR(irq_num, vec_name, icu, enable_icus, reg) \ +#define INTR(irq_num, vec_name, icu, enable_icus, reg, maybe_extra_ipending) \ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ @@ -120,6 +120,7 @@ IDTVEC(vec_name) ; \ movl %ax,%ds ; /* ... early for obsolete reasons */ \ movl %ax,%es ; \ movl %ax,%fs ; \ + maybe_extra_ipending ; \ movb _imen + IRQ_BYTE(irq_num),%al ; \ orb $IRQ_BIT(irq_num),%al ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ @@ -180,22 +181,23 @@ MCOUNT_LABEL(bintr) FAST_INTR(13,fastintr13, ENABLE_ICU1_AND_2) FAST_INTR(14,fastintr14, ENABLE_ICU1_AND_2) FAST_INTR(15,fastintr15, ENABLE_ICU1_AND_2) - INTR(0,intr0, IO_ICU1, ENABLE_ICU1, al) - INTR(1,intr1, IO_ICU1, ENABLE_ICU1, al) - INTR(2,intr2, IO_ICU1, ENABLE_ICU1, al) - INTR(3,intr3, IO_ICU1, ENABLE_ICU1, al) - INTR(4,intr4, IO_ICU1, ENABLE_ICU1, al) - INTR(5,intr5, IO_ICU1, ENABLE_ICU1, al) - INTR(6,intr6, IO_ICU1, ENABLE_ICU1, al) - INTR(7,intr7, IO_ICU1, ENABLE_ICU1, al) - INTR(8,intr8, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(9,intr9, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(10,intr10, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(11,intr11, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(12,intr12, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(13,intr13, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(14,intr14, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(15,intr15, IO_ICU2, ENABLE_ICU1_AND_2, ah) +#define CLKINTR_PENDING movl $1,CNAME(clkintr_pending) + INTR(0,intr0, IO_ICU1, ENABLE_ICU1, al, CLKINTR_PENDING) + INTR(1,intr1, IO_ICU1, ENABLE_ICU1, al,) + INTR(2,intr2, IO_ICU1, ENABLE_ICU1, al,) + INTR(3,intr3, IO_ICU1, ENABLE_ICU1, al,) + INTR(4,intr4, IO_ICU1, ENABLE_ICU1, al,) + INTR(5,intr5, IO_ICU1, ENABLE_ICU1, al,) + INTR(6,intr6, IO_ICU1, ENABLE_ICU1, al,) + INTR(7,intr7, IO_ICU1, ENABLE_ICU1, al,) + INTR(8,intr8, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(9,intr9, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(10,intr10, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(11,intr11, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(12,intr12, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(13,intr13, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(14,intr14, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(15,intr15, IO_ICU2, ENABLE_ICU1_AND_2, ah,) MCOUNT_LABEL(eintr) .data diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c index d9ee00edd9a5..75511f411e12 100644 --- a/sys/amd64/isa/clock.c +++ b/sys/amd64/isa/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.132 1999/04/25 09:00:00 phk Exp $ + * $Id: clock.c,v 1.133 1999/05/09 23:32:29 peter Exp $ */ /* @@ -69,6 +69,7 @@ #include #include #include +#include #if NAPM > 0 #include #include @@ -127,6 +128,7 @@ static void setup_8254_mixed_mode __P((void)); #define TIMER0_MAX_FREQ 20000 int adjkerntz; /* local offset from GMT in seconds */ +int clkintr_pending; int disable_rtc_set; /* disable resettodr() if != 0 */ volatile u_int idelayed; int statclock_disable; @@ -199,24 +201,15 @@ static void clkintr(struct clockframe frame) { if (timecounter->tc_get_timecount == i8254_get_timecount) { - /* - * Maintain i8254_offset and related variables. Optimize - * the usual case where i8254 counter rollover has not been - * detected in i8254_get_timecount() by pretending that we - * read the counter when it rolled over. Otherwise, call - * i8254_get_timecount() to do most of the work. The - * hardware counter must be read to ensure monotonicity - * despite multiple rollovers and misbehaving hardware. - */ - (disable_intr)(); /* XXX avoid clock locking */ - if (i8254_ticked) { - i8254_get_timecount(NULL); + disable_intr(); + if (i8254_ticked) i8254_ticked = 0; - } else { + else { i8254_offset += timer0_max_count; i8254_lastcount = 0; } - (enable_intr)(); /* XXX avoid clock locking */ + clkintr_pending = 0; + enable_intr(); } timer_func(&frame); switch (timer0_state) { @@ -1159,13 +1152,21 @@ i8254_get_timecount(struct timecounter *tc) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); - - count = hardclock_max_count - ((high << 8) | low); - if (count < i8254_lastcount) { + count = timer0_max_count - ((high << 8) | low); + if (count < i8254_lastcount || + (!i8254_ticked && (clkintr_pending || + ((count < 20 || (!(ef & PSL_I) && count < timer0_max_count / 2u)) && +#ifdef APIC_IO +#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */ + /* XXX this assumes that apic_8254_intr is < 24. */ + (lapic_irr1 & (1 << apic_8254_intr)))) +#else + (inb(IO_ICU1) & 1))) +#endif + )) { i8254_ticked = 1; - i8254_offset += hardclock_max_count; + i8254_offset += timer0_max_count; } - i8254_lastcount = count; count += i8254_offset; CLOCK_UNLOCK(); diff --git a/sys/amd64/isa/icu_vector.S b/sys/amd64/isa/icu_vector.S index 446030303231..453f9d553b84 100644 --- a/sys/amd64/isa/icu_vector.S +++ b/sys/amd64/isa/icu_vector.S @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: icu_vector.s,v 1.10 1999/04/14 14:26:36 bde Exp $ + * $Id: icu_vector.s,v 1.11 1999/04/28 01:04:13 luoqi Exp $ */ /* @@ -106,7 +106,7 @@ IDTVEC(vec_name) ; \ MEXITCOUNT ; \ jmp _doreti -#define INTR(irq_num, vec_name, icu, enable_icus, reg) \ +#define INTR(irq_num, vec_name, icu, enable_icus, reg, maybe_extra_ipending) \ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ @@ -120,6 +120,7 @@ IDTVEC(vec_name) ; \ movl %ax,%ds ; /* ... early for obsolete reasons */ \ movl %ax,%es ; \ movl %ax,%fs ; \ + maybe_extra_ipending ; \ movb _imen + IRQ_BYTE(irq_num),%al ; \ orb $IRQ_BIT(irq_num),%al ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ @@ -180,22 +181,23 @@ MCOUNT_LABEL(bintr) FAST_INTR(13,fastintr13, ENABLE_ICU1_AND_2) FAST_INTR(14,fastintr14, ENABLE_ICU1_AND_2) FAST_INTR(15,fastintr15, ENABLE_ICU1_AND_2) - INTR(0,intr0, IO_ICU1, ENABLE_ICU1, al) - INTR(1,intr1, IO_ICU1, ENABLE_ICU1, al) - INTR(2,intr2, IO_ICU1, ENABLE_ICU1, al) - INTR(3,intr3, IO_ICU1, ENABLE_ICU1, al) - INTR(4,intr4, IO_ICU1, ENABLE_ICU1, al) - INTR(5,intr5, IO_ICU1, ENABLE_ICU1, al) - INTR(6,intr6, IO_ICU1, ENABLE_ICU1, al) - INTR(7,intr7, IO_ICU1, ENABLE_ICU1, al) - INTR(8,intr8, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(9,intr9, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(10,intr10, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(11,intr11, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(12,intr12, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(13,intr13, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(14,intr14, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(15,intr15, IO_ICU2, ENABLE_ICU1_AND_2, ah) +#define CLKINTR_PENDING movl $1,CNAME(clkintr_pending) + INTR(0,intr0, IO_ICU1, ENABLE_ICU1, al, CLKINTR_PENDING) + INTR(1,intr1, IO_ICU1, ENABLE_ICU1, al,) + INTR(2,intr2, IO_ICU1, ENABLE_ICU1, al,) + INTR(3,intr3, IO_ICU1, ENABLE_ICU1, al,) + INTR(4,intr4, IO_ICU1, ENABLE_ICU1, al,) + INTR(5,intr5, IO_ICU1, ENABLE_ICU1, al,) + INTR(6,intr6, IO_ICU1, ENABLE_ICU1, al,) + INTR(7,intr7, IO_ICU1, ENABLE_ICU1, al,) + INTR(8,intr8, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(9,intr9, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(10,intr10, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(11,intr11, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(12,intr12, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(13,intr13, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(14,intr14, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(15,intr15, IO_ICU2, ENABLE_ICU1_AND_2, ah,) MCOUNT_LABEL(eintr) .data diff --git a/sys/amd64/isa/icu_vector.s b/sys/amd64/isa/icu_vector.s index 446030303231..453f9d553b84 100644 --- a/sys/amd64/isa/icu_vector.s +++ b/sys/amd64/isa/icu_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: icu_vector.s,v 1.10 1999/04/14 14:26:36 bde Exp $ + * $Id: icu_vector.s,v 1.11 1999/04/28 01:04:13 luoqi Exp $ */ /* @@ -106,7 +106,7 @@ IDTVEC(vec_name) ; \ MEXITCOUNT ; \ jmp _doreti -#define INTR(irq_num, vec_name, icu, enable_icus, reg) \ +#define INTR(irq_num, vec_name, icu, enable_icus, reg, maybe_extra_ipending) \ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ @@ -120,6 +120,7 @@ IDTVEC(vec_name) ; \ movl %ax,%ds ; /* ... early for obsolete reasons */ \ movl %ax,%es ; \ movl %ax,%fs ; \ + maybe_extra_ipending ; \ movb _imen + IRQ_BYTE(irq_num),%al ; \ orb $IRQ_BIT(irq_num),%al ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ @@ -180,22 +181,23 @@ MCOUNT_LABEL(bintr) FAST_INTR(13,fastintr13, ENABLE_ICU1_AND_2) FAST_INTR(14,fastintr14, ENABLE_ICU1_AND_2) FAST_INTR(15,fastintr15, ENABLE_ICU1_AND_2) - INTR(0,intr0, IO_ICU1, ENABLE_ICU1, al) - INTR(1,intr1, IO_ICU1, ENABLE_ICU1, al) - INTR(2,intr2, IO_ICU1, ENABLE_ICU1, al) - INTR(3,intr3, IO_ICU1, ENABLE_ICU1, al) - INTR(4,intr4, IO_ICU1, ENABLE_ICU1, al) - INTR(5,intr5, IO_ICU1, ENABLE_ICU1, al) - INTR(6,intr6, IO_ICU1, ENABLE_ICU1, al) - INTR(7,intr7, IO_ICU1, ENABLE_ICU1, al) - INTR(8,intr8, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(9,intr9, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(10,intr10, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(11,intr11, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(12,intr12, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(13,intr13, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(14,intr14, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(15,intr15, IO_ICU2, ENABLE_ICU1_AND_2, ah) +#define CLKINTR_PENDING movl $1,CNAME(clkintr_pending) + INTR(0,intr0, IO_ICU1, ENABLE_ICU1, al, CLKINTR_PENDING) + INTR(1,intr1, IO_ICU1, ENABLE_ICU1, al,) + INTR(2,intr2, IO_ICU1, ENABLE_ICU1, al,) + INTR(3,intr3, IO_ICU1, ENABLE_ICU1, al,) + INTR(4,intr4, IO_ICU1, ENABLE_ICU1, al,) + INTR(5,intr5, IO_ICU1, ENABLE_ICU1, al,) + INTR(6,intr6, IO_ICU1, ENABLE_ICU1, al,) + INTR(7,intr7, IO_ICU1, ENABLE_ICU1, al,) + INTR(8,intr8, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(9,intr9, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(10,intr10, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(11,intr11, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(12,intr12, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(13,intr13, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(14,intr14, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(15,intr15, IO_ICU2, ENABLE_ICU1_AND_2, ah,) MCOUNT_LABEL(eintr) .data diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index 88340e6626b6..66d53a6a2ce0 100644 --- a/sys/i386/i386/apic_vector.s +++ b/sys/i386/i386/apic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.36 1999/04/14 14:26:35 bde Exp $ + * $Id: apic_vector.s,v 1.37 1999/04/28 01:04:12 luoqi Exp $ */ @@ -324,7 +324,7 @@ log_intr_event: #ifdef CPL_AND_CML -#define INTR(irq_num, vec_name) \ +#define INTR(irq_num, vec_name, maybe_extra_ipending) \ .text ; \ SUPERALIGN_TEXT ; \ /* _XintrNN: entry point used by IDT/HWIs & splz_unpend via _vec[]. */ \ @@ -335,6 +335,8 @@ IDTVEC(vec_name) ; \ movl %ax, %es ; \ movl $KPSEL, %eax ; \ movl %ax, %fs ; \ +; \ + maybe_extra_ipending ; \ ; \ APIC_ITRACE(apic_itrace_enter, irq_num, APIC_ITRACE_ENTER) ; \ lock ; /* MP-safe */ \ @@ -436,7 +438,7 @@ __CONCAT(Xresume,irq_num): ; \ #else /* CPL_AND_CML */ -#define INTR(irq_num, vec_name) \ +#define INTR(irq_num, vec_name, maybe_extra_ipending) \ .text ; \ SUPERALIGN_TEXT ; \ /* _XintrNN: entry point used by IDT/HWIs & splz_unpend via _vec[]. */ \ @@ -447,6 +449,8 @@ IDTVEC(vec_name) ; \ movl %ax, %es ; \ movl $KPSEL, %eax ; \ movl %ax, %fs ; \ +; \ + maybe_extra_ipending ; \ ; \ APIC_ITRACE(apic_itrace_enter, irq_num, APIC_ITRACE_ENTER) ; \ lock ; /* MP-safe */ \ @@ -916,30 +920,31 @@ MCOUNT_LABEL(bintr) FAST_INTR(21,fastintr21) FAST_INTR(22,fastintr22) FAST_INTR(23,fastintr23) - INTR(0,intr0) - INTR(1,intr1) - INTR(2,intr2) - INTR(3,intr3) - INTR(4,intr4) - INTR(5,intr5) - INTR(6,intr6) - INTR(7,intr7) - INTR(8,intr8) - INTR(9,intr9) - INTR(10,intr10) - INTR(11,intr11) - INTR(12,intr12) - INTR(13,intr13) - INTR(14,intr14) - INTR(15,intr15) - INTR(16,intr16) - INTR(17,intr17) - INTR(18,intr18) - INTR(19,intr19) - INTR(20,intr20) - INTR(21,intr21) - INTR(22,intr22) - INTR(23,intr23) +#define CLKINTR_PENDING movl $1,CNAME(clkintr_pending) + INTR(0,intr0, CLKINTR_PENDING) + INTR(1,intr1,) + INTR(2,intr2,) + INTR(3,intr3,) + INTR(4,intr4,) + INTR(5,intr5,) + INTR(6,intr6,) + INTR(7,intr7,) + INTR(8,intr8,) + INTR(9,intr9,) + INTR(10,intr10,) + INTR(11,intr11,) + INTR(12,intr12,) + INTR(13,intr13,) + INTR(14,intr14,) + INTR(15,intr15,) + INTR(16,intr16,) + INTR(17,intr17,) + INTR(18,intr18,) + INTR(19,intr19,) + INTR(20,intr20,) + INTR(21,intr21,) + INTR(22,intr22,) + INTR(23,intr23,) MCOUNT_LABEL(eintr) .data diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c index d9ee00edd9a5..75511f411e12 100644 --- a/sys/i386/i386/tsc.c +++ b/sys/i386/i386/tsc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.132 1999/04/25 09:00:00 phk Exp $ + * $Id: clock.c,v 1.133 1999/05/09 23:32:29 peter Exp $ */ /* @@ -69,6 +69,7 @@ #include #include #include +#include #if NAPM > 0 #include #include @@ -127,6 +128,7 @@ static void setup_8254_mixed_mode __P((void)); #define TIMER0_MAX_FREQ 20000 int adjkerntz; /* local offset from GMT in seconds */ +int clkintr_pending; int disable_rtc_set; /* disable resettodr() if != 0 */ volatile u_int idelayed; int statclock_disable; @@ -199,24 +201,15 @@ static void clkintr(struct clockframe frame) { if (timecounter->tc_get_timecount == i8254_get_timecount) { - /* - * Maintain i8254_offset and related variables. Optimize - * the usual case where i8254 counter rollover has not been - * detected in i8254_get_timecount() by pretending that we - * read the counter when it rolled over. Otherwise, call - * i8254_get_timecount() to do most of the work. The - * hardware counter must be read to ensure monotonicity - * despite multiple rollovers and misbehaving hardware. - */ - (disable_intr)(); /* XXX avoid clock locking */ - if (i8254_ticked) { - i8254_get_timecount(NULL); + disable_intr(); + if (i8254_ticked) i8254_ticked = 0; - } else { + else { i8254_offset += timer0_max_count; i8254_lastcount = 0; } - (enable_intr)(); /* XXX avoid clock locking */ + clkintr_pending = 0; + enable_intr(); } timer_func(&frame); switch (timer0_state) { @@ -1159,13 +1152,21 @@ i8254_get_timecount(struct timecounter *tc) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); - - count = hardclock_max_count - ((high << 8) | low); - if (count < i8254_lastcount) { + count = timer0_max_count - ((high << 8) | low); + if (count < i8254_lastcount || + (!i8254_ticked && (clkintr_pending || + ((count < 20 || (!(ef & PSL_I) && count < timer0_max_count / 2u)) && +#ifdef APIC_IO +#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */ + /* XXX this assumes that apic_8254_intr is < 24. */ + (lapic_irr1 & (1 << apic_8254_intr)))) +#else + (inb(IO_ICU1) & 1))) +#endif + )) { i8254_ticked = 1; - i8254_offset += hardclock_max_count; + i8254_offset += timer0_max_count; } - i8254_lastcount = count; count += i8254_offset; CLOCK_UNLOCK(); diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s index 88340e6626b6..66d53a6a2ce0 100644 --- a/sys/i386/isa/apic_vector.s +++ b/sys/i386/isa/apic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.36 1999/04/14 14:26:35 bde Exp $ + * $Id: apic_vector.s,v 1.37 1999/04/28 01:04:12 luoqi Exp $ */ @@ -324,7 +324,7 @@ log_intr_event: #ifdef CPL_AND_CML -#define INTR(irq_num, vec_name) \ +#define INTR(irq_num, vec_name, maybe_extra_ipending) \ .text ; \ SUPERALIGN_TEXT ; \ /* _XintrNN: entry point used by IDT/HWIs & splz_unpend via _vec[]. */ \ @@ -335,6 +335,8 @@ IDTVEC(vec_name) ; \ movl %ax, %es ; \ movl $KPSEL, %eax ; \ movl %ax, %fs ; \ +; \ + maybe_extra_ipending ; \ ; \ APIC_ITRACE(apic_itrace_enter, irq_num, APIC_ITRACE_ENTER) ; \ lock ; /* MP-safe */ \ @@ -436,7 +438,7 @@ __CONCAT(Xresume,irq_num): ; \ #else /* CPL_AND_CML */ -#define INTR(irq_num, vec_name) \ +#define INTR(irq_num, vec_name, maybe_extra_ipending) \ .text ; \ SUPERALIGN_TEXT ; \ /* _XintrNN: entry point used by IDT/HWIs & splz_unpend via _vec[]. */ \ @@ -447,6 +449,8 @@ IDTVEC(vec_name) ; \ movl %ax, %es ; \ movl $KPSEL, %eax ; \ movl %ax, %fs ; \ +; \ + maybe_extra_ipending ; \ ; \ APIC_ITRACE(apic_itrace_enter, irq_num, APIC_ITRACE_ENTER) ; \ lock ; /* MP-safe */ \ @@ -916,30 +920,31 @@ MCOUNT_LABEL(bintr) FAST_INTR(21,fastintr21) FAST_INTR(22,fastintr22) FAST_INTR(23,fastintr23) - INTR(0,intr0) - INTR(1,intr1) - INTR(2,intr2) - INTR(3,intr3) - INTR(4,intr4) - INTR(5,intr5) - INTR(6,intr6) - INTR(7,intr7) - INTR(8,intr8) - INTR(9,intr9) - INTR(10,intr10) - INTR(11,intr11) - INTR(12,intr12) - INTR(13,intr13) - INTR(14,intr14) - INTR(15,intr15) - INTR(16,intr16) - INTR(17,intr17) - INTR(18,intr18) - INTR(19,intr19) - INTR(20,intr20) - INTR(21,intr21) - INTR(22,intr22) - INTR(23,intr23) +#define CLKINTR_PENDING movl $1,CNAME(clkintr_pending) + INTR(0,intr0, CLKINTR_PENDING) + INTR(1,intr1,) + INTR(2,intr2,) + INTR(3,intr3,) + INTR(4,intr4,) + INTR(5,intr5,) + INTR(6,intr6,) + INTR(7,intr7,) + INTR(8,intr8,) + INTR(9,intr9,) + INTR(10,intr10,) + INTR(11,intr11,) + INTR(12,intr12,) + INTR(13,intr13,) + INTR(14,intr14,) + INTR(15,intr15,) + INTR(16,intr16,) + INTR(17,intr17,) + INTR(18,intr18,) + INTR(19,intr19,) + INTR(20,intr20,) + INTR(21,intr21,) + INTR(22,intr22,) + INTR(23,intr23,) MCOUNT_LABEL(eintr) .data diff --git a/sys/i386/isa/atpic_vector.s b/sys/i386/isa/atpic_vector.s index 446030303231..453f9d553b84 100644 --- a/sys/i386/isa/atpic_vector.s +++ b/sys/i386/isa/atpic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: icu_vector.s,v 1.10 1999/04/14 14:26:36 bde Exp $ + * $Id: icu_vector.s,v 1.11 1999/04/28 01:04:13 luoqi Exp $ */ /* @@ -106,7 +106,7 @@ IDTVEC(vec_name) ; \ MEXITCOUNT ; \ jmp _doreti -#define INTR(irq_num, vec_name, icu, enable_icus, reg) \ +#define INTR(irq_num, vec_name, icu, enable_icus, reg, maybe_extra_ipending) \ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ @@ -120,6 +120,7 @@ IDTVEC(vec_name) ; \ movl %ax,%ds ; /* ... early for obsolete reasons */ \ movl %ax,%es ; \ movl %ax,%fs ; \ + maybe_extra_ipending ; \ movb _imen + IRQ_BYTE(irq_num),%al ; \ orb $IRQ_BIT(irq_num),%al ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ @@ -180,22 +181,23 @@ MCOUNT_LABEL(bintr) FAST_INTR(13,fastintr13, ENABLE_ICU1_AND_2) FAST_INTR(14,fastintr14, ENABLE_ICU1_AND_2) FAST_INTR(15,fastintr15, ENABLE_ICU1_AND_2) - INTR(0,intr0, IO_ICU1, ENABLE_ICU1, al) - INTR(1,intr1, IO_ICU1, ENABLE_ICU1, al) - INTR(2,intr2, IO_ICU1, ENABLE_ICU1, al) - INTR(3,intr3, IO_ICU1, ENABLE_ICU1, al) - INTR(4,intr4, IO_ICU1, ENABLE_ICU1, al) - INTR(5,intr5, IO_ICU1, ENABLE_ICU1, al) - INTR(6,intr6, IO_ICU1, ENABLE_ICU1, al) - INTR(7,intr7, IO_ICU1, ENABLE_ICU1, al) - INTR(8,intr8, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(9,intr9, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(10,intr10, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(11,intr11, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(12,intr12, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(13,intr13, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(14,intr14, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(15,intr15, IO_ICU2, ENABLE_ICU1_AND_2, ah) +#define CLKINTR_PENDING movl $1,CNAME(clkintr_pending) + INTR(0,intr0, IO_ICU1, ENABLE_ICU1, al, CLKINTR_PENDING) + INTR(1,intr1, IO_ICU1, ENABLE_ICU1, al,) + INTR(2,intr2, IO_ICU1, ENABLE_ICU1, al,) + INTR(3,intr3, IO_ICU1, ENABLE_ICU1, al,) + INTR(4,intr4, IO_ICU1, ENABLE_ICU1, al,) + INTR(5,intr5, IO_ICU1, ENABLE_ICU1, al,) + INTR(6,intr6, IO_ICU1, ENABLE_ICU1, al,) + INTR(7,intr7, IO_ICU1, ENABLE_ICU1, al,) + INTR(8,intr8, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(9,intr9, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(10,intr10, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(11,intr11, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(12,intr12, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(13,intr13, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(14,intr14, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(15,intr15, IO_ICU2, ENABLE_ICU1_AND_2, ah,) MCOUNT_LABEL(eintr) .data diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index d9ee00edd9a5..75511f411e12 100644 --- a/sys/i386/isa/clock.c +++ b/sys/i386/isa/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.132 1999/04/25 09:00:00 phk Exp $ + * $Id: clock.c,v 1.133 1999/05/09 23:32:29 peter Exp $ */ /* @@ -69,6 +69,7 @@ #include #include #include +#include #if NAPM > 0 #include #include @@ -127,6 +128,7 @@ static void setup_8254_mixed_mode __P((void)); #define TIMER0_MAX_FREQ 20000 int adjkerntz; /* local offset from GMT in seconds */ +int clkintr_pending; int disable_rtc_set; /* disable resettodr() if != 0 */ volatile u_int idelayed; int statclock_disable; @@ -199,24 +201,15 @@ static void clkintr(struct clockframe frame) { if (timecounter->tc_get_timecount == i8254_get_timecount) { - /* - * Maintain i8254_offset and related variables. Optimize - * the usual case where i8254 counter rollover has not been - * detected in i8254_get_timecount() by pretending that we - * read the counter when it rolled over. Otherwise, call - * i8254_get_timecount() to do most of the work. The - * hardware counter must be read to ensure monotonicity - * despite multiple rollovers and misbehaving hardware. - */ - (disable_intr)(); /* XXX avoid clock locking */ - if (i8254_ticked) { - i8254_get_timecount(NULL); + disable_intr(); + if (i8254_ticked) i8254_ticked = 0; - } else { + else { i8254_offset += timer0_max_count; i8254_lastcount = 0; } - (enable_intr)(); /* XXX avoid clock locking */ + clkintr_pending = 0; + enable_intr(); } timer_func(&frame); switch (timer0_state) { @@ -1159,13 +1152,21 @@ i8254_get_timecount(struct timecounter *tc) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); - - count = hardclock_max_count - ((high << 8) | low); - if (count < i8254_lastcount) { + count = timer0_max_count - ((high << 8) | low); + if (count < i8254_lastcount || + (!i8254_ticked && (clkintr_pending || + ((count < 20 || (!(ef & PSL_I) && count < timer0_max_count / 2u)) && +#ifdef APIC_IO +#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */ + /* XXX this assumes that apic_8254_intr is < 24. */ + (lapic_irr1 & (1 << apic_8254_intr)))) +#else + (inb(IO_ICU1) & 1))) +#endif + )) { i8254_ticked = 1; - i8254_offset += hardclock_max_count; + i8254_offset += timer0_max_count; } - i8254_lastcount = count; count += i8254_offset; CLOCK_UNLOCK(); diff --git a/sys/i386/isa/icu_vector.s b/sys/i386/isa/icu_vector.s index 446030303231..453f9d553b84 100644 --- a/sys/i386/isa/icu_vector.s +++ b/sys/i386/isa/icu_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: icu_vector.s,v 1.10 1999/04/14 14:26:36 bde Exp $ + * $Id: icu_vector.s,v 1.11 1999/04/28 01:04:13 luoqi Exp $ */ /* @@ -106,7 +106,7 @@ IDTVEC(vec_name) ; \ MEXITCOUNT ; \ jmp _doreti -#define INTR(irq_num, vec_name, icu, enable_icus, reg) \ +#define INTR(irq_num, vec_name, icu, enable_icus, reg, maybe_extra_ipending) \ .text ; \ SUPERALIGN_TEXT ; \ IDTVEC(vec_name) ; \ @@ -120,6 +120,7 @@ IDTVEC(vec_name) ; \ movl %ax,%ds ; /* ... early for obsolete reasons */ \ movl %ax,%es ; \ movl %ax,%fs ; \ + maybe_extra_ipending ; \ movb _imen + IRQ_BYTE(irq_num),%al ; \ orb $IRQ_BIT(irq_num),%al ; \ movb %al,_imen + IRQ_BYTE(irq_num) ; \ @@ -180,22 +181,23 @@ MCOUNT_LABEL(bintr) FAST_INTR(13,fastintr13, ENABLE_ICU1_AND_2) FAST_INTR(14,fastintr14, ENABLE_ICU1_AND_2) FAST_INTR(15,fastintr15, ENABLE_ICU1_AND_2) - INTR(0,intr0, IO_ICU1, ENABLE_ICU1, al) - INTR(1,intr1, IO_ICU1, ENABLE_ICU1, al) - INTR(2,intr2, IO_ICU1, ENABLE_ICU1, al) - INTR(3,intr3, IO_ICU1, ENABLE_ICU1, al) - INTR(4,intr4, IO_ICU1, ENABLE_ICU1, al) - INTR(5,intr5, IO_ICU1, ENABLE_ICU1, al) - INTR(6,intr6, IO_ICU1, ENABLE_ICU1, al) - INTR(7,intr7, IO_ICU1, ENABLE_ICU1, al) - INTR(8,intr8, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(9,intr9, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(10,intr10, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(11,intr11, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(12,intr12, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(13,intr13, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(14,intr14, IO_ICU2, ENABLE_ICU1_AND_2, ah) - INTR(15,intr15, IO_ICU2, ENABLE_ICU1_AND_2, ah) +#define CLKINTR_PENDING movl $1,CNAME(clkintr_pending) + INTR(0,intr0, IO_ICU1, ENABLE_ICU1, al, CLKINTR_PENDING) + INTR(1,intr1, IO_ICU1, ENABLE_ICU1, al,) + INTR(2,intr2, IO_ICU1, ENABLE_ICU1, al,) + INTR(3,intr3, IO_ICU1, ENABLE_ICU1, al,) + INTR(4,intr4, IO_ICU1, ENABLE_ICU1, al,) + INTR(5,intr5, IO_ICU1, ENABLE_ICU1, al,) + INTR(6,intr6, IO_ICU1, ENABLE_ICU1, al,) + INTR(7,intr7, IO_ICU1, ENABLE_ICU1, al,) + INTR(8,intr8, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(9,intr9, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(10,intr10, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(11,intr11, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(12,intr12, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(13,intr13, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(14,intr14, IO_ICU2, ENABLE_ICU1_AND_2, ah,) + INTR(15,intr15, IO_ICU2, ENABLE_ICU1_AND_2, ah,) MCOUNT_LABEL(eintr) .data diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c index d9ee00edd9a5..75511f411e12 100644 --- a/sys/isa/atrtc.c +++ b/sys/isa/atrtc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.132 1999/04/25 09:00:00 phk Exp $ + * $Id: clock.c,v 1.133 1999/05/09 23:32:29 peter Exp $ */ /* @@ -69,6 +69,7 @@ #include #include #include +#include #if NAPM > 0 #include #include @@ -127,6 +128,7 @@ static void setup_8254_mixed_mode __P((void)); #define TIMER0_MAX_FREQ 20000 int adjkerntz; /* local offset from GMT in seconds */ +int clkintr_pending; int disable_rtc_set; /* disable resettodr() if != 0 */ volatile u_int idelayed; int statclock_disable; @@ -199,24 +201,15 @@ static void clkintr(struct clockframe frame) { if (timecounter->tc_get_timecount == i8254_get_timecount) { - /* - * Maintain i8254_offset and related variables. Optimize - * the usual case where i8254 counter rollover has not been - * detected in i8254_get_timecount() by pretending that we - * read the counter when it rolled over. Otherwise, call - * i8254_get_timecount() to do most of the work. The - * hardware counter must be read to ensure monotonicity - * despite multiple rollovers and misbehaving hardware. - */ - (disable_intr)(); /* XXX avoid clock locking */ - if (i8254_ticked) { - i8254_get_timecount(NULL); + disable_intr(); + if (i8254_ticked) i8254_ticked = 0; - } else { + else { i8254_offset += timer0_max_count; i8254_lastcount = 0; } - (enable_intr)(); /* XXX avoid clock locking */ + clkintr_pending = 0; + enable_intr(); } timer_func(&frame); switch (timer0_state) { @@ -1159,13 +1152,21 @@ i8254_get_timecount(struct timecounter *tc) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); - - count = hardclock_max_count - ((high << 8) | low); - if (count < i8254_lastcount) { + count = timer0_max_count - ((high << 8) | low); + if (count < i8254_lastcount || + (!i8254_ticked && (clkintr_pending || + ((count < 20 || (!(ef & PSL_I) && count < timer0_max_count / 2u)) && +#ifdef APIC_IO +#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */ + /* XXX this assumes that apic_8254_intr is < 24. */ + (lapic_irr1 & (1 << apic_8254_intr)))) +#else + (inb(IO_ICU1) & 1))) +#endif + )) { i8254_ticked = 1; - i8254_offset += hardclock_max_count; + i8254_offset += timer0_max_count; } - i8254_lastcount = count; count += i8254_offset; CLOCK_UNLOCK();