Support for the new FAST_HI algorithm, enabled.

Preliminary support for the INTR_SIMPLELOCK algorithm, disabled.
Note that this code is NOT ready.
This commit is contained in:
fsmp 1997-08-29 18:45:23 +00:00
parent cf2671c51e
commit 13fe237edc
12 changed files with 529 additions and 135 deletions

View File

@ -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<<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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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<<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 */

View File

@ -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)

View File

@ -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<<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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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()

View File

@ -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);