diff options
author | fsmp <fsmp@FreeBSD.org> | 1997-08-29 18:45:23 +0000 |
---|---|---|
committer | fsmp <fsmp@FreeBSD.org> | 1997-08-29 18:45:23 +0000 |
commit | 13fe237edc09b0964851ff000267e07797dff742 (patch) | |
tree | 720c917319b77866f197246120cfb757f4af2d6e /sys/i386 | |
parent | cf2671c51e058f96fb3318fe2053f587bc6eeebe (diff) | |
download | FreeBSD-src-13fe237edc09b0964851ff000267e07797dff742.zip FreeBSD-src-13fe237edc09b0964851ff000267e07797dff742.tar.gz |
Support for the new FAST_HI algorithm, enabled.
Preliminary support for the INTR_SIMPLELOCK algorithm, disabled.
Note that this code is NOT ready.
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/i386/apic_vector.s | 91 | ||||
-rw-r--r-- | sys/i386/isa/apic_ipl.s | 18 | ||||
-rw-r--r-- | sys/i386/isa/apic_vector.s | 91 | ||||
-rw-r--r-- | sys/i386/isa/intr_machdep.c | 42 | ||||
-rw-r--r-- | sys/i386/isa/intr_machdep.h | 77 | ||||
-rw-r--r-- | sys/i386/isa/ipl.s | 47 | ||||
-rw-r--r-- | sys/i386/isa/ipl_funcs.c | 4 | ||||
-rw-r--r-- | sys/i386/isa/nmi.c | 42 |
8 files changed, 332 insertions, 80 deletions
diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index 71c341d..d78d320 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.27 1997/08/23 05:15:12 smp Exp smp $ + * $Id: apic_vector.s,v 1.32 1997/08/29 18:37:23 smp Exp smp $ */ @@ -11,17 +11,17 @@ #include "i386/isa/intr_machdep.h" -#if defined(SMP) && defined(REAL_AVCPL) +#ifdef REAL_AVCPL #define AVCPL_LOCK CPL_LOCK #define AVCPL_UNLOCK CPL_UNLOCK -#else +#else /* REAL_AVCPL */ #define AVCPL_LOCK #define AVCPL_UNLOCK -#endif +#endif /* REAL_AVCPL */ #ifdef FAST_SIMPLELOCK @@ -213,6 +213,8 @@ IDTVEC(vec_name) ; \ 9: ; \ IMASK_UNLOCK +#ifdef INTR_SIMPLELOCK + #define INTR(irq_num, vec_name) \ .text ; \ SUPERALIGN_TEXT ; \ @@ -233,6 +235,8 @@ IDTVEC(vec_name) ; \ AVCPL_LOCK ; /* MP-safe */ \ testl $IRQ_BIT(irq_num), _cpl ; \ jne 2f ; /* this INT masked */ \ + testl $IRQ_BIT(irq_num), _cml ; \ + jne 2f ; /* this INT masked */ \ orl $IRQ_BIT(irq_num), _cil ; \ AVCPL_UNLOCK ; \ ; \ @@ -245,6 +249,75 @@ __CONCAT(Xresume,irq_num): ; \ lock ; incl (%eax) ; \ ; \ AVCPL_LOCK ; /* MP-safe */ \ + movl _cml, %eax ; \ + pushl %eax ; \ + orl _intr_mask + (irq_num) * 4, %eax ; \ + movl %eax, _cml ; \ + AVCPL_UNLOCK ; \ +; \ + pushl _intr_unit + (irq_num) * 4 ; \ + sti ; \ + call *_intr_handler + (irq_num) * 4 ; \ + cli ; \ +; \ + lock ; andl $~IRQ_BIT(irq_num), iactive ; \ + lock ; andl $~IRQ_BIT(irq_num), _cil ; \ + UNMASK_IRQ(irq_num) ; \ + sti ; /* doreti repeats cli/sti */ \ + MEXITCOUNT ; \ + jmp _doreti ; \ +; \ + ALIGN_TEXT ; \ +1: ; /* active or locked */ \ + MASK_LEVEL_IRQ(irq_num) ; \ + movl $0, lapic_eoi ; /* do the EOI */ \ +; \ + AVCPL_LOCK ; /* MP-safe */ \ + orl $IRQ_BIT(irq_num), _ipending ; \ + AVCPL_UNLOCK ; \ +; \ + POP_FRAME ; \ + iret ; \ +; \ + ALIGN_TEXT ; \ +2: ; /* masked by cpl|cml */ \ + AVCPL_UNLOCK ; \ + ISR_RELLOCK ; /* XXX this is going away... */ \ + jmp 1b + +#else /* INTR_SIMPLELOCK */ + +#define INTR(irq_num, vec_name) \ + .text ; \ + SUPERALIGN_TEXT ; \ +IDTVEC(vec_name) ; \ + PUSH_FRAME ; \ + movl $KDSEL, %eax ; /* reload with kernel's data segment */ \ + movl %ax, %ds ; \ + movl %ax, %es ; \ +; \ + lock ; /* MP-safe */ \ + btsl $(irq_num), iactive ; /* lazy masking */ \ + jc 1f ; /* already active */ \ +; \ + ISR_TRYLOCK ; /* XXX this is going away... */ \ + testl %eax, %eax ; /* did we get it? */ \ + jz 1f ; /* no */ \ +; \ + AVCPL_LOCK ; /* MP-safe */ \ + testl $IRQ_BIT(irq_num), _cpl ; \ + jne 2f ; /* this INT masked */ \ + AVCPL_UNLOCK ; \ +; \ + movl $0, lapic_eoi ; /* XXX too soon? */ \ + incb _intr_nesting_level ; \ +__CONCAT(Xresume,irq_num): ; \ + FAKE_MCOUNT(12*4(%esp)) ; /* XXX avoid dbl cnt */ \ + lock ; incl _cnt+V_INTR ; /* tally interrupts */ \ + movl _intr_countp + (irq_num) * 4, %eax ; \ + lock ; incl (%eax) ; \ +; \ + AVCPL_LOCK ; /* MP-safe */ \ movl _cpl, %eax ; \ pushl %eax ; \ orl _intr_mask + (irq_num) * 4, %eax ; \ @@ -280,6 +353,8 @@ __CONCAT(Xresume,irq_num): ; \ ISR_RELLOCK ; /* XXX this is going away... */ \ jmp 1b +#endif /* INTR_SIMPLELOCK */ + /* * Handle "spurious INTerrupts". @@ -344,23 +419,15 @@ _Xcpustop: movl _cpuid, %eax - ASMPOSTCODE_HI(0x1) - lock btsl %eax, _stopped_cpus /* stopped_cpus |= (1<<id) */ - - ASMPOSTCODE_HI(0x2); 1: btl %eax, _started_cpus /* while (!(started_cpus & (1<<id))) */ jnc 1b - ASMPOSTCODE_HI(0x3) - lock btrl %eax, _started_cpus /* started_cpus &= ~(1<<id) */ - ASMPOSTCODE_HI(0x4) - movl $0, lapic_eoi /* End Of Interrupt to APIC */ popl %ds /* restore previous data segment */ diff --git a/sys/i386/isa/apic_ipl.s b/sys/i386/isa/apic_ipl.s index ec9b94f..6df74c3 100644 --- a/sys/i386/isa/apic_ipl.s +++ b/sys/i386/isa/apic_ipl.s @@ -22,21 +22,21 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: apic_ipl.s,v 1.28 1997/08/23 05:15:12 smp Exp smp $ + * $Id: apic_ipl.s,v 1.32 1997/08/29 18:39:36 smp Exp smp $ */ -#if defined(SMP) && defined(REAL_AICPL) +#ifdef REAL_AICPL #define AICPL_LOCK SCPL_LOCK #define AICPL_UNLOCK SCPL_UNLOCK -#else /* SMP */ +#else /* REAL_AICPL */ #define AICPL_LOCK #define AICPL_UNLOCK -#endif /* SMP */ +#endif /* REAL_AICPL */ .data ALIGN_DATA @@ -45,6 +45,10 @@ .globl _cil _cil: .long 0 +/* current INTerrupt level mask */ + .globl _cml +_cml: .long 0 + /* this allows us to change the 8254 APIC pin# assignment */ .globl _Xintr8254 _Xintr8254: @@ -107,6 +111,9 @@ ENTRY(splz) */ AICPL_LOCK movl _cpl,%eax +#ifdef INTR_SIMPLELOCK + orl _cml, %eax /* add cml to cpl */ +#endif splz_next: /* * We don't need any locking here. (ipending & ~cpl) cannot grow @@ -137,6 +144,9 @@ splz_unpend: * frame. Also, there's a problem determining the unit number. * We should change the interface so that the unit number is not * determined at config time. + * + * The vec[] routines build the proper frame on the stack, + * then call one of _Xintr0 thru _Xintr23 */ jmp *_vec(,%ecx,4) diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s index 71c341d..d78d320 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.27 1997/08/23 05:15:12 smp Exp smp $ + * $Id: apic_vector.s,v 1.32 1997/08/29 18:37:23 smp Exp smp $ */ @@ -11,17 +11,17 @@ #include "i386/isa/intr_machdep.h" -#if defined(SMP) && defined(REAL_AVCPL) +#ifdef REAL_AVCPL #define AVCPL_LOCK CPL_LOCK #define AVCPL_UNLOCK CPL_UNLOCK -#else +#else /* REAL_AVCPL */ #define AVCPL_LOCK #define AVCPL_UNLOCK -#endif +#endif /* REAL_AVCPL */ #ifdef FAST_SIMPLELOCK @@ -213,6 +213,8 @@ IDTVEC(vec_name) ; \ 9: ; \ IMASK_UNLOCK +#ifdef INTR_SIMPLELOCK + #define INTR(irq_num, vec_name) \ .text ; \ SUPERALIGN_TEXT ; \ @@ -233,6 +235,8 @@ IDTVEC(vec_name) ; \ AVCPL_LOCK ; /* MP-safe */ \ testl $IRQ_BIT(irq_num), _cpl ; \ jne 2f ; /* this INT masked */ \ + testl $IRQ_BIT(irq_num), _cml ; \ + jne 2f ; /* this INT masked */ \ orl $IRQ_BIT(irq_num), _cil ; \ AVCPL_UNLOCK ; \ ; \ @@ -245,6 +249,75 @@ __CONCAT(Xresume,irq_num): ; \ lock ; incl (%eax) ; \ ; \ AVCPL_LOCK ; /* MP-safe */ \ + movl _cml, %eax ; \ + pushl %eax ; \ + orl _intr_mask + (irq_num) * 4, %eax ; \ + movl %eax, _cml ; \ + AVCPL_UNLOCK ; \ +; \ + pushl _intr_unit + (irq_num) * 4 ; \ + sti ; \ + call *_intr_handler + (irq_num) * 4 ; \ + cli ; \ +; \ + lock ; andl $~IRQ_BIT(irq_num), iactive ; \ + lock ; andl $~IRQ_BIT(irq_num), _cil ; \ + UNMASK_IRQ(irq_num) ; \ + sti ; /* doreti repeats cli/sti */ \ + MEXITCOUNT ; \ + jmp _doreti ; \ +; \ + ALIGN_TEXT ; \ +1: ; /* active or locked */ \ + MASK_LEVEL_IRQ(irq_num) ; \ + movl $0, lapic_eoi ; /* do the EOI */ \ +; \ + AVCPL_LOCK ; /* MP-safe */ \ + orl $IRQ_BIT(irq_num), _ipending ; \ + AVCPL_UNLOCK ; \ +; \ + POP_FRAME ; \ + iret ; \ +; \ + ALIGN_TEXT ; \ +2: ; /* masked by cpl|cml */ \ + AVCPL_UNLOCK ; \ + ISR_RELLOCK ; /* XXX this is going away... */ \ + jmp 1b + +#else /* INTR_SIMPLELOCK */ + +#define INTR(irq_num, vec_name) \ + .text ; \ + SUPERALIGN_TEXT ; \ +IDTVEC(vec_name) ; \ + PUSH_FRAME ; \ + movl $KDSEL, %eax ; /* reload with kernel's data segment */ \ + movl %ax, %ds ; \ + movl %ax, %es ; \ +; \ + lock ; /* MP-safe */ \ + btsl $(irq_num), iactive ; /* lazy masking */ \ + jc 1f ; /* already active */ \ +; \ + ISR_TRYLOCK ; /* XXX this is going away... */ \ + testl %eax, %eax ; /* did we get it? */ \ + jz 1f ; /* no */ \ +; \ + AVCPL_LOCK ; /* MP-safe */ \ + testl $IRQ_BIT(irq_num), _cpl ; \ + jne 2f ; /* this INT masked */ \ + AVCPL_UNLOCK ; \ +; \ + movl $0, lapic_eoi ; /* XXX too soon? */ \ + incb _intr_nesting_level ; \ +__CONCAT(Xresume,irq_num): ; \ + FAKE_MCOUNT(12*4(%esp)) ; /* XXX avoid dbl cnt */ \ + lock ; incl _cnt+V_INTR ; /* tally interrupts */ \ + movl _intr_countp + (irq_num) * 4, %eax ; \ + lock ; incl (%eax) ; \ +; \ + AVCPL_LOCK ; /* MP-safe */ \ movl _cpl, %eax ; \ pushl %eax ; \ orl _intr_mask + (irq_num) * 4, %eax ; \ @@ -280,6 +353,8 @@ __CONCAT(Xresume,irq_num): ; \ ISR_RELLOCK ; /* XXX this is going away... */ \ jmp 1b +#endif /* INTR_SIMPLELOCK */ + /* * Handle "spurious INTerrupts". @@ -344,23 +419,15 @@ _Xcpustop: movl _cpuid, %eax - ASMPOSTCODE_HI(0x1) - lock btsl %eax, _stopped_cpus /* stopped_cpus |= (1<<id) */ - - ASMPOSTCODE_HI(0x2); 1: btl %eax, _started_cpus /* while (!(started_cpus & (1<<id))) */ jnc 1b - ASMPOSTCODE_HI(0x3) - lock btrl %eax, _started_cpus /* started_cpus &= ~(1<<id) */ - ASMPOSTCODE_HI(0x4) - movl $0, lapic_eoi /* End Of Interrupt to APIC */ popl %ds /* restore previous data segment */ diff --git a/sys/i386/isa/intr_machdep.c b/sys/i386/isa/intr_machdep.c index 5f241d6..c9b5da5 100644 --- a/sys/i386/isa/intr_machdep.c +++ b/sys/i386/isa/intr_machdep.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.3 1997/06/22 16:04:04 peter Exp $ + * $Id: intr_machdep.c,v 1.1 1997/08/29 18:38:35 smp Exp smp $ */ #include "opt_auto_eoi.h" @@ -47,6 +47,7 @@ #include <machine/segments.h> #if defined(APIC_IO) #include <machine/smp.h> +#include <machine/smptests.h> /** FAST_HI */ #endif /* APIC_IO */ #include <i386/isa/isa_device.h> #ifdef PC98 @@ -260,9 +261,17 @@ int isa_irq_pending(dvp) struct isa_device *dvp; { - /* read APIC IRR containing the 16 ISA INTerrupts */ - return ((lapic.irr1 & 0x00ffffff) - & (u_int32_t)dvp->id_irq) ? 1 : 0; +#ifdef FAST_HI +/* XXX not quite right for >1 IO APIC yet */ + if (dvp->id_ri_flags & RI_FAST) + /* read APIC IRR containing the FAST INTerrupts */ + return ((lapic.irr3 & 0x00ffffff) + & (u_int32_t)dvp->id_irq) ? 1 : 0; + else +#endif /* FAST_HI */ + /* read APIC IRR containing the SLOW INTerrupts */ + return ((lapic.irr1 & 0x00ffffff) + & (u_int32_t)dvp->id_irq) ? 1 : 0; } /* @@ -396,6 +405,11 @@ update_intrname(int intr, int device_id) int icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) { +#ifdef FAST_HI + int select; /* the select register is 8 bits */ + int vector; + u_int32_t value; /* the window register is 32 bits */ +#endif /* FAST_HI */ u_long ef; u_int mask = (maskptr ? *maskptr : 0); @@ -413,9 +427,29 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) intr_mptr[intr] = maskptr; intr_mask[intr] = mask | (1 << intr); intr_unit[intr] = (int) arg; +#ifdef FAST_HI + if (flags & INTR_FAST) { + vector = TPR_FAST_INTS + intr; + setidt(vector, fastintr[intr], + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + + /* + * XXX MULTIPLE_IOAPICSXXX + * Reprogram the vector in the IO APIC. + */ + select = (intr * 2) + IOAPIC_REDTBL0; + value = io_apic_read(0, select) & ~IOART_INTVEC; + io_apic_write(0, select, value | vector); + } + else + setidt(TPR_SLOW_INTS + intr, slowintr[intr], + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + +#else setidt(ICU_OFFSET + intr, flags & INTR_FAST ? fastintr[intr] : slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#endif /* FAST_HI */ INTREN(1 << intr); write_eflags(ef); return (0); diff --git a/sys/i386/isa/intr_machdep.h b/sys/i386/isa/intr_machdep.h index c164799..6df8f3a 100644 --- a/sys/i386/isa/intr_machdep.h +++ b/sys/i386/isa/intr_machdep.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)isa_device.h 7.1 (Berkeley) 5/9/91 - * $Id: intr_machdep.h,v 1.5 1997/07/18 21:27:14 fsmp Exp $ + * $Id: intr_machdep.h,v 1.10 1997/08/29 18:37:23 smp Exp smp $ */ #ifndef _I386_ISA_INTR_MACHDEP_H_ @@ -50,43 +50,50 @@ /* APIC TPR priority vector levels: - 0xff (255) +------------+ - | | 15 (IPIs: Xspuriousint) - 0xf0 (240) +------------+ - | | 14 - 0xe0 (224) +------------+ - | | 13 - 0xd0 (208) +------------+ - | | 12 - 0xc0 (192) +------------+ - | | 11 - 0xb0 (176) +------------+ - | | 10 (IPIs: Xcpustop) - 0xa0 (160) +------------+ - | | 9 (IPIs: Xinvltlb) - 0x90 (144) +------------+ - | | 8 (linux compat @ vector 0x80) - 0x80 (128) +------------+ - | | 7 - 0x70 (112) +------------+ - | | 6 - 0x60 (96) +------------+ - | | 5 - 0x50 (80) +------------+ - | | 4 - 0x40 (64) +------------+ - | | 3 (upper APIC hardware INTs: PCI) - 0x30 (48) +------------+ - | | 2 (start of hardware INTs: ISA) - 0x20 (32) +------------+ - | | 1 (exceptions, traps, etc.) - 0x10 (16) +------------+ - | | 0 (exceptions, traps, etc.) - 0x00 (0) +------------+ + 0xff (255) +-------------+ + | | 15 (IPIs: Xspuriousint) + 0xf0 (240) +-------------+ + | | 14 + 0xe0 (224) +-------------+ + | | 13 + 0xd0 (208) +-------------+ + | | 12 + 0xc0 (192) +-------------+ + | | 11 + 0xb0 (176) +-------------+ + | | 10 (IPIs: Xcpustop) + 0xa0 (160) +-------------+ + | | 9 (IPIs: Xinvltlb) + 0x90 (144) +-------------+ + | | 8 (linux/BSD syscall, IGNORE FAST HW INTS) + 0x80 (128) +-------------+ + | | 7 (FAST_INTR 16-23) + 0x70 (112) +-------------+ + | | 6 (FAST_INTR 0-15) + 0x60 (96) +-------------+ + | | 5 (IGNORE HW INTS) + 0x50 (80) +-------------+ + | | 4 (2nd IO APIC) + 0x40 (64) +------+------+ + | | | 3 (upper APIC hardware INTs: PCI) + 0x30 (48) +------+------+ + | | 2 (start of hardware INTs: ISA) + 0x20 (32) +-------------+ + | | 1 (exceptions, traps, etc.) + 0x10 (16) +-------------+ + | | 0 (exceptions, traps, etc.) + 0x00 (0) +-------------+ */ +/* IDT vector base for regular (aka. slow) and fast interrupts */ +#define TPR_SLOW_INTS 0x20 +#define TPR_FAST_INTS 0x60 + /* blocking values for local APIC Task Priority Register */ -#define TPR_BLOCK_HWI 0x3f /* hardware INTs */ +#define TPR_BLOCK_HWI 0x4f /* hardware INTs */ +#define TPR_IGNORE_HWI 0x5f /* ignore INTs */ +#define TPR_BLOCK_FHWI 0x7f /* hardware FAST INTs */ +#define TPR_IGNORE_FHWI 0x8f /* ignore FAST INTs */ #define TPR_BLOCK_XINVLTLB 0x9f /* */ #define TPR_BLOCK_XCPUSTOP 0xaf /* */ #define TPR_BLOCK_ALL 0xff /* all INTs */ diff --git a/sys/i386/isa/ipl.s b/sys/i386/isa/ipl.s index 6393882..481f886 100644 --- a/sys/i386/isa/ipl.s +++ b/sys/i386/isa/ipl.s @@ -36,23 +36,23 @@ * * @(#)ipl.s * - * $Id: ipl.s,v 1.13 1997/08/23 05:15:12 smp Exp smp $ + * $Id: ipl.s,v 1.16 1997/08/28 09:51:32 smp Exp smp $ */ -#if defined(SMP) && defined(REAL_ICPL) +#ifdef REAL_ICPL #define ICPL_LOCK CPL_LOCK #define ICPL_UNLOCK CPL_UNLOCK #define FAST_ICPL_UNLOCK movl $0, _cpl_lock -#else /* SMP */ +#else /* REAL_ICPL */ #define ICPL_LOCK #define ICPL_UNLOCK #define FAST_ICPL_UNLOCK -#endif /* SMP */ +#endif /* REAL_ICPL */ /* * AT/386 @@ -108,7 +108,7 @@ _netisrs: _doreti: FAKE_MCOUNT(_bintr) /* init "from" _bintr -> _doreti */ addl $4,%esp /* discard unit number */ - popl %eax /* cpl to restore */ + popl %eax /* cpl or cml to restore */ doreti_next: /* * Check for pending HWIs and SWIs atomically with restoring cpl @@ -126,6 +126,9 @@ doreti_next: movl %edx, %eax #endif movl %eax,%ecx +#ifdef INTR_SIMPLELOCK + orl _cpl, %ecx /* add cpl to cml */ +#endif notl %ecx /* set bit = unmasked level */ #ifndef SMP cli @@ -133,11 +136,19 @@ doreti_next: andl _ipending,%ecx /* set bit = unmasked pending INT */ jne doreti_unpend doreti_exit: +#ifdef INTR_SIMPLELOCK + movl %eax, _cml +#else movl %eax,_cpl +#endif FAST_ICPL_UNLOCK /* preserves %eax */ MPLOCKED decb _intr_nesting_level MEXITCOUNT #ifdef VM86 +#ifdef INTR_SIMPLELOCK + /* XXX INTR_SIMPLELOCK needs work */ +#error not ready for vm86 +#endif /* * XXX * Sometimes when attempting to return to vm86 mode, cpl is not @@ -158,6 +169,9 @@ doreti_stop: #endif /* VM86 */ #ifdef SMP +#ifdef INTR_SIMPLELOCK +/**#error code needed here to decide which lock to release, INTR or giant*/ +#endif /* release the kernel lock */ pushl $_mp_lock /* GIANT_LOCK */ call _MPrellock @@ -211,6 +225,11 @@ doreti_unpend: btrl %ecx,_ipending #endif /* SMP */ jnc doreti_next /* some intr cleared memory copy */ + + /* + * setup call to _Xresume0 thru _Xresume23 for hwi, + * or swi_tty, swi_net, _softclock, swi_ast for swi. + */ movl ihandlers(,%ecx,4),%edx testl %edx,%edx je doreti_next /* "can't happen" */ @@ -220,7 +239,11 @@ doreti_unpend: #ifdef SMP pushl %eax /* preserve %eax */ ICPL_LOCK +#ifdef INTR_SIMPLELOCK + popl _cml +#else popl _cpl +#endif FAST_ICPL_UNLOCK #else movl %eax,_cpl @@ -243,9 +266,13 @@ doreti_swi: #ifdef SMP orl imasks(,%ecx,4), %eax cli /* prevent INT deadlock */ - pushl %eax /* save cpl */ + pushl %eax /* save cpl|cmpl */ ICPL_LOCK +#ifdef INTR_SIMPLELOCK + popl _cml /* restore cml */ +#else popl _cpl /* restore cpl */ +#endif FAST_ICPL_UNLOCK sti #else @@ -265,7 +292,10 @@ swi_ast_user: movl $T_ASTFLT,(2+8+0)*4(%esp) movb $0,_intr_nesting_level /* finish becoming a trap handler */ call _trap - subl %eax,%eax /* recover cpl */ + subl %eax,%eax /* recover cpl|cml */ +#ifdef INTR_SIMPLELOCK + movl %eax, _cpl +#endif movb $1,_intr_nesting_level /* for doreti_next to decrement */ jmp doreti_next @@ -291,6 +321,9 @@ swi_ast_phantom: orl $SWI_AST_PENDING, _ipending /* cpl is unlocked in doreti_exit */ subl %eax,%eax +#ifdef INTR_SIMPLELOCK + movl %eax, _cpl +#endif jmp doreti_exit /* SWI_AST is highest so we must be done */ diff --git a/sys/i386/isa/ipl_funcs.c b/sys/i386/isa/ipl_funcs.c index 78977eb..ecc34e7 100644 --- a/sys/i386/isa/ipl_funcs.c +++ b/sys/i386/isa/ipl_funcs.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ipl_funcs.c,v 1.7 1997/08/24 20:18:28 smp Exp smp $ + * $Id: ipl_funcs.c,v 1.8 1997/08/28 09:51:32 smp Exp smp $ */ #include <sys/types.h> @@ -100,7 +100,7 @@ splx(unsigned ipl) #include <machine/smp.h> extern int bspEarly; /* XXX */ -#if defined(REAL_IFCPL) +#ifdef REAL_IFCPL #define IFCPL_LOCK() SCPL_LOCK() #define IFCPL_UNLOCK() SCPL_UNLOCK() diff --git a/sys/i386/isa/nmi.c b/sys/i386/isa/nmi.c index 5f241d6..c9b5da5 100644 --- a/sys/i386/isa/nmi.c +++ b/sys/i386/isa/nmi.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.3 1997/06/22 16:04:04 peter Exp $ + * $Id: intr_machdep.c,v 1.1 1997/08/29 18:38:35 smp Exp smp $ */ #include "opt_auto_eoi.h" @@ -47,6 +47,7 @@ #include <machine/segments.h> #if defined(APIC_IO) #include <machine/smp.h> +#include <machine/smptests.h> /** FAST_HI */ #endif /* APIC_IO */ #include <i386/isa/isa_device.h> #ifdef PC98 @@ -260,9 +261,17 @@ int isa_irq_pending(dvp) struct isa_device *dvp; { - /* read APIC IRR containing the 16 ISA INTerrupts */ - return ((lapic.irr1 & 0x00ffffff) - & (u_int32_t)dvp->id_irq) ? 1 : 0; +#ifdef FAST_HI +/* XXX not quite right for >1 IO APIC yet */ + if (dvp->id_ri_flags & RI_FAST) + /* read APIC IRR containing the FAST INTerrupts */ + return ((lapic.irr3 & 0x00ffffff) + & (u_int32_t)dvp->id_irq) ? 1 : 0; + else +#endif /* FAST_HI */ + /* read APIC IRR containing the SLOW INTerrupts */ + return ((lapic.irr1 & 0x00ffffff) + & (u_int32_t)dvp->id_irq) ? 1 : 0; } /* @@ -396,6 +405,11 @@ update_intrname(int intr, int device_id) int icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) { +#ifdef FAST_HI + int select; /* the select register is 8 bits */ + int vector; + u_int32_t value; /* the window register is 32 bits */ +#endif /* FAST_HI */ u_long ef; u_int mask = (maskptr ? *maskptr : 0); @@ -413,9 +427,29 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) intr_mptr[intr] = maskptr; intr_mask[intr] = mask | (1 << intr); intr_unit[intr] = (int) arg; +#ifdef FAST_HI + if (flags & INTR_FAST) { + vector = TPR_FAST_INTS + intr; + setidt(vector, fastintr[intr], + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + + /* + * XXX MULTIPLE_IOAPICSXXX + * Reprogram the vector in the IO APIC. + */ + select = (intr * 2) + IOAPIC_REDTBL0; + value = io_apic_read(0, select) & ~IOART_INTVEC; + io_apic_write(0, select, value | vector); + } + else + setidt(TPR_SLOW_INTS + intr, slowintr[intr], + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + +#else setidt(ICU_OFFSET + intr, flags & INTR_FAST ? fastintr[intr] : slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#endif /* FAST_HI */ INTREN(1 << intr); write_eflags(ef); return (0); |