Last commit didn't take, operator error???
This commit is contained in:
parent
995655b397
commit
87a6f31089
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
|
||||
* $Id: autoconf.c,v 1.72 1997/07/20 18:05:16 fsmp Exp $
|
||||
* $Id: autoconf.c,v 1.5 1997/07/22 18:37:49 smp Exp smp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.3 1997/07/20 18:11:45 smp Exp smp $
|
||||
* $Id: clock.c,v 1.6 1997/07/22 18:36:06 smp Exp smp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -829,33 +829,6 @@ resettodr()
|
||||
writertc(RTC_STATUSB, rtc_statusb);
|
||||
}
|
||||
|
||||
#ifdef APIC_IO
|
||||
|
||||
/* XXX FIXME: from icu.s: */
|
||||
#ifdef NEW_STRATEGY
|
||||
|
||||
extern u_int ivectors[];
|
||||
extern u_int vec[];
|
||||
extern void vec8254 __P((void));
|
||||
extern u_int Xintr8254;
|
||||
extern u_int mask8254;
|
||||
|
||||
#else /** NEW_STRATEGY */
|
||||
|
||||
#if !defined(APIC_PIN0_TIMER)
|
||||
extern u_int ivectors[];
|
||||
extern u_int vec[];
|
||||
#endif
|
||||
|
||||
#ifndef APIC_PIN0_TIMER
|
||||
extern void vec8254 __P((void));
|
||||
extern u_int Xintr8254;
|
||||
extern u_int mask8254;
|
||||
#endif /* APIC_PIN0_TIMER */
|
||||
|
||||
#endif /** NEW_STRATEGY */
|
||||
|
||||
#endif /* APIC_IO */
|
||||
|
||||
/*
|
||||
* Start both clocks running.
|
||||
@ -951,7 +924,7 @@ cpu_initclocks()
|
||||
register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0,
|
||||
/* XXX */ (inthand2_t *)clkintr, &clk_imask,
|
||||
/* unit */ 0);
|
||||
INTREN(IRQ0);
|
||||
INTREN(APIC_IRQ0);
|
||||
#else /* APIC_PIN0_TIMER */
|
||||
/* 8254 is traditionally on ISA IRQ0 */
|
||||
if ((x = isa_apic_pin(0)) < 0) {
|
||||
@ -1027,7 +1000,11 @@ cpu_initclocks()
|
||||
register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
|
||||
/* XXX */ (inthand2_t *)rtcintr, &stat_imask,
|
||||
/* unit */ 0);
|
||||
#ifdef APIC_IO
|
||||
INTREN(APIC_IRQ8);
|
||||
#else
|
||||
INTREN(IRQ8);
|
||||
#endif /* APIC_IO */
|
||||
|
||||
writertc(RTC_STATUSB, rtc_statusb);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: smp.h,v 1.8 1997/07/20 17:48:00 smp Exp smp $
|
||||
* $Id: smp.h,v 1.13 1997/07/22 18:31:51 smp Exp smp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -57,9 +57,24 @@ void rel_mplock __P((void));
|
||||
void try_mplock __P((void));
|
||||
|
||||
/* global data in apic_vector.s */
|
||||
extern u_int ivectors[];
|
||||
extern volatile u_int stopped_cpus;
|
||||
extern volatile u_int started_cpus;
|
||||
|
||||
/* global data in apic_ipl.s */
|
||||
extern u_int vec[];
|
||||
extern u_int Xintr8254;
|
||||
extern u_int mask8254;
|
||||
|
||||
/* functions in apic_ipl.s */
|
||||
void vec8254 __P((void));
|
||||
void INTREN __P((u_int));
|
||||
void INTRDIS __P((u_int));
|
||||
void apic_eoi __P((void));
|
||||
u_int io_apic_read __P((int, int));
|
||||
void io_apic_write __P((int, int, u_int));
|
||||
void write_io_apic_mask24 __P((int, u_int));
|
||||
|
||||
/* global data in mp_machdep.c */
|
||||
extern int mp_ncpus;
|
||||
extern int mp_naps;
|
||||
@ -112,11 +127,11 @@ extern volatile ioapic_t *ioapic[];
|
||||
/* functions in mpapic.c */
|
||||
void apic_dump __P((char*));
|
||||
void apic_initialize __P((void));
|
||||
void imen_dump __P((void));
|
||||
int apic_ipi __P((int, int, int));
|
||||
int selected_apic_ipi __P((u_int, int, int));
|
||||
int io_apic_setup __P((int));
|
||||
int ext_int_setup __P((int, int));
|
||||
void write_io_apic_mask24 __P((int, u_int32_t));
|
||||
|
||||
#if defined(READY)
|
||||
void clr_io_apic_mask24 __P((int, u_int32_t));
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.3 1997/07/20 18:11:45 smp Exp smp $
|
||||
* $Id: clock.c,v 1.6 1997/07/22 18:36:06 smp Exp smp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -829,33 +829,6 @@ resettodr()
|
||||
writertc(RTC_STATUSB, rtc_statusb);
|
||||
}
|
||||
|
||||
#ifdef APIC_IO
|
||||
|
||||
/* XXX FIXME: from icu.s: */
|
||||
#ifdef NEW_STRATEGY
|
||||
|
||||
extern u_int ivectors[];
|
||||
extern u_int vec[];
|
||||
extern void vec8254 __P((void));
|
||||
extern u_int Xintr8254;
|
||||
extern u_int mask8254;
|
||||
|
||||
#else /** NEW_STRATEGY */
|
||||
|
||||
#if !defined(APIC_PIN0_TIMER)
|
||||
extern u_int ivectors[];
|
||||
extern u_int vec[];
|
||||
#endif
|
||||
|
||||
#ifndef APIC_PIN0_TIMER
|
||||
extern void vec8254 __P((void));
|
||||
extern u_int Xintr8254;
|
||||
extern u_int mask8254;
|
||||
#endif /* APIC_PIN0_TIMER */
|
||||
|
||||
#endif /** NEW_STRATEGY */
|
||||
|
||||
#endif /* APIC_IO */
|
||||
|
||||
/*
|
||||
* Start both clocks running.
|
||||
@ -951,7 +924,7 @@ cpu_initclocks()
|
||||
register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0,
|
||||
/* XXX */ (inthand2_t *)clkintr, &clk_imask,
|
||||
/* unit */ 0);
|
||||
INTREN(IRQ0);
|
||||
INTREN(APIC_IRQ0);
|
||||
#else /* APIC_PIN0_TIMER */
|
||||
/* 8254 is traditionally on ISA IRQ0 */
|
||||
if ((x = isa_apic_pin(0)) < 0) {
|
||||
@ -1027,7 +1000,11 @@ cpu_initclocks()
|
||||
register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
|
||||
/* XXX */ (inthand2_t *)rtcintr, &stat_imask,
|
||||
/* unit */ 0);
|
||||
#ifdef APIC_IO
|
||||
INTREN(APIC_IRQ8);
|
||||
#else
|
||||
INTREN(IRQ8);
|
||||
#endif /* APIC_IO */
|
||||
|
||||
writertc(RTC_STATUSB, rtc_statusb);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)icu.h 5.6 (Berkeley) 5/9/91
|
||||
* $Id: icu.h,v 1.13 1997/05/29 04:58:04 peter Exp $
|
||||
* $Id: icu.h,v 1.4 1997/07/22 18:36:06 smp Exp smp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -47,58 +47,27 @@
|
||||
|
||||
#ifndef LOCORE
|
||||
|
||||
#ifdef APIC_IO
|
||||
|
||||
/*
|
||||
* Interrupt "level" mechanism variables, masks, and macros
|
||||
#define MP_SAFE
|
||||
* Note:
|
||||
* Most of the SMP equivilants of the icu macros are coded
|
||||
* elsewhere in an MP-safe fashion.
|
||||
* In particular note that the 'imen' variable is opaque.
|
||||
* DO NOT access imen directly, use INTREN()/INTRDIS().
|
||||
*/
|
||||
extern unsigned imen; /* interrupt mask enable */
|
||||
|
||||
#if defined(APIC_IO)
|
||||
|
||||
# if !defined(_MACHINE_SMP_H_)
|
||||
/** XXX what a hack, its this or include <machine/smp.h>! */
|
||||
void write_io_apic_mask24 __P((int, u_int32_t)); /* i386/i386/mpapic.c */
|
||||
# endif /* _MACHINE_SMP_H_ */
|
||||
|
||||
#if defined(MULTIPLE_IOAPICS)
|
||||
#error MULTIPLE_IOAPICSXXX: cannot assume apic #0 in the following functions.
|
||||
#endif /* MULTIPLE_IOAPICS */
|
||||
|
||||
#ifdef nevermore
|
||||
/* see if we can get by without these, they're NOT MP_SAFE... */
|
||||
static __inline u_int32_t
|
||||
INTRGET(void)
|
||||
{
|
||||
return (imen & 0x00ffffff); /* return our global copy */
|
||||
}
|
||||
|
||||
static __inline void
|
||||
INTRSET(unsigned s)
|
||||
{
|
||||
write_io_apic_mask24(0, s);
|
||||
imen = s;
|
||||
}
|
||||
#endif /** nevermore */
|
||||
|
||||
static __inline void
|
||||
INTREN(unsigned s)
|
||||
{
|
||||
write_io_apic_mask24(0, imen & ~s);
|
||||
imen &= ~s;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
INTRDIS(unsigned s)
|
||||
{
|
||||
write_io_apic_mask24(0, imen | s);
|
||||
imen |= s;
|
||||
}
|
||||
|
||||
|
||||
#define INTRMASK(msk,s) (msk |= (s))
|
||||
#define INTRUNMASK(msk,s) (msk &= ~(s))
|
||||
|
||||
#else /* APIC_IO */
|
||||
|
||||
/*
|
||||
* Interrupt "level" mechanism variables, masks, and macros
|
||||
*/
|
||||
extern unsigned imen; /* interrupt mask enable */
|
||||
|
||||
#define INTREN(s) (imen &= ~(s), SET_ICUS())
|
||||
#define INTRDIS(s) (imen |= (s), SET_ICUS())
|
||||
#define INTRMASK(msk,s) (msk |= (s))
|
||||
@ -131,6 +100,17 @@ INTRDIS(unsigned s)
|
||||
|
||||
#endif /* LOCORE */
|
||||
|
||||
|
||||
#ifdef APIC_IO
|
||||
/*
|
||||
* Note: The APIC uses different values for IRQxxx.
|
||||
* Unfortunately many drivers use the 8259 values as indexes
|
||||
* into tables, etc. The APIC equivilants are kept as APIC_IRQxxx.
|
||||
* The 8259 versions have to be used in SMP for legacy operation
|
||||
* of the drivers.
|
||||
*/
|
||||
#endif /* APIC_IO */
|
||||
|
||||
/*
|
||||
* Interrupt enable bits - in normal order of priority (which we change)
|
||||
*/
|
||||
@ -159,12 +139,13 @@ INTRDIS(unsigned s)
|
||||
#define IRQ_SLAVE 0x0080
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Interrupt Control offset into Interrupt descriptor table (IDT)
|
||||
*/
|
||||
#define ICU_OFFSET 32 /* 0-31 are processor exceptions */
|
||||
|
||||
#if defined(APIC_IO)
|
||||
#ifdef APIC_IO
|
||||
|
||||
/* 32-47: ISA IRQ0-IRQ15, 48-55: IO APIC IRQ16-IRQ23 */
|
||||
#define ICU_LEN 24
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
|
||||
* $Id: autoconf.c,v 1.72 1997/07/20 18:05:16 fsmp Exp $
|
||||
* $Id: autoconf.c,v 1.5 1997/07/22 18:37:49 smp Exp smp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mpapic.c,v 1.18 1997/07/22 18:48:07 fsmp Exp $
|
||||
* $Id: mpapic.c,v 1.18 1997/07/22 18:37:49 smp Exp smp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -113,9 +113,12 @@ apic_initialize(void)
|
||||
void
|
||||
apic_dump(char* str)
|
||||
{
|
||||
printf("SMP: CPU%d %s:\n", cpuid, str);
|
||||
printf(" lint0: 0x%08x lint1: 0x%08x TPR: 0x%08x SVR: 0x%08x\n",
|
||||
lapic.lvt_lint0, lapic.lvt_lint1, lapic.tpr, lapic.svr);
|
||||
printf("SMP: CPU%02d %s lint0: 0x%08x\n",
|
||||
cpuid, str, lapic.lvt_lint0);
|
||||
printf(" lint1: 0x%08x\n",
|
||||
lapic.lvt_lint1);
|
||||
printf(" TPR: 0x%08x\n", lapic.tpr);
|
||||
printf(" SVR: 0x%08x\n", lapic.svr);
|
||||
}
|
||||
|
||||
|
||||
@ -432,137 +435,20 @@ bad:
|
||||
|
||||
|
||||
/*
|
||||
* Set INT mask bit for each bit set in 'mask'.
|
||||
* Clear INT mask bit for all others.
|
||||
* Only consider lower 24 bits in mask.
|
||||
*/
|
||||
#if defined(MULTIPLE_IOAPICS)
|
||||
#error MULTIPLE_IOAPICSXXX
|
||||
#else
|
||||
#define IO_MASK (imen & 0x00ffffff)
|
||||
#define IO_FIELD 0x00ffffff
|
||||
|
||||
void
|
||||
write_io_apic_mask24(int apic, u_int32_t mask)
|
||||
{
|
||||
int x, y;
|
||||
u_char select; /* the select register is 8 bits */
|
||||
u_int32_t low_reg; /* the window register is 32 bits */
|
||||
u_int32_t diffs;
|
||||
|
||||
mask &= IO_FIELD; /* safety valve, only use 24 bits */
|
||||
if (mask == IO_MASK) /* check for same value as current */
|
||||
return;
|
||||
|
||||
diffs = mask ^ IO_MASK; /* record differences */
|
||||
|
||||
for (x = 0, y = REDIRCNT_IOAPIC(apic); x < y; ++x) {
|
||||
if (!(diffs & (1 << x)))
|
||||
continue; /* no change, skip */
|
||||
|
||||
select = IOAPIC_REDTBL + (x * 2); /* calculate addr */
|
||||
low_reg = io_apic_read(apic, select); /* read contents */
|
||||
|
||||
if (mask & (1 << x))
|
||||
low_reg |= IOART_INTMASK; /* set mask */
|
||||
else
|
||||
low_reg &= ~IOART_INTMASK; /* clear mask */
|
||||
|
||||
io_apic_write(apic, select, low_reg); /* new value */
|
||||
}
|
||||
}
|
||||
#endif /* MULTIPLE_IOAPICS */
|
||||
|
||||
|
||||
#if defined(READY)
|
||||
/*
|
||||
* Read current IRQ0 -IRQ23 masks.
|
||||
*/
|
||||
#if defined(MULTIPLE_IOAPICS)
|
||||
#error MULTIPLE_IOAPICSXXX
|
||||
#else
|
||||
static __inline u_int32_t
|
||||
read_io_apic_mask24(int apic)
|
||||
{
|
||||
|
||||
}
|
||||
#endif /* MULTIPLE_IOAPICS */
|
||||
#endif /* READY */
|
||||
|
||||
|
||||
#if defined(READY)
|
||||
/*
|
||||
* Set INT mask bit for each bit set in 'mask'.
|
||||
* Ignore INT mask bit for all others.
|
||||
* Only consider lower 24 bits in mask.
|
||||
* Print contents of imen, keeps imen 'opaque'.
|
||||
*/
|
||||
void
|
||||
set_io_apic_mask24(apic, u_int32_t bits)
|
||||
imen_dump(void)
|
||||
{
|
||||
int x, y;
|
||||
u_char select; /* the select register is 8 bits */
|
||||
u_int32_t low_reg; /* the window register is 32 bits */
|
||||
u_int32_t diffs;
|
||||
extern unsigned imen; /* interrupt mask enable */
|
||||
int x;
|
||||
|
||||
bits &= IO_FIELD; /* safety valve, only use 24 bits */
|
||||
diffs = bits & ~IO_MASK; /* clear AND needing 'set'ing */
|
||||
if (!diffs)
|
||||
return;
|
||||
|
||||
#error imen/io_apic_mask NOT merged in set_io_apic_mask24()
|
||||
|
||||
for (x = 0, y = REDIRCNT_IOAPIC(apic); x < y; ++x) {
|
||||
if (!(diffs & (1 << x)))
|
||||
continue; /* no change, skip */
|
||||
|
||||
select = IOAPIC_REDTBL + (x * 2); /* calculate addr */
|
||||
low_reg = io_apic_read(apic, select); /* read contents */
|
||||
|
||||
lowReg |= IOART_INTMASK; /* set mask */
|
||||
|
||||
io_apic_write(apic, select, low_reg); /* new value */
|
||||
}
|
||||
printf("SMP: enabled INTs: ");
|
||||
for (x = 0; x < 24; ++x)
|
||||
if ((imen & (1 << x)) == 0)
|
||||
printf("%d, ", x);
|
||||
printf("imen: 0x%08x\n", imen);
|
||||
}
|
||||
#endif /* READY */
|
||||
|
||||
|
||||
#if defined(READY)
|
||||
/*
|
||||
* Clear INT mask bit for each bit set in 'mask'.
|
||||
* Ignore INT mask bit for all others.
|
||||
* Only consider lower 24 bits in mask.
|
||||
*/
|
||||
void
|
||||
clr_io_apic_mask24(int apic, u_int32_t bits)
|
||||
{
|
||||
int x, y;
|
||||
u_char select; /* the select register is 8 bits */
|
||||
u_int32_t low_reg; /* the window register is 32 bits */
|
||||
u_int32_t diffs;
|
||||
|
||||
bits &= IO_FIELD; /* safety valve, only use 24 bits */
|
||||
diffs = bits & IO_MASK; /* set AND needing 'clr'ing */
|
||||
if (!diffs)
|
||||
return;
|
||||
|
||||
#error imen/io_apic_mask NOT merged in clr_io_apic_mask24()
|
||||
|
||||
for (x = 0, y = REDIRCNT_IOAPIC(apic); x < y; ++x) {
|
||||
if (!(diffs & (1 << x)))
|
||||
continue; /* no change, skip */
|
||||
|
||||
select = IOAPIC_REDTBL + (x * 2); /* calculate addr */
|
||||
low_reg = io_apic_read(apic, select); /* read contents */
|
||||
|
||||
low_reg &= ~IOART_INTMASK; /* clear mask */
|
||||
|
||||
io_apic_write(apic, select, low_reg); /* new value */
|
||||
}
|
||||
}
|
||||
#endif /* READY */
|
||||
|
||||
#undef IO_FIELD
|
||||
#undef IO_MASK
|
||||
|
||||
|
||||
/*
|
||||
@ -686,7 +572,6 @@ selected_proc_ipi(int target, int vector)
|
||||
}
|
||||
#endif /* READY */
|
||||
|
||||
|
||||
#endif /* APIC_IO */
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.3 1997/07/20 18:11:45 smp Exp smp $
|
||||
* $Id: clock.c,v 1.6 1997/07/22 18:36:06 smp Exp smp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -829,33 +829,6 @@ resettodr()
|
||||
writertc(RTC_STATUSB, rtc_statusb);
|
||||
}
|
||||
|
||||
#ifdef APIC_IO
|
||||
|
||||
/* XXX FIXME: from icu.s: */
|
||||
#ifdef NEW_STRATEGY
|
||||
|
||||
extern u_int ivectors[];
|
||||
extern u_int vec[];
|
||||
extern void vec8254 __P((void));
|
||||
extern u_int Xintr8254;
|
||||
extern u_int mask8254;
|
||||
|
||||
#else /** NEW_STRATEGY */
|
||||
|
||||
#if !defined(APIC_PIN0_TIMER)
|
||||
extern u_int ivectors[];
|
||||
extern u_int vec[];
|
||||
#endif
|
||||
|
||||
#ifndef APIC_PIN0_TIMER
|
||||
extern void vec8254 __P((void));
|
||||
extern u_int Xintr8254;
|
||||
extern u_int mask8254;
|
||||
#endif /* APIC_PIN0_TIMER */
|
||||
|
||||
#endif /** NEW_STRATEGY */
|
||||
|
||||
#endif /* APIC_IO */
|
||||
|
||||
/*
|
||||
* Start both clocks running.
|
||||
@ -951,7 +924,7 @@ cpu_initclocks()
|
||||
register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0,
|
||||
/* XXX */ (inthand2_t *)clkintr, &clk_imask,
|
||||
/* unit */ 0);
|
||||
INTREN(IRQ0);
|
||||
INTREN(APIC_IRQ0);
|
||||
#else /* APIC_PIN0_TIMER */
|
||||
/* 8254 is traditionally on ISA IRQ0 */
|
||||
if ((x = isa_apic_pin(0)) < 0) {
|
||||
@ -1027,7 +1000,11 @@ cpu_initclocks()
|
||||
register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
|
||||
/* XXX */ (inthand2_t *)rtcintr, &stat_imask,
|
||||
/* unit */ 0);
|
||||
#ifdef APIC_IO
|
||||
INTREN(APIC_IRQ8);
|
||||
#else
|
||||
INTREN(IRQ8);
|
||||
#endif /* APIC_IO */
|
||||
|
||||
writertc(RTC_STATUSB, rtc_statusb);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mpapic.h,v 1.7 1997/05/31 03:29:06 fsmp Exp $
|
||||
* $Id: mpapic.h,v 1.3 1997/07/22 18:31:51 smp Exp smp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_MPAPIC_H_
|
||||
@ -75,46 +75,6 @@ enum busTypes {
|
||||
#define ID_TO_IO(ID) (apic_id_to_logical[ID])
|
||||
|
||||
|
||||
/*
|
||||
* inline functions to read/write the IO APIC
|
||||
* NOTES:
|
||||
* unlike the local APIC, the IO APIC is accessed indirectly thru 2 registers.
|
||||
* the select register is loaded with an index to the desired 'window' reg.
|
||||
* the 'window' is accessed as a 32 bit unsigned.
|
||||
*/
|
||||
|
||||
/*
|
||||
* read 'reg' from 'apic'
|
||||
*/
|
||||
static __inline u_int32_t
|
||||
io_apic_read(int apic, int reg)
|
||||
{
|
||||
ioapic[apic]->ioregsel = reg;
|
||||
return ioapic[apic]->iowin;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* write 'value' to 'reg' of 'apic'
|
||||
*/
|
||||
static __inline void
|
||||
io_apic_write(int apic, int reg, u_int32_t value)
|
||||
{
|
||||
ioapic[apic]->ioregsel = reg;
|
||||
ioapic[apic]->iowin = value;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* send an EndOfInterrupt to the local APIC
|
||||
*/
|
||||
static __inline void
|
||||
apic_eoi(void)
|
||||
{
|
||||
lapic.eoi = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* send an IPI INTerrupt containing 'vector' to CPUs in 'targetMap'
|
||||
* 'targetMap' is a bitfiled of length 14,
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: smp.h,v 1.8 1997/07/20 17:48:00 smp Exp smp $
|
||||
* $Id: smp.h,v 1.13 1997/07/22 18:31:51 smp Exp smp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -57,9 +57,24 @@ void rel_mplock __P((void));
|
||||
void try_mplock __P((void));
|
||||
|
||||
/* global data in apic_vector.s */
|
||||
extern u_int ivectors[];
|
||||
extern volatile u_int stopped_cpus;
|
||||
extern volatile u_int started_cpus;
|
||||
|
||||
/* global data in apic_ipl.s */
|
||||
extern u_int vec[];
|
||||
extern u_int Xintr8254;
|
||||
extern u_int mask8254;
|
||||
|
||||
/* functions in apic_ipl.s */
|
||||
void vec8254 __P((void));
|
||||
void INTREN __P((u_int));
|
||||
void INTRDIS __P((u_int));
|
||||
void apic_eoi __P((void));
|
||||
u_int io_apic_read __P((int, int));
|
||||
void io_apic_write __P((int, int, u_int));
|
||||
void write_io_apic_mask24 __P((int, u_int));
|
||||
|
||||
/* global data in mp_machdep.c */
|
||||
extern int mp_ncpus;
|
||||
extern int mp_naps;
|
||||
@ -112,11 +127,11 @@ extern volatile ioapic_t *ioapic[];
|
||||
/* functions in mpapic.c */
|
||||
void apic_dump __P((char*));
|
||||
void apic_initialize __P((void));
|
||||
void imen_dump __P((void));
|
||||
int apic_ipi __P((int, int, int));
|
||||
int selected_apic_ipi __P((u_int, int, int));
|
||||
int io_apic_setup __P((int));
|
||||
int ext_int_setup __P((int, int));
|
||||
void write_io_apic_mask24 __P((int, u_int32_t));
|
||||
|
||||
#if defined(READY)
|
||||
void clr_io_apic_mask24 __P((int, u_int32_t));
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: apic_ipl.s,v 1.2 1997/07/20 18:11:45 smp Exp smp $
|
||||
* $Id: apic_ipl.s,v 1.13 1997/07/22 18:36:06 smp Exp smp $
|
||||
*/
|
||||
|
||||
|
||||
@ -197,3 +197,197 @@ __CONCAT(vec,irq_num): ; \
|
||||
BUILD_VEC(22)
|
||||
BUILD_VEC(23)
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* XXX FIXME: figure out where these belong.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MULTIPLE_IOAPICSXXX: cannot assume apic #0 in the following function.
|
||||
* (soon to be) MP-safe function to set ONE INT mask bit.
|
||||
* The passed arg is a 32bit u_int MASK.
|
||||
* It sets the associated bit in imen.
|
||||
* It sets the mask bit of the associated IO APIC register.
|
||||
*/
|
||||
ALIGN_TEXT
|
||||
.globl _INTREN
|
||||
_INTREN:
|
||||
movl 4(%esp), %eax /* mask into %eax */
|
||||
notl %eax /* mask = ~mask */
|
||||
andl _imen, %eax /* %eax = imen & ~mask */
|
||||
|
||||
pushl %eax /* new (future) imen value */
|
||||
pushl $0 /* APIC# arg */
|
||||
call write_io_apic_mask /* modify the APIC registers */
|
||||
|
||||
addl $4, %esp /* remove APIC# arg from stack */
|
||||
popl _imen /* imen &= ~mask */
|
||||
ret
|
||||
|
||||
/*
|
||||
* MULTIPLE_IOAPICSXXX: cannot assume apic #0 in the following function.
|
||||
* (soon to be) MP-safe function to clear ONE INT mask bit.
|
||||
* The passed arg is a 32bit u_int MASK.
|
||||
* It clears the associated bit in imen.
|
||||
* It clears the mask bit of the associated IO APIC register.
|
||||
*/
|
||||
ALIGN_TEXT
|
||||
.globl _INTRDIS
|
||||
_INTRDIS:
|
||||
movl _imen, %eax
|
||||
orl 4(%esp), %eax /* %eax = imen | mask */
|
||||
|
||||
pushl %eax /* new (future) imen value */
|
||||
pushl $0 /* APIC# arg */
|
||||
call write_io_apic_mask /* modify the APIC registers */
|
||||
|
||||
addl $4, %esp /* remove APIC# arg from stack */
|
||||
popl _imen /* imen |= mask */
|
||||
ret
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* void write_io_apic_mask(int apic, u_int mask);
|
||||
*/
|
||||
|
||||
#define _INT_MASK 0x00010000
|
||||
#define _PIN_MASK 0x00ffffff
|
||||
|
||||
#define _OLD_ESI 0(%esp)
|
||||
#define _OLD_EBX 4(%esp)
|
||||
#define _RETADDR 8(%esp)
|
||||
#define _APIC 12(%esp)
|
||||
#define _MASK 16(%esp)
|
||||
|
||||
.align 2
|
||||
write_io_apic_mask:
|
||||
pushl %ebx /* scratch */
|
||||
pushl %esi /* scratch */
|
||||
|
||||
movl _imen, %ebx
|
||||
xorl _MASK, %ebx /* %ebx = imen ^ mask */
|
||||
andl $_PIN_MASK, %ebx /* %ebx = imen & 0x00ffffff */
|
||||
jz all_done /* no change, return */
|
||||
|
||||
movl _APIC, %esi /* APIC # */
|
||||
movl _ioapic(,%esi,4), %esi /* %esi holds APIC base address */
|
||||
|
||||
next_loop: /* %ebx = diffs, %esi = APIC base */
|
||||
bsfl %ebx, %ecx /* %ecx = index if 1st/next set bit */
|
||||
jz all_done
|
||||
|
||||
btrl %ecx, %ebx /* clear this bit in diffs */
|
||||
leal 16(,%ecx,2), %edx /* calculate register index */
|
||||
|
||||
movl %edx, (%esi) /* write the target register index */
|
||||
movl 16(%esi), %eax /* read the target register data */
|
||||
|
||||
btl %ecx, _MASK /* test for mask or unmask */
|
||||
jnc clear /* bit is clear */
|
||||
orl $_INT_MASK, %eax /* set mask bit */
|
||||
jmp write
|
||||
clear: andl $~_INT_MASK, %eax /* clear mask bit */
|
||||
|
||||
write: movl %edx, (%esi) /* write the target register index */
|
||||
movl %eax, 16(%esi) /* write the APIC register data */
|
||||
|
||||
jmp next_loop /* try another pass */
|
||||
|
||||
all_done:
|
||||
popl %esi
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
#undef _OLD_ESI
|
||||
#undef _OLD_EBX
|
||||
#undef _RETADDR
|
||||
#undef _APIC
|
||||
#undef _MASK
|
||||
|
||||
#undef _PIN_MASK
|
||||
#undef _INT_MASK
|
||||
|
||||
|
||||
#ifdef ready
|
||||
|
||||
/*
|
||||
* u_int read_io_apic_mask(int apic);
|
||||
*/
|
||||
.align 2
|
||||
read_io_apic_mask:
|
||||
ret
|
||||
|
||||
/*
|
||||
* Set INT mask bit for each bit set in 'mask'.
|
||||
* Ignore INT mask bit for all others.
|
||||
* Only consider lower 24 bits in mask.
|
||||
*
|
||||
* void set_io_apic_mask24(apic, u_int32_t bits);
|
||||
*/
|
||||
.align 2
|
||||
set_io_apic_mask:
|
||||
ret
|
||||
|
||||
/*
|
||||
* Clear INT mask bit for each bit set in 'mask'.
|
||||
* Ignore INT mask bit for all others.
|
||||
* Only consider lower 24 bits in mask.
|
||||
*
|
||||
* void clr_io_apic_mask24(int apic, u_int32_t bits);
|
||||
*/
|
||||
.align 2
|
||||
clr_io_apic_mask24:
|
||||
ret
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
.align 2
|
||||
|
||||
ret
|
||||
|
||||
#endif /** ready */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* u_int io_apic_write(int apic, int select);
|
||||
*/
|
||||
.align 2
|
||||
.globl _io_apic_read
|
||||
_io_apic_read:
|
||||
movl 4(%esp), %ecx /* APIC # */
|
||||
movl _ioapic(,%ecx,4), %edx /* APIC base register address */
|
||||
movl 8(%esp), %eax /* target register index */
|
||||
movl %eax, (%edx) /* write the target register index */
|
||||
movl 16(%edx), %eax /* read the APIC register data */
|
||||
ret /* %eax = register value */
|
||||
|
||||
/*
|
||||
* void io_apic_write(int apic, int select, int value);
|
||||
*/
|
||||
.align 2
|
||||
.globl _io_apic_write
|
||||
_io_apic_write:
|
||||
movl 4(%esp), %ecx /* APIC # */
|
||||
movl _ioapic(,%ecx,4), %edx /* APIC base register address */
|
||||
movl 8(%esp), %eax /* target register index */
|
||||
movl %eax, (%edx) /* write the target register index */
|
||||
movl 12(%esp), %eax /* target register value */
|
||||
movl %eax, 16(%edx) /* write the APIC register data */
|
||||
ret /* %eax = void */
|
||||
|
||||
/*
|
||||
* Send an EOI to the local APIC.
|
||||
*/
|
||||
.align 2
|
||||
.globl _apic_eoi
|
||||
_apic_eoi:
|
||||
movl $0, _lapic+0xb0
|
||||
ret
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.3 1997/07/20 18:11:45 smp Exp smp $
|
||||
* $Id: clock.c,v 1.6 1997/07/22 18:36:06 smp Exp smp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -829,33 +829,6 @@ resettodr()
|
||||
writertc(RTC_STATUSB, rtc_statusb);
|
||||
}
|
||||
|
||||
#ifdef APIC_IO
|
||||
|
||||
/* XXX FIXME: from icu.s: */
|
||||
#ifdef NEW_STRATEGY
|
||||
|
||||
extern u_int ivectors[];
|
||||
extern u_int vec[];
|
||||
extern void vec8254 __P((void));
|
||||
extern u_int Xintr8254;
|
||||
extern u_int mask8254;
|
||||
|
||||
#else /** NEW_STRATEGY */
|
||||
|
||||
#if !defined(APIC_PIN0_TIMER)
|
||||
extern u_int ivectors[];
|
||||
extern u_int vec[];
|
||||
#endif
|
||||
|
||||
#ifndef APIC_PIN0_TIMER
|
||||
extern void vec8254 __P((void));
|
||||
extern u_int Xintr8254;
|
||||
extern u_int mask8254;
|
||||
#endif /* APIC_PIN0_TIMER */
|
||||
|
||||
#endif /** NEW_STRATEGY */
|
||||
|
||||
#endif /* APIC_IO */
|
||||
|
||||
/*
|
||||
* Start both clocks running.
|
||||
@ -951,7 +924,7 @@ cpu_initclocks()
|
||||
register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0,
|
||||
/* XXX */ (inthand2_t *)clkintr, &clk_imask,
|
||||
/* unit */ 0);
|
||||
INTREN(IRQ0);
|
||||
INTREN(APIC_IRQ0);
|
||||
#else /* APIC_PIN0_TIMER */
|
||||
/* 8254 is traditionally on ISA IRQ0 */
|
||||
if ((x = isa_apic_pin(0)) < 0) {
|
||||
@ -1027,7 +1000,11 @@ cpu_initclocks()
|
||||
register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
|
||||
/* XXX */ (inthand2_t *)rtcintr, &stat_imask,
|
||||
/* unit */ 0);
|
||||
#ifdef APIC_IO
|
||||
INTREN(APIC_IRQ8);
|
||||
#else
|
||||
INTREN(IRQ8);
|
||||
#endif /* APIC_IO */
|
||||
|
||||
writertc(RTC_STATUSB, rtc_statusb);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)icu.h 5.6 (Berkeley) 5/9/91
|
||||
* $Id: icu.h,v 1.13 1997/05/29 04:58:04 peter Exp $
|
||||
* $Id: icu.h,v 1.4 1997/07/22 18:36:06 smp Exp smp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -47,58 +47,27 @@
|
||||
|
||||
#ifndef LOCORE
|
||||
|
||||
#ifdef APIC_IO
|
||||
|
||||
/*
|
||||
* Interrupt "level" mechanism variables, masks, and macros
|
||||
#define MP_SAFE
|
||||
* Note:
|
||||
* Most of the SMP equivilants of the icu macros are coded
|
||||
* elsewhere in an MP-safe fashion.
|
||||
* In particular note that the 'imen' variable is opaque.
|
||||
* DO NOT access imen directly, use INTREN()/INTRDIS().
|
||||
*/
|
||||
extern unsigned imen; /* interrupt mask enable */
|
||||
|
||||
#if defined(APIC_IO)
|
||||
|
||||
# if !defined(_MACHINE_SMP_H_)
|
||||
/** XXX what a hack, its this or include <machine/smp.h>! */
|
||||
void write_io_apic_mask24 __P((int, u_int32_t)); /* i386/i386/mpapic.c */
|
||||
# endif /* _MACHINE_SMP_H_ */
|
||||
|
||||
#if defined(MULTIPLE_IOAPICS)
|
||||
#error MULTIPLE_IOAPICSXXX: cannot assume apic #0 in the following functions.
|
||||
#endif /* MULTIPLE_IOAPICS */
|
||||
|
||||
#ifdef nevermore
|
||||
/* see if we can get by without these, they're NOT MP_SAFE... */
|
||||
static __inline u_int32_t
|
||||
INTRGET(void)
|
||||
{
|
||||
return (imen & 0x00ffffff); /* return our global copy */
|
||||
}
|
||||
|
||||
static __inline void
|
||||
INTRSET(unsigned s)
|
||||
{
|
||||
write_io_apic_mask24(0, s);
|
||||
imen = s;
|
||||
}
|
||||
#endif /** nevermore */
|
||||
|
||||
static __inline void
|
||||
INTREN(unsigned s)
|
||||
{
|
||||
write_io_apic_mask24(0, imen & ~s);
|
||||
imen &= ~s;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
INTRDIS(unsigned s)
|
||||
{
|
||||
write_io_apic_mask24(0, imen | s);
|
||||
imen |= s;
|
||||
}
|
||||
|
||||
|
||||
#define INTRMASK(msk,s) (msk |= (s))
|
||||
#define INTRUNMASK(msk,s) (msk &= ~(s))
|
||||
|
||||
#else /* APIC_IO */
|
||||
|
||||
/*
|
||||
* Interrupt "level" mechanism variables, masks, and macros
|
||||
*/
|
||||
extern unsigned imen; /* interrupt mask enable */
|
||||
|
||||
#define INTREN(s) (imen &= ~(s), SET_ICUS())
|
||||
#define INTRDIS(s) (imen |= (s), SET_ICUS())
|
||||
#define INTRMASK(msk,s) (msk |= (s))
|
||||
@ -131,6 +100,17 @@ INTRDIS(unsigned s)
|
||||
|
||||
#endif /* LOCORE */
|
||||
|
||||
|
||||
#ifdef APIC_IO
|
||||
/*
|
||||
* Note: The APIC uses different values for IRQxxx.
|
||||
* Unfortunately many drivers use the 8259 values as indexes
|
||||
* into tables, etc. The APIC equivilants are kept as APIC_IRQxxx.
|
||||
* The 8259 versions have to be used in SMP for legacy operation
|
||||
* of the drivers.
|
||||
*/
|
||||
#endif /* APIC_IO */
|
||||
|
||||
/*
|
||||
* Interrupt enable bits - in normal order of priority (which we change)
|
||||
*/
|
||||
@ -159,12 +139,13 @@ INTRDIS(unsigned s)
|
||||
#define IRQ_SLAVE 0x0080
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Interrupt Control offset into Interrupt descriptor table (IDT)
|
||||
*/
|
||||
#define ICU_OFFSET 32 /* 0-31 are processor exceptions */
|
||||
|
||||
#if defined(APIC_IO)
|
||||
#ifdef APIC_IO
|
||||
|
||||
/* 32-47: ISA IRQ0-IRQ15, 48-55: IO APIC IRQ16-IRQ23 */
|
||||
#define ICU_LEN 24
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.3 1997/07/20 18:11:45 smp Exp smp $
|
||||
* $Id: clock.c,v 1.6 1997/07/22 18:36:06 smp Exp smp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -829,33 +829,6 @@ resettodr()
|
||||
writertc(RTC_STATUSB, rtc_statusb);
|
||||
}
|
||||
|
||||
#ifdef APIC_IO
|
||||
|
||||
/* XXX FIXME: from icu.s: */
|
||||
#ifdef NEW_STRATEGY
|
||||
|
||||
extern u_int ivectors[];
|
||||
extern u_int vec[];
|
||||
extern void vec8254 __P((void));
|
||||
extern u_int Xintr8254;
|
||||
extern u_int mask8254;
|
||||
|
||||
#else /** NEW_STRATEGY */
|
||||
|
||||
#if !defined(APIC_PIN0_TIMER)
|
||||
extern u_int ivectors[];
|
||||
extern u_int vec[];
|
||||
#endif
|
||||
|
||||
#ifndef APIC_PIN0_TIMER
|
||||
extern void vec8254 __P((void));
|
||||
extern u_int Xintr8254;
|
||||
extern u_int mask8254;
|
||||
#endif /* APIC_PIN0_TIMER */
|
||||
|
||||
#endif /** NEW_STRATEGY */
|
||||
|
||||
#endif /* APIC_IO */
|
||||
|
||||
/*
|
||||
* Start both clocks running.
|
||||
@ -951,7 +924,7 @@ cpu_initclocks()
|
||||
register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0,
|
||||
/* XXX */ (inthand2_t *)clkintr, &clk_imask,
|
||||
/* unit */ 0);
|
||||
INTREN(IRQ0);
|
||||
INTREN(APIC_IRQ0);
|
||||
#else /* APIC_PIN0_TIMER */
|
||||
/* 8254 is traditionally on ISA IRQ0 */
|
||||
if ((x = isa_apic_pin(0)) < 0) {
|
||||
@ -1027,7 +1000,11 @@ cpu_initclocks()
|
||||
register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
|
||||
/* XXX */ (inthand2_t *)rtcintr, &stat_imask,
|
||||
/* unit */ 0);
|
||||
#ifdef APIC_IO
|
||||
INTREN(APIC_IRQ8);
|
||||
#else
|
||||
INTREN(IRQ8);
|
||||
#endif /* APIC_IO */
|
||||
|
||||
writertc(RTC_STATUSB, rtc_statusb);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: smp.h,v 1.8 1997/07/20 17:48:00 smp Exp smp $
|
||||
* $Id: smp.h,v 1.13 1997/07/22 18:31:51 smp Exp smp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -57,9 +57,24 @@ void rel_mplock __P((void));
|
||||
void try_mplock __P((void));
|
||||
|
||||
/* global data in apic_vector.s */
|
||||
extern u_int ivectors[];
|
||||
extern volatile u_int stopped_cpus;
|
||||
extern volatile u_int started_cpus;
|
||||
|
||||
/* global data in apic_ipl.s */
|
||||
extern u_int vec[];
|
||||
extern u_int Xintr8254;
|
||||
extern u_int mask8254;
|
||||
|
||||
/* functions in apic_ipl.s */
|
||||
void vec8254 __P((void));
|
||||
void INTREN __P((u_int));
|
||||
void INTRDIS __P((u_int));
|
||||
void apic_eoi __P((void));
|
||||
u_int io_apic_read __P((int, int));
|
||||
void io_apic_write __P((int, int, u_int));
|
||||
void write_io_apic_mask24 __P((int, u_int));
|
||||
|
||||
/* global data in mp_machdep.c */
|
||||
extern int mp_ncpus;
|
||||
extern int mp_naps;
|
||||
@ -112,11 +127,11 @@ extern volatile ioapic_t *ioapic[];
|
||||
/* functions in mpapic.c */
|
||||
void apic_dump __P((char*));
|
||||
void apic_initialize __P((void));
|
||||
void imen_dump __P((void));
|
||||
int apic_ipi __P((int, int, int));
|
||||
int selected_apic_ipi __P((u_int, int, int));
|
||||
int io_apic_setup __P((int));
|
||||
int ext_int_setup __P((int, int));
|
||||
void write_io_apic_mask24 __P((int, u_int32_t));
|
||||
|
||||
#if defined(READY)
|
||||
void clr_io_apic_mask24 __P((int, u_int32_t));
|
||||
|
Loading…
x
Reference in New Issue
Block a user