From 34162fc615946cb6eaa1adf0bd2c779856665e72 Mon Sep 17 00:00:00 2001 From: Steve Passe Date: Fri, 29 Aug 1997 18:45:23 +0000 Subject: [PATCH] Support for the new FAST_HI algorithm, enabled. Preliminary support for the INTR_SIMPLELOCK algorithm, disabled. Note that this code is NOT ready. --- sys/amd64/amd64/apic_vector.S | 91 ++++++++++++++++++++++++++++++----- sys/amd64/isa/intr_machdep.c | 42 ++++++++++++++-- sys/amd64/isa/intr_machdep.h | 77 +++++++++++++++-------------- sys/amd64/isa/nmi.c | 42 ++++++++++++++-- sys/i386/i386/apic_vector.s | 91 ++++++++++++++++++++++++++++++----- sys/i386/isa/apic_ipl.s | 18 +++++-- sys/i386/isa/apic_vector.s | 91 ++++++++++++++++++++++++++++++----- sys/i386/isa/intr_machdep.c | 42 ++++++++++++++-- sys/i386/isa/intr_machdep.h | 77 +++++++++++++++-------------- sys/i386/isa/ipl.s | 47 +++++++++++++++--- sys/i386/isa/ipl_funcs.c | 4 +- sys/i386/isa/nmi.c | 42 ++++++++++++++-- 12 files changed, 529 insertions(+), 135 deletions(-) diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index 71c341dcf86..d78d3202df9 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.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 ; \ ; \ @@ -243,6 +247,75 @@ __CONCAT(Xresume,irq_num): ; \ lock ; incl _cnt+V_INTR ; /* tally interrupts */ \ movl _intr_countp + (irq_num) * 4, %eax ; \ 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 ; \ @@ -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< #if defined(APIC_IO) #include +#include /** FAST_HI */ #endif /* APIC_IO */ #include #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/amd64/isa/intr_machdep.h b/sys/amd64/isa/intr_machdep.h index c1647991e80..6df8f3a96bf 100644 --- a/sys/amd64/isa/intr_machdep.h +++ b/sys/amd64/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/amd64/isa/nmi.c b/sys/amd64/isa/nmi.c index 5f241d651b6..c9b5da541ce 100644 --- a/sys/amd64/isa/nmi.c +++ b/sys/amd64/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 #if defined(APIC_IO) #include +#include /** FAST_HI */ #endif /* APIC_IO */ #include #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/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index 71c341dcf86..d78d3202df9 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 ; \ ; \ @@ -243,6 +247,75 @@ __CONCAT(Xresume,irq_num): ; \ lock ; incl _cnt+V_INTR ; /* tally interrupts */ \ movl _intr_countp + (irq_num) * 4, %eax ; \ 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 ; \ @@ -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< #if defined(APIC_IO) #include +#include /** FAST_HI */ #endif /* APIC_IO */ #include #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 c1647991e80..6df8f3a96bf 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 6393882b90a..481f8861913 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 78977eb25ac..ecc34e7ecdc 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 @@ -100,7 +100,7 @@ splx(unsigned ipl) #include 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 5f241d651b6..c9b5da541ce 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 #if defined(APIC_IO) #include +#include /** FAST_HI */ #endif /* APIC_IO */ #include #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);