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:
parent
cf2671c51e
commit
13fe237edc
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user