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