diff options
author | fsmp <fsmp@FreeBSD.org> | 1997-07-26 01:53:04 +0000 |
---|---|---|
committer | fsmp <fsmp@FreeBSD.org> | 1997-07-26 01:53:04 +0000 |
commit | 78cff7365d666ea82c32d53ae429cb3f5b843259 (patch) | |
tree | 37ad503dbdfcbe9eded05c7a112a0412b228f949 /sys/i386/isa | |
parent | 7b1e0dfbb931fa6122580673d4ff133380b6b569 (diff) | |
download | FreeBSD-src-78cff7365d666ea82c32d53ae429cb3f5b843259.zip FreeBSD-src-78cff7365d666ea82c32d53ae429cb3f5b843259.tar.gz |
clock.c:
- removed TEST_ALTTIMER.
- removed APIC_PIN0_TIMER.
- removed TIMER_ALL.
apic_vector.s:
- new algorithm where a CPU uses try_mplock instead of get_mplock:
if successful continue as before.
if fail set ipending bit, mask INT (to avoid recursion), cleanup & iret.
This allows the CPU to return to successful work, while the ISR will be run
by the CPU holding the lock as part of the doreti dance.
Diffstat (limited to 'sys/i386/isa')
-rw-r--r-- | sys/i386/isa/apic_vector.s | 60 | ||||
-rw-r--r-- | sys/i386/isa/clock.c | 77 |
2 files changed, 49 insertions, 88 deletions
diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s index cb4c4ff..00f6b8d 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.14 1997/07/23 20:18:14 smp Exp smp $ + * $Id: apic_vector.s,v 1.15 1997/07/25 22:20:11 smp Exp smp $ */ @@ -16,21 +16,24 @@ /* * 'lazy masking' code suggested by Bruce Evans <bde@zeta.org.au> */ -#if 1 + +#ifdef PEND_INTS + #define MAYBE_MASK_IRQ(irq_num) \ lock ; /* MP-safe */ \ btsl $(irq_num),iactive ; /* lazy masking */ \ - jnc 1f ; /* NOT active */ \ + jnc 8f ; /* NOT active */ \ +7: ; \ IMASK_LOCK ; /* enter critical reg */\ orl $IRQ_BIT(irq_num),_apic_imen ; /* set the mask bit */ \ - movl _ioapic,%ecx ; /* ioapic[0]addr */ \ + movl _ioapic,%ecx ; /* ioapic[0] addr */ \ movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \ orl $IOART_INTMASK,%eax ; /* set the mask */ \ movl %eax,IOAPIC_WINDOW(%ecx) ; /* new value */ \ orl $IRQ_BIT(irq_num), _ipending ; /* set _ipending bit */ \ - movl $0, lapic_eoi ; /* do the EOI */ \ IMASK_UNLOCK ; /* exit critical reg */ \ + movl $0, lapic_eoi ; /* do the EOI */ \ popl %es ; \ popl %ds ; \ popal ; \ @@ -38,23 +41,27 @@ iret ; \ ; \ ALIGN_TEXT ; \ -1: GET_MPLOCK /* SMP Spin lock */ -#else +8: ; \ + call _try_mplock ; \ + testl %eax, %eax ; \ + jz 7b /* can't enter kernel */ + +#else /* PEND_INTS */ + #define MAYBE_MASK_IRQ(irq_num) \ - GET_MPLOCK ; /* SMP Spin lock */ \ lock ; /* MP-safe */ \ btsl $(irq_num),iactive ; /* lazy masking */ \ jnc 1f ; /* NOT active */ \ - /* XXX atomic access */ \ + IMASK_LOCK ; /* enter critical reg */\ orl $IRQ_BIT(irq_num),_apic_imen ; /* set the mask bit */ \ movl _ioapic,%ecx ; /* ioapic[0]addr */ \ movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \ orl $IOART_INTMASK,%eax ; /* set the mask */ \ movl %eax,IOAPIC_WINDOW(%ecx) ; /* new value */ \ - movl $0, lapic_eoi ; /* do the EOI */ \ orl $IRQ_BIT(irq_num), _ipending ; /* set _ipending bit */ \ - REL_MPLOCK ; /* release SMP GL */ \ + movl $0, lapic_eoi ; /* do the EOI */ \ + IMASK_UNLOCK ; /* exit critical reg */ \ popl %es ; \ popl %ds ; \ popal ; \ @@ -62,43 +69,28 @@ iret ; \ ; \ ALIGN_TEXT ; \ -1: -#endif +1: ; \ + GET_MPLOCK /* SMP Spin lock */ + +#endif /* PEND_INTS */ + -#if 1 #define MAYBE_UNMASK_IRQ(irq_num) \ cli ; /* must unmask _apic_imen and IO APIC atomically */ \ lock ; /* MP-safe */ \ andl $~IRQ_BIT(irq_num),iactive ; \ IMASK_LOCK ; /* enter critical reg */\ testl $IRQ_BIT(irq_num),_apic_imen ; \ - je 2f ; \ + je 9f ; \ andl $~IRQ_BIT(irq_num),_apic_imen ; /* clear mask bit */ \ movl _ioapic,%ecx ; /* ioapic[0]addr */ \ movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \ andl $~IOART_INTMASK,%eax ; /* clear the mask */ \ movl %eax,IOAPIC_WINDOW(%ecx) ; /* new value */ \ -2: ; \ +9: ; \ IMASK_UNLOCK ; /* exit critical reg */ \ sti /* XXX _doreti repeats the cli/sti */ -#else -#define MAYBE_UNMASK_IRQ(irq_num) \ - cli ; /* must unmask _apic_imen and IO APIC atomically */ \ - lock ; /* MP-safe */ \ - andl $~IRQ_BIT(irq_num),iactive ; \ - /* XXX atomic access */ \ - testl $IRQ_BIT(irq_num),_apic_imen ; \ - je 2f ; \ - andl $~IRQ_BIT(irq_num),_apic_imen ; /* clear mask bit */ \ - movl _ioapic,%ecx ; /* ioapic[0]addr */ \ - movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \ - movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \ - andl $~IOART_INTMASK,%eax ; /* clear the mask */ \ - movl %eax,IOAPIC_WINDOW(%ecx) ; /* new value */ \ -2: ; \ - sti ; /* XXX _doreti repeats the cli/sti */ -#endif /* @@ -118,7 +110,7 @@ IDTVEC(vec_name) ; \ movl %ax,%ds ; \ MAYBE_MOVW_AX_ES ; \ FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ - GET_MPLOCK ; /* SMP Spin lock */ \ + GET_MPLOCK ; \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ movl $0, lapic_eoi ; \ diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index a9d2110..5b54178 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.6 1997/07/22 18:36:06 smp Exp smp $ + * $Id: clock.c,v 1.97 1997/07/22 20:12:04 fsmp Exp $ */ /* @@ -66,7 +66,7 @@ #include <machine/ipl.h> #ifdef APIC_IO #include <machine/smp.h> -#include <machine/smptests.h> /** TEST_ALTTIMER, APIC_PIN0_TIMER */ +#include <machine/smptests.h> /** NEW_STRATEGY (,SMP_TIMER_NC) */ #endif /* APIC_IO */ #include <i386/isa/icu.h> @@ -860,6 +860,10 @@ cpu_initclocks() #ifdef APIC_IO #ifdef NEW_STRATEGY +#ifdef SMP_TIMER_NC +#error 'options SMP_TIMER_NC' no longer used, remove & reconfig. +#endif /** XXX SMP_TIMER_NC */ + /* 1st look for ExtInt on pin 0 */ if (apic_int_type(0, 0) == 3) { /* @@ -868,7 +872,7 @@ cpu_initclocks() * reset; prog 4 bytes, single ICU, edge triggered */ outb(IO_ICU1, 0x13); - outb(IO_ICU1 + 1, NRSVIDT); /* start vector */ + outb(IO_ICU1 + 1, NRSVIDT); /* start vector (unused) */ outb(IO_ICU1 + 1, 0x00); /* ignore slave */ outb(IO_ICU1 + 1, 0x03); /* auto EOI, 8086 */ outb(IO_ICU1 + 1, 0xfe); /* unmask INT0 */ @@ -878,14 +882,14 @@ cpu_initclocks() panic("8254 redirect via APIC pin0 impossible!"); x = 0; - /** if (bootverbose */ + /* XXX if (bootverbose) */ printf("APIC_IO: routing 8254 via 8259 on pin 0\n"); } /* failing that, look for 8254 on pin 2 */ else if (isa_apic_pin(0) == 2) { x = 2; - /** if (bootverbose */ + /* XXX if (bootverbose) */ printf("APIC_IO: routing 8254 via pin 2\n"); } @@ -893,62 +897,24 @@ cpu_initclocks() else panic("neither pin 0 or pin 2 works for 8254"); - /* setup the vectors for the chosen method */ - vec[x] = (u_int)vec8254; - Xintr8254 = (u_int)ivectors[x]; - mask8254 = (1 << x); - - register_intr(/* irq */ x, /* XXX id */ 0, /* flags */ 0, - /* XXX */ (inthand2_t *)clkintr, &clk_imask, - /* unit */ 0); - INTREN(mask8254); - #else /** NEW_STRATEGY */ -#ifdef APIC_PIN0_TIMER - /* - * Allow 8254 timer to INTerrupt 8259: - * re-initialize master 8259: - * reset; prog 4 bytes, single ICU, edge triggered - */ - outb(IO_ICU1, 0x13); - outb(IO_ICU1 + 1, NRSVIDT); /* start vector */ - outb(IO_ICU1 + 1, 0x00); /* ignore slave */ - outb(IO_ICU1 + 1, 0x03); /* auto EOI, 8086 */ - outb(IO_ICU1 + 1, 0xfe); /* unmask INT0 */ - - /* program IO APIC for type 3 INT on INT0 */ - if (ext_int_setup(0, 0) < 0) - panic("8254 redirect via APIC pin0 impossible!"); - - register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, - /* XXX */ (inthand2_t *)clkintr, &clk_imask, - /* unit */ 0); - INTREN(APIC_IRQ0); -#else /* APIC_PIN0_TIMER */ /* 8254 is traditionally on ISA IRQ0 */ - if ((x = isa_apic_pin(0)) < 0) { +#if defined(SMP_TIMER_NC) + x = -1; +#else + x = isa_apic_pin(0); +#endif /** XXX SMP_TIMER_NC */ + + if (x < 0) { /* bummer, attempt to redirect thru the 8259 */ if (bootverbose) printf("APIC missing 8254 connection\n"); /* allow 8254 timer to INTerrupt 8259 */ -#ifdef TEST_ALTTIMER - /* - * re-initialize master 8259: - * reset; prog 4 bytes, single ICU, edge triggered - */ - outb(IO_ICU1, 0x13); - outb(IO_ICU1 + 1, NRSVIDT); /* start vector */ - outb(IO_ICU1 + 1, 0x00); /* ignore slave */ - outb(IO_ICU1 + 1, 0x03); /* auto EOI, 8086 */ - - outb(IO_ICU1 + 1, 0xfe); /* unmask INT0 */ -#else x = inb(IO_ICU1 + 1); /* current mask in 8259 */ x &= ~1; /* clear 8254 timer mask */ outb(IO_ICU1 + 1, x); /* write new mask */ -#endif /* TEST_ALTTIMER */ /* program IO APIC for type 3 INT on INT0 */ if (ext_int_setup(0, 0) < 0) @@ -956,22 +922,25 @@ cpu_initclocks() x = 0; /* 8259 is on 0 */ } +#endif /** NEW_STRATEGY */ + + /* setup the vectors */ vec[x] = (u_int)vec8254; - Xintr8254 = (u_int)ivectors[x]; /* XXX might need Xfastintr# */ + Xintr8254 = (u_int)ivectors[x]; mask8254 = (1 << x); + register_intr(/* irq */ x, /* XXX id */ 0, /* flags */ 0, /* XXX */ (inthand2_t *)clkintr, &clk_imask, /* unit */ 0); INTREN(mask8254); -#endif /* APIC_PIN0_TIMER */ - -#endif /** NEW_STRATEGY */ #else /* APIC_IO */ + register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, /* XXX */ (inthand2_t *)clkintr, &clk_imask, /* unit */ 0); INTREN(IRQ0); + #endif /* APIC_IO */ #if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) |