Maintain a mapping from irq number to (ioapic number, int pin) tuple,
and use this when masking/unmasking interrupts. Maintain a mapping from (iopaic number, int pin) tuple to irq number, and use this when configuring devices and programming the ioapics. Previous code assumed that irq number was equal to int pin number, and that the ioapic number was 0. Don't let an AP enter _cpu_switch before all local apics are initialized.
This commit is contained in:
parent
f36aa446c7
commit
05420fa9d0
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* from: vector.s, 386BSD 0.1 unknown origin
|
||||
* $Id: apic_vector.s,v 1.32 1998/08/11 17:01:32 bde Exp $
|
||||
* $Id: apic_vector.s,v 1.33 1998/09/04 23:03:04 luoqi Exp $
|
||||
*/
|
||||
|
||||
|
||||
@ -166,13 +166,17 @@ IDTVEC(vec_name) ; \
|
||||
popal ; \
|
||||
addl $4+4,%esp
|
||||
|
||||
#define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8
|
||||
#define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12
|
||||
|
||||
#define MASK_IRQ(irq_num) \
|
||||
IMASK_LOCK ; /* into critical reg */ \
|
||||
testl $IRQ_BIT(irq_num), _apic_imen ; \
|
||||
jne 7f ; /* masked, don't mask */ \
|
||||
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 IOAPICADDR(irq_num), %ecx ; /* ioapic addr */ \
|
||||
movl REDIRIDX(irq_num), %eax ; /* get the index */ \
|
||||
movl %eax, (%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 */ \
|
||||
@ -218,8 +222,9 @@ IDTVEC(vec_name) ; \
|
||||
testl $IRQ_BIT(irq_num), _apic_imen ; \
|
||||
je 7f ; /* bit clear, not masked */ \
|
||||
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 IOAPICADDR(irq_num),%ecx ; /* ioapic addr */ \
|
||||
movl REDIRIDX(irq_num), %eax ; /* get the index */ \
|
||||
movl %eax,(%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 */ \
|
||||
@ -990,7 +995,7 @@ CNAME(cpustop_restartfunc):
|
||||
|
||||
.globl _apic_pin_trigger
|
||||
_apic_pin_trigger:
|
||||
.space (NAPIC * 4), 0
|
||||
.long 0
|
||||
|
||||
|
||||
/*
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $
|
||||
* $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -278,6 +278,8 @@ struct {
|
||||
} apic_isrbit_location[32];
|
||||
#endif
|
||||
|
||||
struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE];
|
||||
|
||||
/*
|
||||
* APIC ID logical/physical mapping structures.
|
||||
* We oversize these to simplify boot-time config.
|
||||
@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD;
|
||||
|
||||
struct pcb stoppcbs[NCPU];
|
||||
|
||||
static int smp_started; /* has the system started? */
|
||||
int smp_started; /* has the system started? */
|
||||
|
||||
/*
|
||||
* Local data and functions.
|
||||
@ -334,6 +336,7 @@ static int mptable_pass1(void);
|
||||
static int mptable_pass2(void);
|
||||
static void default_mp_table(int type);
|
||||
static void fix_mp_table(void);
|
||||
static void setup_apic_irq_mapping(void);
|
||||
static void init_locks(void);
|
||||
static int start_all_aps(u_int boot_addr);
|
||||
static void install_ap_tramp(u_int boot_addr);
|
||||
@ -569,6 +572,7 @@ mp_enable(u_int boot_addr)
|
||||
|
||||
/* post scan cleanup */
|
||||
fix_mp_table();
|
||||
setup_apic_irq_mapping();
|
||||
|
||||
#if defined(APIC_IO)
|
||||
|
||||
@ -675,6 +679,7 @@ typedef struct INTDATA {
|
||||
u_char src_bus_irq;
|
||||
u_char dst_apic_id;
|
||||
u_char dst_apic_int;
|
||||
u_char int_vector;
|
||||
} io_int, local_int;
|
||||
|
||||
typedef struct BUSTYPENAME {
|
||||
@ -905,8 +910,10 @@ mptable_pass2(void)
|
||||
bus_data[x].bus_id = 0xff;
|
||||
|
||||
/* clear IO APIC INT table */
|
||||
for (x = 0; x < NINTR; ++x)
|
||||
for (x = 0; x < NINTR; ++x) {
|
||||
io_apic_ints[x].int_type = 0xff;
|
||||
io_apic_ints[x].int_vector = 0xff;
|
||||
}
|
||||
|
||||
/* setup the cpu/apic mapping arrays */
|
||||
boot_cpu_id = -1;
|
||||
@ -966,6 +973,29 @@ mptable_pass2(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
assign_apic_irq(int apic, int intpin, int irq)
|
||||
{
|
||||
int x;
|
||||
|
||||
if (int_to_apicintpin[irq].ioapic != -1)
|
||||
panic("assign_apic_irq: inconsistent table");
|
||||
|
||||
int_to_apicintpin[irq].ioapic = apic;
|
||||
int_to_apicintpin[irq].int_pin = intpin;
|
||||
int_to_apicintpin[irq].apic_address = ioapic[apic];
|
||||
int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin;
|
||||
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) &&
|
||||
io_apic_ints[x].dst_apic_int == intpin)
|
||||
io_apic_ints[x].int_vector = irq;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* parse an Intel MP specification table
|
||||
*/
|
||||
@ -1041,6 +1071,50 @@ fix_mp_table(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_apic_irq_mapping(void)
|
||||
{
|
||||
int x;
|
||||
int int_vector;
|
||||
|
||||
/* Assign low level interrupt handlers */
|
||||
for (x = 0; x < APIC_INTMAPSIZE; x++) {
|
||||
int_to_apicintpin[x].ioapic = -1;
|
||||
int_to_apicintpin[x].int_pin = 0;
|
||||
int_to_apicintpin[x].apic_address = NULL;
|
||||
int_to_apicintpin[x].redirindex = 0;
|
||||
}
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
(io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3)) {
|
||||
assign_apic_irq(0,
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
io_apic_ints[x].dst_apic_int);
|
||||
}
|
||||
}
|
||||
int_vector = 0;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff) {
|
||||
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
int_vector);
|
||||
int_vector++;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
processor_entry(proc_entry_ptr entry, int cpu)
|
||||
{
|
||||
@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask)
|
||||
return 0;
|
||||
--isa_irq; /* make it zero based */
|
||||
|
||||
apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */
|
||||
apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */
|
||||
if (apic_pin == -1)
|
||||
return 0;
|
||||
|
||||
@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask)
|
||||
*/
|
||||
#define INTTYPE(I) (io_apic_ints[(I)].int_type)
|
||||
#define INTPIN(I) (io_apic_ints[(I)].dst_apic_int)
|
||||
#define INTIRQ(I) (io_apic_ints[(I)].int_vector)
|
||||
#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id))
|
||||
|
||||
#define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq)
|
||||
int
|
||||
isa_apic_pin(int isa_irq)
|
||||
isa_apic_irq(int isa_irq)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq)
|
||||
if (SRCBUSIRQ(intr) == isa_irq) {
|
||||
if (apic_int_is_bus_type(intr, ISA) ||
|
||||
apic_int_is_bus_type(intr, EISA))
|
||||
return INTPIN(intr); /* found */
|
||||
return INTIRQ(intr); /* found */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq)
|
||||
#define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f)
|
||||
#define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03)
|
||||
int
|
||||
pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
pci_apic_irq(int pciBus, int pciDevice, int pciInt)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
&& (SRCBUSDEVICE(intr) == pciDevice)
|
||||
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
|
||||
if (apic_int_is_bus_type(intr, PCI))
|
||||
return INTPIN(intr); /* exact match */
|
||||
return INTIRQ(intr); /* exact match */
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
next_apic_irq(int irq)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
@ -1230,7 +1306,7 @@ next_apic_pin(int pin)
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
if (INTIRQ(intr) != irq || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
@ -1265,7 +1341,7 @@ next_apic_pin(int pin)
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
return INTIRQ(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
@ -1273,6 +1349,8 @@ next_apic_pin(int pin)
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTIRQ
|
||||
#undef INTAPIC
|
||||
#undef INTTYPE
|
||||
|
||||
|
||||
@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin)
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
apic_irq(int apic, int pin)
|
||||
{
|
||||
int x;
|
||||
int res;
|
||||
|
||||
for (x = 0; x < nintrs; ++x)
|
||||
if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
|
||||
(pin == io_apic_ints[x].dst_apic_int)) {
|
||||
res = io_apic_ints[x].int_vector;
|
||||
if (res == 0xff)
|
||||
return -1;
|
||||
if (apic != int_to_apicintpin[res].ioapic)
|
||||
panic("apic_irq: inconsistent table");
|
||||
if (pin != int_to_apicintpin[res].int_pin)
|
||||
panic("apic_irq inconsistent table (2)");
|
||||
return res;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* given a LOGICAL APIC# and pin#, return:
|
||||
@ -2127,9 +2226,11 @@ ap_init()
|
||||
* quite correct yet. We should have a bitfield for cpus willing
|
||||
* to accept TLB flush IPI's or something and sync them.
|
||||
*/
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
if (smp_cpus == mp_ncpus) {
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
}
|
||||
|
||||
curproc = NULL; /* make sure */
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
* mpboot.s: FreeBSD machine support for the Intel MP Spec
|
||||
* multiprocessor systems.
|
||||
*
|
||||
* $Id: mpboot.s,v 1.5 1997/09/22 05:03:03 peter Exp $
|
||||
* $Id: mpboot.s,v 1.6 1997/10/10 09:44:05 peter Exp $
|
||||
*/
|
||||
|
||||
#include "opt_vm86.h"
|
||||
@ -124,6 +124,12 @@ mp_begin: /* now running relocated at KERNBASE */
|
||||
/* Now, let's prepare for some REAL WORK :-) */
|
||||
call _ap_init
|
||||
|
||||
call _rel_mplock
|
||||
2:
|
||||
cmpl $0, CNAME(smp_started) /* Wait for last AP to be ready */
|
||||
jz 2b
|
||||
call _get_mplock
|
||||
|
||||
/* let her rip! (loads new stack) */
|
||||
jmp _cpu_switch
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $
|
||||
* $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -278,6 +278,8 @@ struct {
|
||||
} apic_isrbit_location[32];
|
||||
#endif
|
||||
|
||||
struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE];
|
||||
|
||||
/*
|
||||
* APIC ID logical/physical mapping structures.
|
||||
* We oversize these to simplify boot-time config.
|
||||
@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD;
|
||||
|
||||
struct pcb stoppcbs[NCPU];
|
||||
|
||||
static int smp_started; /* has the system started? */
|
||||
int smp_started; /* has the system started? */
|
||||
|
||||
/*
|
||||
* Local data and functions.
|
||||
@ -334,6 +336,7 @@ static int mptable_pass1(void);
|
||||
static int mptable_pass2(void);
|
||||
static void default_mp_table(int type);
|
||||
static void fix_mp_table(void);
|
||||
static void setup_apic_irq_mapping(void);
|
||||
static void init_locks(void);
|
||||
static int start_all_aps(u_int boot_addr);
|
||||
static void install_ap_tramp(u_int boot_addr);
|
||||
@ -569,6 +572,7 @@ mp_enable(u_int boot_addr)
|
||||
|
||||
/* post scan cleanup */
|
||||
fix_mp_table();
|
||||
setup_apic_irq_mapping();
|
||||
|
||||
#if defined(APIC_IO)
|
||||
|
||||
@ -675,6 +679,7 @@ typedef struct INTDATA {
|
||||
u_char src_bus_irq;
|
||||
u_char dst_apic_id;
|
||||
u_char dst_apic_int;
|
||||
u_char int_vector;
|
||||
} io_int, local_int;
|
||||
|
||||
typedef struct BUSTYPENAME {
|
||||
@ -905,8 +910,10 @@ mptable_pass2(void)
|
||||
bus_data[x].bus_id = 0xff;
|
||||
|
||||
/* clear IO APIC INT table */
|
||||
for (x = 0; x < NINTR; ++x)
|
||||
for (x = 0; x < NINTR; ++x) {
|
||||
io_apic_ints[x].int_type = 0xff;
|
||||
io_apic_ints[x].int_vector = 0xff;
|
||||
}
|
||||
|
||||
/* setup the cpu/apic mapping arrays */
|
||||
boot_cpu_id = -1;
|
||||
@ -966,6 +973,29 @@ mptable_pass2(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
assign_apic_irq(int apic, int intpin, int irq)
|
||||
{
|
||||
int x;
|
||||
|
||||
if (int_to_apicintpin[irq].ioapic != -1)
|
||||
panic("assign_apic_irq: inconsistent table");
|
||||
|
||||
int_to_apicintpin[irq].ioapic = apic;
|
||||
int_to_apicintpin[irq].int_pin = intpin;
|
||||
int_to_apicintpin[irq].apic_address = ioapic[apic];
|
||||
int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin;
|
||||
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) &&
|
||||
io_apic_ints[x].dst_apic_int == intpin)
|
||||
io_apic_ints[x].int_vector = irq;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* parse an Intel MP specification table
|
||||
*/
|
||||
@ -1041,6 +1071,50 @@ fix_mp_table(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_apic_irq_mapping(void)
|
||||
{
|
||||
int x;
|
||||
int int_vector;
|
||||
|
||||
/* Assign low level interrupt handlers */
|
||||
for (x = 0; x < APIC_INTMAPSIZE; x++) {
|
||||
int_to_apicintpin[x].ioapic = -1;
|
||||
int_to_apicintpin[x].int_pin = 0;
|
||||
int_to_apicintpin[x].apic_address = NULL;
|
||||
int_to_apicintpin[x].redirindex = 0;
|
||||
}
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
(io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3)) {
|
||||
assign_apic_irq(0,
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
io_apic_ints[x].dst_apic_int);
|
||||
}
|
||||
}
|
||||
int_vector = 0;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff) {
|
||||
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
int_vector);
|
||||
int_vector++;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
processor_entry(proc_entry_ptr entry, int cpu)
|
||||
{
|
||||
@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask)
|
||||
return 0;
|
||||
--isa_irq; /* make it zero based */
|
||||
|
||||
apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */
|
||||
apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */
|
||||
if (apic_pin == -1)
|
||||
return 0;
|
||||
|
||||
@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask)
|
||||
*/
|
||||
#define INTTYPE(I) (io_apic_ints[(I)].int_type)
|
||||
#define INTPIN(I) (io_apic_ints[(I)].dst_apic_int)
|
||||
#define INTIRQ(I) (io_apic_ints[(I)].int_vector)
|
||||
#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id))
|
||||
|
||||
#define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq)
|
||||
int
|
||||
isa_apic_pin(int isa_irq)
|
||||
isa_apic_irq(int isa_irq)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq)
|
||||
if (SRCBUSIRQ(intr) == isa_irq) {
|
||||
if (apic_int_is_bus_type(intr, ISA) ||
|
||||
apic_int_is_bus_type(intr, EISA))
|
||||
return INTPIN(intr); /* found */
|
||||
return INTIRQ(intr); /* found */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq)
|
||||
#define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f)
|
||||
#define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03)
|
||||
int
|
||||
pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
pci_apic_irq(int pciBus, int pciDevice, int pciInt)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
&& (SRCBUSDEVICE(intr) == pciDevice)
|
||||
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
|
||||
if (apic_int_is_bus_type(intr, PCI))
|
||||
return INTPIN(intr); /* exact match */
|
||||
return INTIRQ(intr); /* exact match */
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
next_apic_irq(int irq)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
@ -1230,7 +1306,7 @@ next_apic_pin(int pin)
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
if (INTIRQ(intr) != irq || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
@ -1265,7 +1341,7 @@ next_apic_pin(int pin)
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
return INTIRQ(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
@ -1273,6 +1349,8 @@ next_apic_pin(int pin)
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTIRQ
|
||||
#undef INTAPIC
|
||||
#undef INTTYPE
|
||||
|
||||
|
||||
@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin)
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
apic_irq(int apic, int pin)
|
||||
{
|
||||
int x;
|
||||
int res;
|
||||
|
||||
for (x = 0; x < nintrs; ++x)
|
||||
if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
|
||||
(pin == io_apic_ints[x].dst_apic_int)) {
|
||||
res = io_apic_ints[x].int_vector;
|
||||
if (res == 0xff)
|
||||
return -1;
|
||||
if (apic != int_to_apicintpin[res].ioapic)
|
||||
panic("apic_irq: inconsistent table");
|
||||
if (pin != int_to_apicintpin[res].int_pin)
|
||||
panic("apic_irq inconsistent table (2)");
|
||||
return res;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* given a LOGICAL APIC# and pin#, return:
|
||||
@ -2127,9 +2226,11 @@ ap_init()
|
||||
* quite correct yet. We should have a bitfield for cpus willing
|
||||
* to accept TLB flush IPI's or something and sync them.
|
||||
*/
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
if (smp_cpus == mp_ncpus) {
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
}
|
||||
|
||||
curproc = NULL; /* make sure */
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.123 1998/06/07 20:36:39 phk Exp $
|
||||
* $Id: clock.c,v 1.124 1998/06/09 13:10:46 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -953,7 +953,7 @@ cpu_initclocks()
|
||||
/* Finish initializing 8253 timer 0. */
|
||||
#ifdef APIC_IO
|
||||
|
||||
apic_8254_intr = isa_apic_pin(0);
|
||||
apic_8254_intr = isa_apic_irq(0);
|
||||
apic_8254_trial = 0;
|
||||
if (apic_8254_intr >= 0 ) {
|
||||
if (apic_int_type(0, 0) == 3)
|
||||
@ -993,7 +993,7 @@ cpu_initclocks()
|
||||
printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
|
||||
|
||||
#ifdef APIC_IO
|
||||
if (isa_apic_pin(8) != 8)
|
||||
if (isa_apic_irq(8) != 8)
|
||||
panic("APIC RTC != 8");
|
||||
#endif /* APIC_IO */
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: apic.h,v 1.7 1997/08/04 17:20:39 smp Exp smp $
|
||||
* $Id: apic.h,v 1.11 1997/08/04 17:31:24 fsmp Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_APIC_H_
|
||||
@ -113,12 +113,6 @@
|
||||
* global defines, etc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* this enables code concerned with handling more than one IO APIC.
|
||||
* Note: this is NOT READY for use!
|
||||
*
|
||||
#define MULTIPLE_IOAPICS
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* LOCAL APIC structure
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $
|
||||
* $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -278,6 +278,8 @@ struct {
|
||||
} apic_isrbit_location[32];
|
||||
#endif
|
||||
|
||||
struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE];
|
||||
|
||||
/*
|
||||
* APIC ID logical/physical mapping structures.
|
||||
* We oversize these to simplify boot-time config.
|
||||
@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD;
|
||||
|
||||
struct pcb stoppcbs[NCPU];
|
||||
|
||||
static int smp_started; /* has the system started? */
|
||||
int smp_started; /* has the system started? */
|
||||
|
||||
/*
|
||||
* Local data and functions.
|
||||
@ -334,6 +336,7 @@ static int mptable_pass1(void);
|
||||
static int mptable_pass2(void);
|
||||
static void default_mp_table(int type);
|
||||
static void fix_mp_table(void);
|
||||
static void setup_apic_irq_mapping(void);
|
||||
static void init_locks(void);
|
||||
static int start_all_aps(u_int boot_addr);
|
||||
static void install_ap_tramp(u_int boot_addr);
|
||||
@ -569,6 +572,7 @@ mp_enable(u_int boot_addr)
|
||||
|
||||
/* post scan cleanup */
|
||||
fix_mp_table();
|
||||
setup_apic_irq_mapping();
|
||||
|
||||
#if defined(APIC_IO)
|
||||
|
||||
@ -675,6 +679,7 @@ typedef struct INTDATA {
|
||||
u_char src_bus_irq;
|
||||
u_char dst_apic_id;
|
||||
u_char dst_apic_int;
|
||||
u_char int_vector;
|
||||
} io_int, local_int;
|
||||
|
||||
typedef struct BUSTYPENAME {
|
||||
@ -905,8 +910,10 @@ mptable_pass2(void)
|
||||
bus_data[x].bus_id = 0xff;
|
||||
|
||||
/* clear IO APIC INT table */
|
||||
for (x = 0; x < NINTR; ++x)
|
||||
for (x = 0; x < NINTR; ++x) {
|
||||
io_apic_ints[x].int_type = 0xff;
|
||||
io_apic_ints[x].int_vector = 0xff;
|
||||
}
|
||||
|
||||
/* setup the cpu/apic mapping arrays */
|
||||
boot_cpu_id = -1;
|
||||
@ -966,6 +973,29 @@ mptable_pass2(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
assign_apic_irq(int apic, int intpin, int irq)
|
||||
{
|
||||
int x;
|
||||
|
||||
if (int_to_apicintpin[irq].ioapic != -1)
|
||||
panic("assign_apic_irq: inconsistent table");
|
||||
|
||||
int_to_apicintpin[irq].ioapic = apic;
|
||||
int_to_apicintpin[irq].int_pin = intpin;
|
||||
int_to_apicintpin[irq].apic_address = ioapic[apic];
|
||||
int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin;
|
||||
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) &&
|
||||
io_apic_ints[x].dst_apic_int == intpin)
|
||||
io_apic_ints[x].int_vector = irq;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* parse an Intel MP specification table
|
||||
*/
|
||||
@ -1041,6 +1071,50 @@ fix_mp_table(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_apic_irq_mapping(void)
|
||||
{
|
||||
int x;
|
||||
int int_vector;
|
||||
|
||||
/* Assign low level interrupt handlers */
|
||||
for (x = 0; x < APIC_INTMAPSIZE; x++) {
|
||||
int_to_apicintpin[x].ioapic = -1;
|
||||
int_to_apicintpin[x].int_pin = 0;
|
||||
int_to_apicintpin[x].apic_address = NULL;
|
||||
int_to_apicintpin[x].redirindex = 0;
|
||||
}
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
(io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3)) {
|
||||
assign_apic_irq(0,
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
io_apic_ints[x].dst_apic_int);
|
||||
}
|
||||
}
|
||||
int_vector = 0;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff) {
|
||||
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
int_vector);
|
||||
int_vector++;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
processor_entry(proc_entry_ptr entry, int cpu)
|
||||
{
|
||||
@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask)
|
||||
return 0;
|
||||
--isa_irq; /* make it zero based */
|
||||
|
||||
apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */
|
||||
apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */
|
||||
if (apic_pin == -1)
|
||||
return 0;
|
||||
|
||||
@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask)
|
||||
*/
|
||||
#define INTTYPE(I) (io_apic_ints[(I)].int_type)
|
||||
#define INTPIN(I) (io_apic_ints[(I)].dst_apic_int)
|
||||
#define INTIRQ(I) (io_apic_ints[(I)].int_vector)
|
||||
#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id))
|
||||
|
||||
#define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq)
|
||||
int
|
||||
isa_apic_pin(int isa_irq)
|
||||
isa_apic_irq(int isa_irq)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq)
|
||||
if (SRCBUSIRQ(intr) == isa_irq) {
|
||||
if (apic_int_is_bus_type(intr, ISA) ||
|
||||
apic_int_is_bus_type(intr, EISA))
|
||||
return INTPIN(intr); /* found */
|
||||
return INTIRQ(intr); /* found */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq)
|
||||
#define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f)
|
||||
#define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03)
|
||||
int
|
||||
pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
pci_apic_irq(int pciBus, int pciDevice, int pciInt)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
&& (SRCBUSDEVICE(intr) == pciDevice)
|
||||
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
|
||||
if (apic_int_is_bus_type(intr, PCI))
|
||||
return INTPIN(intr); /* exact match */
|
||||
return INTIRQ(intr); /* exact match */
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
next_apic_irq(int irq)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
@ -1230,7 +1306,7 @@ next_apic_pin(int pin)
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
if (INTIRQ(intr) != irq || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
@ -1265,7 +1341,7 @@ next_apic_pin(int pin)
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
return INTIRQ(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
@ -1273,6 +1349,8 @@ next_apic_pin(int pin)
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTIRQ
|
||||
#undef INTAPIC
|
||||
#undef INTTYPE
|
||||
|
||||
|
||||
@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin)
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
apic_irq(int apic, int pin)
|
||||
{
|
||||
int x;
|
||||
int res;
|
||||
|
||||
for (x = 0; x < nintrs; ++x)
|
||||
if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
|
||||
(pin == io_apic_ints[x].dst_apic_int)) {
|
||||
res = io_apic_ints[x].int_vector;
|
||||
if (res == 0xff)
|
||||
return -1;
|
||||
if (apic != int_to_apicintpin[res].ioapic)
|
||||
panic("apic_irq: inconsistent table");
|
||||
if (pin != int_to_apicintpin[res].int_pin)
|
||||
panic("apic_irq inconsistent table (2)");
|
||||
return res;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* given a LOGICAL APIC# and pin#, return:
|
||||
@ -2127,9 +2226,11 @@ ap_init()
|
||||
* quite correct yet. We should have a bitfield for cpus willing
|
||||
* to accept TLB flush IPI's or something and sync them.
|
||||
*/
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
if (smp_cpus == mp_ncpus) {
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
}
|
||||
|
||||
curproc = NULL; /* make sure */
|
||||
}
|
||||
|
@ -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.42 1998/04/01 21:07:36 tegge Exp $
|
||||
* $Id: smp.h,v 1.43 1998/05/17 22:12:05 tegge Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -103,6 +103,14 @@ extern u_int32_t io_apic_versions[];
|
||||
extern int cpu_num_to_apic_id[];
|
||||
extern int io_num_to_apic_id[];
|
||||
extern int apic_id_to_logical[];
|
||||
#define APIC_INTMAPSIZE 24
|
||||
struct apic_intmapinfo {
|
||||
int ioapic;
|
||||
int int_pin;
|
||||
volatile void *apic_address;
|
||||
int redirindex;
|
||||
};
|
||||
extern struct apic_intmapinfo int_to_apicintpin[];
|
||||
extern u_int all_cpus;
|
||||
extern u_char SMP_ioapic[];
|
||||
extern struct pcb stoppcbs[];
|
||||
@ -113,9 +121,10 @@ int mp_probe __P((void));
|
||||
void mp_start __P((void));
|
||||
void mp_announce __P((void));
|
||||
u_int isa_apic_mask __P((u_int));
|
||||
int isa_apic_pin __P((int));
|
||||
int pci_apic_pin __P((int, int, int));
|
||||
int next_apic_pin __P((int));
|
||||
int isa_apic_irq __P((int));
|
||||
int pci_apic_irq __P((int, int, int));
|
||||
int apic_irq __P((int, int));
|
||||
int next_apic_irq __P((int));
|
||||
int undirect_isa_irq __P((int));
|
||||
int undirect_pci_irq __P((int));
|
||||
int apic_bus_type __P((int));
|
||||
@ -141,12 +150,7 @@ void set_lapic_isrloc __P((int, int));
|
||||
|
||||
/* global data in mpapic.c */
|
||||
extern volatile lapic_t lapic;
|
||||
|
||||
#if defined(MULTIPLE_IOAPICS)
|
||||
#error MULTIPLE_IOAPICSXXX
|
||||
#else
|
||||
extern volatile ioapic_t *ioapic[];
|
||||
#endif /* MULTIPLE_IOAPICS */
|
||||
|
||||
/* functions in mpapic.c */
|
||||
void apic_dump __P((char*));
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.123 1998/06/07 20:36:39 phk Exp $
|
||||
* $Id: clock.c,v 1.124 1998/06/09 13:10:46 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -953,7 +953,7 @@ cpu_initclocks()
|
||||
/* Finish initializing 8253 timer 0. */
|
||||
#ifdef APIC_IO
|
||||
|
||||
apic_8254_intr = isa_apic_pin(0);
|
||||
apic_8254_intr = isa_apic_irq(0);
|
||||
apic_8254_trial = 0;
|
||||
if (apic_8254_intr >= 0 ) {
|
||||
if (apic_int_type(0, 0) == 3)
|
||||
@ -993,7 +993,7 @@ cpu_initclocks()
|
||||
printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
|
||||
|
||||
#ifdef APIC_IO
|
||||
if (isa_apic_pin(8) != 8)
|
||||
if (isa_apic_irq(8) != 8)
|
||||
panic("APIC RTC != 8");
|
||||
#endif /* APIC_IO */
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
|
||||
* $Id: intr_machdep.c,v 1.12 1998/06/18 15:32:06 bde Exp $
|
||||
* $Id: intr_machdep.c,v 1.13 1998/06/18 16:08:46 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_auto_eoi.h"
|
||||
@ -429,12 +429,15 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags)
|
||||
set_lapic_isrloc(intr, vector);
|
||||
#endif
|
||||
/*
|
||||
* 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);
|
||||
if (int_to_apicintpin[intr].ioapic >= 0) {
|
||||
select = int_to_apicintpin[intr].redirindex;
|
||||
value = io_apic_read(int_to_apicintpin[intr].ioapic,
|
||||
select) & ~IOART_INTVEC;
|
||||
io_apic_write(int_to_apicintpin[intr].ioapic,
|
||||
select, value | vector);
|
||||
}
|
||||
#else
|
||||
setidt(ICU_OFFSET + intr,
|
||||
flags & INTR_FAST ? fastintr[intr] : slowintr[intr],
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
|
||||
* $Id: intr_machdep.c,v 1.12 1998/06/18 15:32:06 bde Exp $
|
||||
* $Id: intr_machdep.c,v 1.13 1998/06/18 16:08:46 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_auto_eoi.h"
|
||||
@ -429,12 +429,15 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags)
|
||||
set_lapic_isrloc(intr, vector);
|
||||
#endif
|
||||
/*
|
||||
* 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);
|
||||
if (int_to_apicintpin[intr].ioapic >= 0) {
|
||||
select = int_to_apicintpin[intr].redirindex;
|
||||
value = io_apic_read(int_to_apicintpin[intr].ioapic,
|
||||
select) & ~IOART_INTVEC;
|
||||
io_apic_write(int_to_apicintpin[intr].ioapic,
|
||||
select, value | vector);
|
||||
}
|
||||
#else
|
||||
setidt(ICU_OFFSET + intr,
|
||||
flags & INTR_FAST ? fastintr[intr] : slowintr[intr],
|
||||
|
@ -23,7 +23,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pci.c,v 1.84 1998/07/22 08:40:46 dfr Exp $
|
||||
* $Id: pci.c,v 1.85 1998/08/13 19:12:20 gibbs Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -343,7 +343,7 @@ pci_readcfg(pcicfgregs *probe)
|
||||
if (cfg->intpin != 0) {
|
||||
int airq;
|
||||
|
||||
airq = pci_apic_pin(cfg->bus, cfg->slot, cfg->intpin);
|
||||
airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin);
|
||||
if (airq >= 0) {
|
||||
/* PCI specific entry found in MP table */
|
||||
if (airq != cfg->intline) {
|
||||
@ -357,7 +357,7 @@ pci_readcfg(pcicfgregs *probe)
|
||||
* same methods as used by the ISA devices
|
||||
* devices to find the proper IOAPIC int pin.
|
||||
*/
|
||||
airq = isa_apic_pin(cfg->intline);
|
||||
airq = isa_apic_irq(cfg->intline);
|
||||
if ((airq >= 0) && (airq != cfg->intline)) {
|
||||
/* XXX: undirect_pci_irq() ? */
|
||||
undirect_isa_irq(cfg->intline);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* from: vector.s, 386BSD 0.1 unknown origin
|
||||
* $Id: apic_vector.s,v 1.32 1998/08/11 17:01:32 bde Exp $
|
||||
* $Id: apic_vector.s,v 1.33 1998/09/04 23:03:04 luoqi Exp $
|
||||
*/
|
||||
|
||||
|
||||
@ -166,13 +166,17 @@ IDTVEC(vec_name) ; \
|
||||
popal ; \
|
||||
addl $4+4,%esp
|
||||
|
||||
#define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8
|
||||
#define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12
|
||||
|
||||
#define MASK_IRQ(irq_num) \
|
||||
IMASK_LOCK ; /* into critical reg */ \
|
||||
testl $IRQ_BIT(irq_num), _apic_imen ; \
|
||||
jne 7f ; /* masked, don't mask */ \
|
||||
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 IOAPICADDR(irq_num), %ecx ; /* ioapic addr */ \
|
||||
movl REDIRIDX(irq_num), %eax ; /* get the index */ \
|
||||
movl %eax, (%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 */ \
|
||||
@ -218,8 +222,9 @@ IDTVEC(vec_name) ; \
|
||||
testl $IRQ_BIT(irq_num), _apic_imen ; \
|
||||
je 7f ; /* bit clear, not masked */ \
|
||||
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 IOAPICADDR(irq_num),%ecx ; /* ioapic addr */ \
|
||||
movl REDIRIDX(irq_num), %eax ; /* get the index */ \
|
||||
movl %eax,(%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 */ \
|
||||
@ -990,7 +995,7 @@ CNAME(cpustop_restartfunc):
|
||||
|
||||
.globl _apic_pin_trigger
|
||||
_apic_pin_trigger:
|
||||
.space (NAPIC * 4), 0
|
||||
.long 0
|
||||
|
||||
|
||||
/*
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $
|
||||
* $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -278,6 +278,8 @@ struct {
|
||||
} apic_isrbit_location[32];
|
||||
#endif
|
||||
|
||||
struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE];
|
||||
|
||||
/*
|
||||
* APIC ID logical/physical mapping structures.
|
||||
* We oversize these to simplify boot-time config.
|
||||
@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD;
|
||||
|
||||
struct pcb stoppcbs[NCPU];
|
||||
|
||||
static int smp_started; /* has the system started? */
|
||||
int smp_started; /* has the system started? */
|
||||
|
||||
/*
|
||||
* Local data and functions.
|
||||
@ -334,6 +336,7 @@ static int mptable_pass1(void);
|
||||
static int mptable_pass2(void);
|
||||
static void default_mp_table(int type);
|
||||
static void fix_mp_table(void);
|
||||
static void setup_apic_irq_mapping(void);
|
||||
static void init_locks(void);
|
||||
static int start_all_aps(u_int boot_addr);
|
||||
static void install_ap_tramp(u_int boot_addr);
|
||||
@ -569,6 +572,7 @@ mp_enable(u_int boot_addr)
|
||||
|
||||
/* post scan cleanup */
|
||||
fix_mp_table();
|
||||
setup_apic_irq_mapping();
|
||||
|
||||
#if defined(APIC_IO)
|
||||
|
||||
@ -675,6 +679,7 @@ typedef struct INTDATA {
|
||||
u_char src_bus_irq;
|
||||
u_char dst_apic_id;
|
||||
u_char dst_apic_int;
|
||||
u_char int_vector;
|
||||
} io_int, local_int;
|
||||
|
||||
typedef struct BUSTYPENAME {
|
||||
@ -905,8 +910,10 @@ mptable_pass2(void)
|
||||
bus_data[x].bus_id = 0xff;
|
||||
|
||||
/* clear IO APIC INT table */
|
||||
for (x = 0; x < NINTR; ++x)
|
||||
for (x = 0; x < NINTR; ++x) {
|
||||
io_apic_ints[x].int_type = 0xff;
|
||||
io_apic_ints[x].int_vector = 0xff;
|
||||
}
|
||||
|
||||
/* setup the cpu/apic mapping arrays */
|
||||
boot_cpu_id = -1;
|
||||
@ -966,6 +973,29 @@ mptable_pass2(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
assign_apic_irq(int apic, int intpin, int irq)
|
||||
{
|
||||
int x;
|
||||
|
||||
if (int_to_apicintpin[irq].ioapic != -1)
|
||||
panic("assign_apic_irq: inconsistent table");
|
||||
|
||||
int_to_apicintpin[irq].ioapic = apic;
|
||||
int_to_apicintpin[irq].int_pin = intpin;
|
||||
int_to_apicintpin[irq].apic_address = ioapic[apic];
|
||||
int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin;
|
||||
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) &&
|
||||
io_apic_ints[x].dst_apic_int == intpin)
|
||||
io_apic_ints[x].int_vector = irq;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* parse an Intel MP specification table
|
||||
*/
|
||||
@ -1041,6 +1071,50 @@ fix_mp_table(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_apic_irq_mapping(void)
|
||||
{
|
||||
int x;
|
||||
int int_vector;
|
||||
|
||||
/* Assign low level interrupt handlers */
|
||||
for (x = 0; x < APIC_INTMAPSIZE; x++) {
|
||||
int_to_apicintpin[x].ioapic = -1;
|
||||
int_to_apicintpin[x].int_pin = 0;
|
||||
int_to_apicintpin[x].apic_address = NULL;
|
||||
int_to_apicintpin[x].redirindex = 0;
|
||||
}
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
(io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3)) {
|
||||
assign_apic_irq(0,
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
io_apic_ints[x].dst_apic_int);
|
||||
}
|
||||
}
|
||||
int_vector = 0;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff) {
|
||||
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
int_vector);
|
||||
int_vector++;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
processor_entry(proc_entry_ptr entry, int cpu)
|
||||
{
|
||||
@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask)
|
||||
return 0;
|
||||
--isa_irq; /* make it zero based */
|
||||
|
||||
apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */
|
||||
apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */
|
||||
if (apic_pin == -1)
|
||||
return 0;
|
||||
|
||||
@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask)
|
||||
*/
|
||||
#define INTTYPE(I) (io_apic_ints[(I)].int_type)
|
||||
#define INTPIN(I) (io_apic_ints[(I)].dst_apic_int)
|
||||
#define INTIRQ(I) (io_apic_ints[(I)].int_vector)
|
||||
#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id))
|
||||
|
||||
#define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq)
|
||||
int
|
||||
isa_apic_pin(int isa_irq)
|
||||
isa_apic_irq(int isa_irq)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq)
|
||||
if (SRCBUSIRQ(intr) == isa_irq) {
|
||||
if (apic_int_is_bus_type(intr, ISA) ||
|
||||
apic_int_is_bus_type(intr, EISA))
|
||||
return INTPIN(intr); /* found */
|
||||
return INTIRQ(intr); /* found */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq)
|
||||
#define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f)
|
||||
#define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03)
|
||||
int
|
||||
pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
pci_apic_irq(int pciBus, int pciDevice, int pciInt)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
&& (SRCBUSDEVICE(intr) == pciDevice)
|
||||
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
|
||||
if (apic_int_is_bus_type(intr, PCI))
|
||||
return INTPIN(intr); /* exact match */
|
||||
return INTIRQ(intr); /* exact match */
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
next_apic_irq(int irq)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
@ -1230,7 +1306,7 @@ next_apic_pin(int pin)
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
if (INTIRQ(intr) != irq || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
@ -1265,7 +1341,7 @@ next_apic_pin(int pin)
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
return INTIRQ(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
@ -1273,6 +1349,8 @@ next_apic_pin(int pin)
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTIRQ
|
||||
#undef INTAPIC
|
||||
#undef INTTYPE
|
||||
|
||||
|
||||
@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin)
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
apic_irq(int apic, int pin)
|
||||
{
|
||||
int x;
|
||||
int res;
|
||||
|
||||
for (x = 0; x < nintrs; ++x)
|
||||
if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
|
||||
(pin == io_apic_ints[x].dst_apic_int)) {
|
||||
res = io_apic_ints[x].int_vector;
|
||||
if (res == 0xff)
|
||||
return -1;
|
||||
if (apic != int_to_apicintpin[res].ioapic)
|
||||
panic("apic_irq: inconsistent table");
|
||||
if (pin != int_to_apicintpin[res].int_pin)
|
||||
panic("apic_irq inconsistent table (2)");
|
||||
return res;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* given a LOGICAL APIC# and pin#, return:
|
||||
@ -2127,9 +2226,11 @@ ap_init()
|
||||
* quite correct yet. We should have a bitfield for cpus willing
|
||||
* to accept TLB flush IPI's or something and sync them.
|
||||
*/
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
if (smp_cpus == mp_ncpus) {
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
}
|
||||
|
||||
curproc = NULL; /* make sure */
|
||||
}
|
||||
|
@ -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.30 1998/04/19 23:19:20 tegge Exp $
|
||||
* $Id: mpapic.c,v 1.31 1998/05/17 17:32:10 tegge Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -146,7 +146,7 @@ static void polarity __P((int apic, int pin, u_int32_t * flags, int level));
|
||||
/*
|
||||
* Setup the IO APIC.
|
||||
*/
|
||||
extern int apic_pin_trigger[]; /* 'opaque' */
|
||||
extern int apic_pin_trigger; /* 'opaque' */
|
||||
int
|
||||
io_apic_setup(int apic)
|
||||
{
|
||||
@ -159,56 +159,55 @@ io_apic_setup(int apic)
|
||||
|
||||
target = IOART_DEST;
|
||||
|
||||
apic_pin_trigger[apic] = 0; /* default to edge-triggered */
|
||||
if (apic == 0)
|
||||
apic_pin_trigger = 0; /* default to edge-triggered */
|
||||
|
||||
if (apic == 0) {
|
||||
maxpin = REDIRCNT_IOAPIC(apic); /* pins in APIC */
|
||||
for (pin = 0; pin < maxpin; ++pin) {
|
||||
int bus, bustype;
|
||||
maxpin = REDIRCNT_IOAPIC(apic); /* pins in APIC */
|
||||
printf("Programming %d pins in IOAPIC #%d\n", maxpin, apic);
|
||||
|
||||
for (pin = 0; pin < maxpin; ++pin) {
|
||||
int bus, bustype, irq;
|
||||
|
||||
/* we only deal with vectored INTs here */
|
||||
if (apic_int_type(apic, pin) != 0)
|
||||
continue;
|
||||
|
||||
/* we only deal with vectored INTs here */
|
||||
if (apic_int_type(apic, pin) != 0)
|
||||
continue;
|
||||
|
||||
/* determine the bus type for this pin */
|
||||
bus = apic_src_bus_id(apic, pin);
|
||||
if (bus == -1)
|
||||
continue;
|
||||
bustype = apic_bus_type(bus);
|
||||
|
||||
/* the "ISA" type INTerrupts */
|
||||
if ((bustype == ISA) &&
|
||||
(pin < IOAPIC_ISA_INTS) &&
|
||||
(isa_apic_pin(pin) == pin) &&
|
||||
(apic_polarity(apic, pin) == 0x1) &&
|
||||
(apic_trigger(apic, pin) == 0x3)) {
|
||||
flags = DEFAULT_ISA_FLAGS;
|
||||
}
|
||||
|
||||
/* PCI or other bus */
|
||||
else {
|
||||
flags = DEFAULT_FLAGS;
|
||||
level = trigger(apic, pin, &flags);
|
||||
if (level == 1)
|
||||
apic_pin_trigger[apic] |= (1 << pin);
|
||||
polarity(apic, pin, &flags, level);
|
||||
}
|
||||
|
||||
/* program the appropriate registers */
|
||||
select = pin * 2 + IOAPIC_REDTBL0; /* register */
|
||||
vector = NRSVIDT + pin; /* IDT vec */
|
||||
io_apic_write(apic, select, flags | vector);
|
||||
io_apic_write(apic, select + 1, target);
|
||||
irq = apic_irq(apic, pin);
|
||||
if (irq == 0xff)
|
||||
continue;
|
||||
|
||||
/* determine the bus type for this pin */
|
||||
bus = apic_src_bus_id(apic, pin);
|
||||
if (bus == -1)
|
||||
continue;
|
||||
bustype = apic_bus_type(bus);
|
||||
|
||||
/* the "ISA" type INTerrupts */
|
||||
if ((bustype == ISA) &&
|
||||
(pin < IOAPIC_ISA_INTS) &&
|
||||
(irq == pin) &&
|
||||
(apic_polarity(apic, pin) == 0x1) &&
|
||||
(apic_trigger(apic, pin) == 0x3)) {
|
||||
flags = DEFAULT_ISA_FLAGS;
|
||||
}
|
||||
}
|
||||
|
||||
/* program entry according to MP table. */
|
||||
else {
|
||||
#if defined(MULTIPLE_IOAPICS)
|
||||
#error MULTIPLE_IOAPICSXXX
|
||||
#else
|
||||
panic("io_apic_setup: apic #%d", apic);
|
||||
#endif/* MULTIPLE_IOAPICS */
|
||||
|
||||
/* PCI or other bus */
|
||||
else {
|
||||
flags = DEFAULT_FLAGS;
|
||||
level = trigger(apic, pin, &flags);
|
||||
if (level == 1)
|
||||
apic_pin_trigger |= (1 << irq);
|
||||
polarity(apic, pin, &flags, level);
|
||||
}
|
||||
|
||||
/* program the appropriate registers */
|
||||
if (apic != 0 || pin != irq)
|
||||
printf("IOAPIC #%d intpint %d -> irq %d\n",
|
||||
apic, pin, irq);
|
||||
select = pin * 2 + IOAPIC_REDTBL0; /* register */
|
||||
vector = NRSVIDT + irq; /* IDT vec */
|
||||
io_apic_write(apic, select, flags | vector);
|
||||
io_apic_write(apic, select + 1, target);
|
||||
}
|
||||
|
||||
/* return GOOD status */
|
||||
|
@ -31,7 +31,7 @@
|
||||
* mpboot.s: FreeBSD machine support for the Intel MP Spec
|
||||
* multiprocessor systems.
|
||||
*
|
||||
* $Id: mpboot.s,v 1.5 1997/09/22 05:03:03 peter Exp $
|
||||
* $Id: mpboot.s,v 1.6 1997/10/10 09:44:05 peter Exp $
|
||||
*/
|
||||
|
||||
#include "opt_vm86.h"
|
||||
@ -124,6 +124,12 @@ mp_begin: /* now running relocated at KERNBASE */
|
||||
/* Now, let's prepare for some REAL WORK :-) */
|
||||
call _ap_init
|
||||
|
||||
call _rel_mplock
|
||||
2:
|
||||
cmpl $0, CNAME(smp_started) /* Wait for last AP to be ready */
|
||||
jz 2b
|
||||
call _get_mplock
|
||||
|
||||
/* let her rip! (loads new stack) */
|
||||
jmp _cpu_switch
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $
|
||||
* $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -278,6 +278,8 @@ struct {
|
||||
} apic_isrbit_location[32];
|
||||
#endif
|
||||
|
||||
struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE];
|
||||
|
||||
/*
|
||||
* APIC ID logical/physical mapping structures.
|
||||
* We oversize these to simplify boot-time config.
|
||||
@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD;
|
||||
|
||||
struct pcb stoppcbs[NCPU];
|
||||
|
||||
static int smp_started; /* has the system started? */
|
||||
int smp_started; /* has the system started? */
|
||||
|
||||
/*
|
||||
* Local data and functions.
|
||||
@ -334,6 +336,7 @@ static int mptable_pass1(void);
|
||||
static int mptable_pass2(void);
|
||||
static void default_mp_table(int type);
|
||||
static void fix_mp_table(void);
|
||||
static void setup_apic_irq_mapping(void);
|
||||
static void init_locks(void);
|
||||
static int start_all_aps(u_int boot_addr);
|
||||
static void install_ap_tramp(u_int boot_addr);
|
||||
@ -569,6 +572,7 @@ mp_enable(u_int boot_addr)
|
||||
|
||||
/* post scan cleanup */
|
||||
fix_mp_table();
|
||||
setup_apic_irq_mapping();
|
||||
|
||||
#if defined(APIC_IO)
|
||||
|
||||
@ -675,6 +679,7 @@ typedef struct INTDATA {
|
||||
u_char src_bus_irq;
|
||||
u_char dst_apic_id;
|
||||
u_char dst_apic_int;
|
||||
u_char int_vector;
|
||||
} io_int, local_int;
|
||||
|
||||
typedef struct BUSTYPENAME {
|
||||
@ -905,8 +910,10 @@ mptable_pass2(void)
|
||||
bus_data[x].bus_id = 0xff;
|
||||
|
||||
/* clear IO APIC INT table */
|
||||
for (x = 0; x < NINTR; ++x)
|
||||
for (x = 0; x < NINTR; ++x) {
|
||||
io_apic_ints[x].int_type = 0xff;
|
||||
io_apic_ints[x].int_vector = 0xff;
|
||||
}
|
||||
|
||||
/* setup the cpu/apic mapping arrays */
|
||||
boot_cpu_id = -1;
|
||||
@ -966,6 +973,29 @@ mptable_pass2(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
assign_apic_irq(int apic, int intpin, int irq)
|
||||
{
|
||||
int x;
|
||||
|
||||
if (int_to_apicintpin[irq].ioapic != -1)
|
||||
panic("assign_apic_irq: inconsistent table");
|
||||
|
||||
int_to_apicintpin[irq].ioapic = apic;
|
||||
int_to_apicintpin[irq].int_pin = intpin;
|
||||
int_to_apicintpin[irq].apic_address = ioapic[apic];
|
||||
int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin;
|
||||
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) &&
|
||||
io_apic_ints[x].dst_apic_int == intpin)
|
||||
io_apic_ints[x].int_vector = irq;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* parse an Intel MP specification table
|
||||
*/
|
||||
@ -1041,6 +1071,50 @@ fix_mp_table(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_apic_irq_mapping(void)
|
||||
{
|
||||
int x;
|
||||
int int_vector;
|
||||
|
||||
/* Assign low level interrupt handlers */
|
||||
for (x = 0; x < APIC_INTMAPSIZE; x++) {
|
||||
int_to_apicintpin[x].ioapic = -1;
|
||||
int_to_apicintpin[x].int_pin = 0;
|
||||
int_to_apicintpin[x].apic_address = NULL;
|
||||
int_to_apicintpin[x].redirindex = 0;
|
||||
}
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
(io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3)) {
|
||||
assign_apic_irq(0,
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
io_apic_ints[x].dst_apic_int);
|
||||
}
|
||||
}
|
||||
int_vector = 0;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff) {
|
||||
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
int_vector);
|
||||
int_vector++;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
processor_entry(proc_entry_ptr entry, int cpu)
|
||||
{
|
||||
@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask)
|
||||
return 0;
|
||||
--isa_irq; /* make it zero based */
|
||||
|
||||
apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */
|
||||
apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */
|
||||
if (apic_pin == -1)
|
||||
return 0;
|
||||
|
||||
@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask)
|
||||
*/
|
||||
#define INTTYPE(I) (io_apic_ints[(I)].int_type)
|
||||
#define INTPIN(I) (io_apic_ints[(I)].dst_apic_int)
|
||||
#define INTIRQ(I) (io_apic_ints[(I)].int_vector)
|
||||
#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id))
|
||||
|
||||
#define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq)
|
||||
int
|
||||
isa_apic_pin(int isa_irq)
|
||||
isa_apic_irq(int isa_irq)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq)
|
||||
if (SRCBUSIRQ(intr) == isa_irq) {
|
||||
if (apic_int_is_bus_type(intr, ISA) ||
|
||||
apic_int_is_bus_type(intr, EISA))
|
||||
return INTPIN(intr); /* found */
|
||||
return INTIRQ(intr); /* found */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq)
|
||||
#define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f)
|
||||
#define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03)
|
||||
int
|
||||
pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
pci_apic_irq(int pciBus, int pciDevice, int pciInt)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
&& (SRCBUSDEVICE(intr) == pciDevice)
|
||||
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
|
||||
if (apic_int_is_bus_type(intr, PCI))
|
||||
return INTPIN(intr); /* exact match */
|
||||
return INTIRQ(intr); /* exact match */
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
next_apic_irq(int irq)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
@ -1230,7 +1306,7 @@ next_apic_pin(int pin)
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
if (INTIRQ(intr) != irq || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
@ -1265,7 +1341,7 @@ next_apic_pin(int pin)
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
return INTIRQ(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
@ -1273,6 +1349,8 @@ next_apic_pin(int pin)
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTIRQ
|
||||
#undef INTAPIC
|
||||
#undef INTTYPE
|
||||
|
||||
|
||||
@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin)
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
apic_irq(int apic, int pin)
|
||||
{
|
||||
int x;
|
||||
int res;
|
||||
|
||||
for (x = 0; x < nintrs; ++x)
|
||||
if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
|
||||
(pin == io_apic_ints[x].dst_apic_int)) {
|
||||
res = io_apic_ints[x].int_vector;
|
||||
if (res == 0xff)
|
||||
return -1;
|
||||
if (apic != int_to_apicintpin[res].ioapic)
|
||||
panic("apic_irq: inconsistent table");
|
||||
if (pin != int_to_apicintpin[res].int_pin)
|
||||
panic("apic_irq inconsistent table (2)");
|
||||
return res;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* given a LOGICAL APIC# and pin#, return:
|
||||
@ -2127,9 +2226,11 @@ ap_init()
|
||||
* quite correct yet. We should have a bitfield for cpus willing
|
||||
* to accept TLB flush IPI's or something and sync them.
|
||||
*/
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
if (smp_cpus == mp_ncpus) {
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
}
|
||||
|
||||
curproc = NULL; /* make sure */
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.123 1998/06/07 20:36:39 phk Exp $
|
||||
* $Id: clock.c,v 1.124 1998/06/09 13:10:46 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -953,7 +953,7 @@ cpu_initclocks()
|
||||
/* Finish initializing 8253 timer 0. */
|
||||
#ifdef APIC_IO
|
||||
|
||||
apic_8254_intr = isa_apic_pin(0);
|
||||
apic_8254_intr = isa_apic_irq(0);
|
||||
apic_8254_trial = 0;
|
||||
if (apic_8254_intr >= 0 ) {
|
||||
if (apic_int_type(0, 0) == 3)
|
||||
@ -993,7 +993,7 @@ cpu_initclocks()
|
||||
printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
|
||||
|
||||
#ifdef APIC_IO
|
||||
if (isa_apic_pin(8) != 8)
|
||||
if (isa_apic_irq(8) != 8)
|
||||
panic("APIC RTC != 8");
|
||||
#endif /* APIC_IO */
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: apic.h,v 1.7 1997/08/04 17:20:39 smp Exp smp $
|
||||
* $Id: apic.h,v 1.11 1997/08/04 17:31:24 fsmp Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_APIC_H_
|
||||
@ -113,12 +113,6 @@
|
||||
* global defines, etc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* this enables code concerned with handling more than one IO APIC.
|
||||
* Note: this is NOT READY for use!
|
||||
*
|
||||
#define MULTIPLE_IOAPICS
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* LOCAL APIC structure
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: apic.h,v 1.7 1997/08/04 17:20:39 smp Exp smp $
|
||||
* $Id: apic.h,v 1.11 1997/08/04 17:31:24 fsmp Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_APIC_H_
|
||||
@ -113,12 +113,6 @@
|
||||
* global defines, etc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* this enables code concerned with handling more than one IO APIC.
|
||||
* Note: this is NOT READY for use!
|
||||
*
|
||||
#define MULTIPLE_IOAPICS
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* LOCAL APIC structure
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $
|
||||
* $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -278,6 +278,8 @@ struct {
|
||||
} apic_isrbit_location[32];
|
||||
#endif
|
||||
|
||||
struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE];
|
||||
|
||||
/*
|
||||
* APIC ID logical/physical mapping structures.
|
||||
* We oversize these to simplify boot-time config.
|
||||
@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD;
|
||||
|
||||
struct pcb stoppcbs[NCPU];
|
||||
|
||||
static int smp_started; /* has the system started? */
|
||||
int smp_started; /* has the system started? */
|
||||
|
||||
/*
|
||||
* Local data and functions.
|
||||
@ -334,6 +336,7 @@ static int mptable_pass1(void);
|
||||
static int mptable_pass2(void);
|
||||
static void default_mp_table(int type);
|
||||
static void fix_mp_table(void);
|
||||
static void setup_apic_irq_mapping(void);
|
||||
static void init_locks(void);
|
||||
static int start_all_aps(u_int boot_addr);
|
||||
static void install_ap_tramp(u_int boot_addr);
|
||||
@ -569,6 +572,7 @@ mp_enable(u_int boot_addr)
|
||||
|
||||
/* post scan cleanup */
|
||||
fix_mp_table();
|
||||
setup_apic_irq_mapping();
|
||||
|
||||
#if defined(APIC_IO)
|
||||
|
||||
@ -675,6 +679,7 @@ typedef struct INTDATA {
|
||||
u_char src_bus_irq;
|
||||
u_char dst_apic_id;
|
||||
u_char dst_apic_int;
|
||||
u_char int_vector;
|
||||
} io_int, local_int;
|
||||
|
||||
typedef struct BUSTYPENAME {
|
||||
@ -905,8 +910,10 @@ mptable_pass2(void)
|
||||
bus_data[x].bus_id = 0xff;
|
||||
|
||||
/* clear IO APIC INT table */
|
||||
for (x = 0; x < NINTR; ++x)
|
||||
for (x = 0; x < NINTR; ++x) {
|
||||
io_apic_ints[x].int_type = 0xff;
|
||||
io_apic_ints[x].int_vector = 0xff;
|
||||
}
|
||||
|
||||
/* setup the cpu/apic mapping arrays */
|
||||
boot_cpu_id = -1;
|
||||
@ -966,6 +973,29 @@ mptable_pass2(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
assign_apic_irq(int apic, int intpin, int irq)
|
||||
{
|
||||
int x;
|
||||
|
||||
if (int_to_apicintpin[irq].ioapic != -1)
|
||||
panic("assign_apic_irq: inconsistent table");
|
||||
|
||||
int_to_apicintpin[irq].ioapic = apic;
|
||||
int_to_apicintpin[irq].int_pin = intpin;
|
||||
int_to_apicintpin[irq].apic_address = ioapic[apic];
|
||||
int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin;
|
||||
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) &&
|
||||
io_apic_ints[x].dst_apic_int == intpin)
|
||||
io_apic_ints[x].int_vector = irq;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* parse an Intel MP specification table
|
||||
*/
|
||||
@ -1041,6 +1071,50 @@ fix_mp_table(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_apic_irq_mapping(void)
|
||||
{
|
||||
int x;
|
||||
int int_vector;
|
||||
|
||||
/* Assign low level interrupt handlers */
|
||||
for (x = 0; x < APIC_INTMAPSIZE; x++) {
|
||||
int_to_apicintpin[x].ioapic = -1;
|
||||
int_to_apicintpin[x].int_pin = 0;
|
||||
int_to_apicintpin[x].apic_address = NULL;
|
||||
int_to_apicintpin[x].redirindex = 0;
|
||||
}
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
(io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3)) {
|
||||
assign_apic_irq(0,
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
io_apic_ints[x].dst_apic_int);
|
||||
}
|
||||
}
|
||||
int_vector = 0;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff) {
|
||||
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
int_vector);
|
||||
int_vector++;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
processor_entry(proc_entry_ptr entry, int cpu)
|
||||
{
|
||||
@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask)
|
||||
return 0;
|
||||
--isa_irq; /* make it zero based */
|
||||
|
||||
apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */
|
||||
apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */
|
||||
if (apic_pin == -1)
|
||||
return 0;
|
||||
|
||||
@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask)
|
||||
*/
|
||||
#define INTTYPE(I) (io_apic_ints[(I)].int_type)
|
||||
#define INTPIN(I) (io_apic_ints[(I)].dst_apic_int)
|
||||
#define INTIRQ(I) (io_apic_ints[(I)].int_vector)
|
||||
#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id))
|
||||
|
||||
#define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq)
|
||||
int
|
||||
isa_apic_pin(int isa_irq)
|
||||
isa_apic_irq(int isa_irq)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq)
|
||||
if (SRCBUSIRQ(intr) == isa_irq) {
|
||||
if (apic_int_is_bus_type(intr, ISA) ||
|
||||
apic_int_is_bus_type(intr, EISA))
|
||||
return INTPIN(intr); /* found */
|
||||
return INTIRQ(intr); /* found */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq)
|
||||
#define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f)
|
||||
#define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03)
|
||||
int
|
||||
pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
pci_apic_irq(int pciBus, int pciDevice, int pciInt)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
&& (SRCBUSDEVICE(intr) == pciDevice)
|
||||
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
|
||||
if (apic_int_is_bus_type(intr, PCI))
|
||||
return INTPIN(intr); /* exact match */
|
||||
return INTIRQ(intr); /* exact match */
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
next_apic_irq(int irq)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
@ -1230,7 +1306,7 @@ next_apic_pin(int pin)
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
if (INTIRQ(intr) != irq || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
@ -1265,7 +1341,7 @@ next_apic_pin(int pin)
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
return INTIRQ(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
@ -1273,6 +1349,8 @@ next_apic_pin(int pin)
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTIRQ
|
||||
#undef INTAPIC
|
||||
#undef INTTYPE
|
||||
|
||||
|
||||
@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin)
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
apic_irq(int apic, int pin)
|
||||
{
|
||||
int x;
|
||||
int res;
|
||||
|
||||
for (x = 0; x < nintrs; ++x)
|
||||
if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
|
||||
(pin == io_apic_ints[x].dst_apic_int)) {
|
||||
res = io_apic_ints[x].int_vector;
|
||||
if (res == 0xff)
|
||||
return -1;
|
||||
if (apic != int_to_apicintpin[res].ioapic)
|
||||
panic("apic_irq: inconsistent table");
|
||||
if (pin != int_to_apicintpin[res].int_pin)
|
||||
panic("apic_irq inconsistent table (2)");
|
||||
return res;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* given a LOGICAL APIC# and pin#, return:
|
||||
@ -2127,9 +2226,11 @@ ap_init()
|
||||
* quite correct yet. We should have a bitfield for cpus willing
|
||||
* to accept TLB flush IPI's or something and sync them.
|
||||
*/
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
if (smp_cpus == mp_ncpus) {
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
}
|
||||
|
||||
curproc = NULL; /* make sure */
|
||||
}
|
||||
|
@ -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.42 1998/04/01 21:07:36 tegge Exp $
|
||||
* $Id: smp.h,v 1.43 1998/05/17 22:12:05 tegge Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -103,6 +103,14 @@ extern u_int32_t io_apic_versions[];
|
||||
extern int cpu_num_to_apic_id[];
|
||||
extern int io_num_to_apic_id[];
|
||||
extern int apic_id_to_logical[];
|
||||
#define APIC_INTMAPSIZE 24
|
||||
struct apic_intmapinfo {
|
||||
int ioapic;
|
||||
int int_pin;
|
||||
volatile void *apic_address;
|
||||
int redirindex;
|
||||
};
|
||||
extern struct apic_intmapinfo int_to_apicintpin[];
|
||||
extern u_int all_cpus;
|
||||
extern u_char SMP_ioapic[];
|
||||
extern struct pcb stoppcbs[];
|
||||
@ -113,9 +121,10 @@ int mp_probe __P((void));
|
||||
void mp_start __P((void));
|
||||
void mp_announce __P((void));
|
||||
u_int isa_apic_mask __P((u_int));
|
||||
int isa_apic_pin __P((int));
|
||||
int pci_apic_pin __P((int, int, int));
|
||||
int next_apic_pin __P((int));
|
||||
int isa_apic_irq __P((int));
|
||||
int pci_apic_irq __P((int, int, int));
|
||||
int apic_irq __P((int, int));
|
||||
int next_apic_irq __P((int));
|
||||
int undirect_isa_irq __P((int));
|
||||
int undirect_pci_irq __P((int));
|
||||
int apic_bus_type __P((int));
|
||||
@ -141,12 +150,7 @@ void set_lapic_isrloc __P((int, int));
|
||||
|
||||
/* global data in mpapic.c */
|
||||
extern volatile lapic_t lapic;
|
||||
|
||||
#if defined(MULTIPLE_IOAPICS)
|
||||
#error MULTIPLE_IOAPICSXXX
|
||||
#else
|
||||
extern volatile ioapic_t *ioapic[];
|
||||
#endif /* MULTIPLE_IOAPICS */
|
||||
|
||||
/* functions in mpapic.c */
|
||||
void apic_dump __P((char*));
|
||||
|
@ -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.20 1998/04/22 22:49:29 tegge Exp $
|
||||
* $Id: apic_ipl.s,v 1.21 1998/08/11 15:08:12 bde Exp $
|
||||
*/
|
||||
|
||||
|
||||
@ -227,7 +227,6 @@ bad_mask: .asciz "bad mask"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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 sets the associated bit in _apic_imen.
|
||||
@ -244,10 +243,9 @@ ENTRY(INTREN)
|
||||
|
||||
QUALIFY_MASK
|
||||
|
||||
leal 16(,%ecx,2), %ecx /* calculate register index */
|
||||
|
||||
movl $0, %edx /* XXX FIXME: APIC # */
|
||||
movl _ioapic(,%edx,4), %edx /* %edx holds APIC base address */
|
||||
shll $4, %ecx
|
||||
movl CNAME(int_to_apicintpin) + 8(%ecx), %edx
|
||||
movl CNAME(int_to_apicintpin) + 12(%ecx), %ecx
|
||||
|
||||
movl %ecx, (%edx) /* write the target register index */
|
||||
movl 16(%edx), %eax /* read the target register data */
|
||||
@ -259,7 +257,6 @@ ENTRY(INTREN)
|
||||
ret
|
||||
|
||||
/*
|
||||
* 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 clears the associated bit in _apic_imen.
|
||||
@ -276,10 +273,9 @@ ENTRY(INTRDIS)
|
||||
|
||||
QUALIFY_MASK
|
||||
|
||||
leal 16(,%ecx,2), %ecx /* calculate register index */
|
||||
|
||||
movl $0, %edx /* XXX FIXME: APIC # */
|
||||
movl _ioapic(,%edx,4), %edx /* %edx holds APIC base address */
|
||||
shll $4, %ecx
|
||||
movl CNAME(int_to_apicintpin) + 8(%ecx), %edx
|
||||
movl CNAME(int_to_apicintpin) + 12(%ecx), %ecx
|
||||
|
||||
movl %ecx, (%edx) /* write the target register index */
|
||||
movl 16(%edx), %eax /* read the target register data */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* from: vector.s, 386BSD 0.1 unknown origin
|
||||
* $Id: apic_vector.s,v 1.32 1998/08/11 17:01:32 bde Exp $
|
||||
* $Id: apic_vector.s,v 1.33 1998/09/04 23:03:04 luoqi Exp $
|
||||
*/
|
||||
|
||||
|
||||
@ -166,13 +166,17 @@ IDTVEC(vec_name) ; \
|
||||
popal ; \
|
||||
addl $4+4,%esp
|
||||
|
||||
#define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8
|
||||
#define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12
|
||||
|
||||
#define MASK_IRQ(irq_num) \
|
||||
IMASK_LOCK ; /* into critical reg */ \
|
||||
testl $IRQ_BIT(irq_num), _apic_imen ; \
|
||||
jne 7f ; /* masked, don't mask */ \
|
||||
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 IOAPICADDR(irq_num), %ecx ; /* ioapic addr */ \
|
||||
movl REDIRIDX(irq_num), %eax ; /* get the index */ \
|
||||
movl %eax, (%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 */ \
|
||||
@ -218,8 +222,9 @@ IDTVEC(vec_name) ; \
|
||||
testl $IRQ_BIT(irq_num), _apic_imen ; \
|
||||
je 7f ; /* bit clear, not masked */ \
|
||||
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 IOAPICADDR(irq_num),%ecx ; /* ioapic addr */ \
|
||||
movl REDIRIDX(irq_num), %eax ; /* get the index */ \
|
||||
movl %eax,(%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 */ \
|
||||
@ -990,7 +995,7 @@ CNAME(cpustop_restartfunc):
|
||||
|
||||
.globl _apic_pin_trigger
|
||||
_apic_pin_trigger:
|
||||
.space (NAPIC * 4), 0
|
||||
.long 0
|
||||
|
||||
|
||||
/*
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.123 1998/06/07 20:36:39 phk Exp $
|
||||
* $Id: clock.c,v 1.124 1998/06/09 13:10:46 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -953,7 +953,7 @@ cpu_initclocks()
|
||||
/* Finish initializing 8253 timer 0. */
|
||||
#ifdef APIC_IO
|
||||
|
||||
apic_8254_intr = isa_apic_pin(0);
|
||||
apic_8254_intr = isa_apic_irq(0);
|
||||
apic_8254_trial = 0;
|
||||
if (apic_8254_intr >= 0 ) {
|
||||
if (apic_int_type(0, 0) == 3)
|
||||
@ -993,7 +993,7 @@ cpu_initclocks()
|
||||
printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
|
||||
|
||||
#ifdef APIC_IO
|
||||
if (isa_apic_pin(8) != 8)
|
||||
if (isa_apic_irq(8) != 8)
|
||||
panic("APIC RTC != 8");
|
||||
#endif /* APIC_IO */
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
|
||||
* $Id: intr_machdep.c,v 1.12 1998/06/18 15:32:06 bde Exp $
|
||||
* $Id: intr_machdep.c,v 1.13 1998/06/18 16:08:46 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_auto_eoi.h"
|
||||
@ -429,12 +429,15 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags)
|
||||
set_lapic_isrloc(intr, vector);
|
||||
#endif
|
||||
/*
|
||||
* 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);
|
||||
if (int_to_apicintpin[intr].ioapic >= 0) {
|
||||
select = int_to_apicintpin[intr].redirindex;
|
||||
value = io_apic_read(int_to_apicintpin[intr].ioapic,
|
||||
select) & ~IOART_INTVEC;
|
||||
io_apic_write(int_to_apicintpin[intr].ioapic,
|
||||
select, value | vector);
|
||||
}
|
||||
#else
|
||||
setidt(ICU_OFFSET + intr,
|
||||
flags & INTR_FAST ? fastintr[intr] : slowintr[intr],
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
|
||||
* $Id: intr_machdep.c,v 1.12 1998/06/18 15:32:06 bde Exp $
|
||||
* $Id: intr_machdep.c,v 1.13 1998/06/18 16:08:46 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_auto_eoi.h"
|
||||
@ -429,12 +429,15 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags)
|
||||
set_lapic_isrloc(intr, vector);
|
||||
#endif
|
||||
/*
|
||||
* 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);
|
||||
if (int_to_apicintpin[intr].ioapic >= 0) {
|
||||
select = int_to_apicintpin[intr].redirindex;
|
||||
value = io_apic_read(int_to_apicintpin[intr].ioapic,
|
||||
select) & ~IOART_INTVEC;
|
||||
io_apic_write(int_to_apicintpin[intr].ioapic,
|
||||
select, value | vector);
|
||||
}
|
||||
#else
|
||||
setidt(ICU_OFFSET + intr,
|
||||
flags & INTR_FAST ? fastintr[intr] : slowintr[intr],
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
* $Id: clock.c,v 1.123 1998/06/07 20:36:39 phk Exp $
|
||||
* $Id: clock.c,v 1.124 1998/06/09 13:10:46 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -953,7 +953,7 @@ cpu_initclocks()
|
||||
/* Finish initializing 8253 timer 0. */
|
||||
#ifdef APIC_IO
|
||||
|
||||
apic_8254_intr = isa_apic_pin(0);
|
||||
apic_8254_intr = isa_apic_irq(0);
|
||||
apic_8254_trial = 0;
|
||||
if (apic_8254_intr >= 0 ) {
|
||||
if (apic_int_type(0, 0) == 3)
|
||||
@ -993,7 +993,7 @@ cpu_initclocks()
|
||||
printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
|
||||
|
||||
#ifdef APIC_IO
|
||||
if (isa_apic_pin(8) != 8)
|
||||
if (isa_apic_irq(8) != 8)
|
||||
panic("APIC RTC != 8");
|
||||
#endif /* APIC_IO */
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $
|
||||
* $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_smp.h"
|
||||
@ -278,6 +278,8 @@ struct {
|
||||
} apic_isrbit_location[32];
|
||||
#endif
|
||||
|
||||
struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE];
|
||||
|
||||
/*
|
||||
* APIC ID logical/physical mapping structures.
|
||||
* We oversize these to simplify boot-time config.
|
||||
@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD;
|
||||
|
||||
struct pcb stoppcbs[NCPU];
|
||||
|
||||
static int smp_started; /* has the system started? */
|
||||
int smp_started; /* has the system started? */
|
||||
|
||||
/*
|
||||
* Local data and functions.
|
||||
@ -334,6 +336,7 @@ static int mptable_pass1(void);
|
||||
static int mptable_pass2(void);
|
||||
static void default_mp_table(int type);
|
||||
static void fix_mp_table(void);
|
||||
static void setup_apic_irq_mapping(void);
|
||||
static void init_locks(void);
|
||||
static int start_all_aps(u_int boot_addr);
|
||||
static void install_ap_tramp(u_int boot_addr);
|
||||
@ -569,6 +572,7 @@ mp_enable(u_int boot_addr)
|
||||
|
||||
/* post scan cleanup */
|
||||
fix_mp_table();
|
||||
setup_apic_irq_mapping();
|
||||
|
||||
#if defined(APIC_IO)
|
||||
|
||||
@ -675,6 +679,7 @@ typedef struct INTDATA {
|
||||
u_char src_bus_irq;
|
||||
u_char dst_apic_id;
|
||||
u_char dst_apic_int;
|
||||
u_char int_vector;
|
||||
} io_int, local_int;
|
||||
|
||||
typedef struct BUSTYPENAME {
|
||||
@ -905,8 +910,10 @@ mptable_pass2(void)
|
||||
bus_data[x].bus_id = 0xff;
|
||||
|
||||
/* clear IO APIC INT table */
|
||||
for (x = 0; x < NINTR; ++x)
|
||||
for (x = 0; x < NINTR; ++x) {
|
||||
io_apic_ints[x].int_type = 0xff;
|
||||
io_apic_ints[x].int_vector = 0xff;
|
||||
}
|
||||
|
||||
/* setup the cpu/apic mapping arrays */
|
||||
boot_cpu_id = -1;
|
||||
@ -966,6 +973,29 @@ mptable_pass2(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
assign_apic_irq(int apic, int intpin, int irq)
|
||||
{
|
||||
int x;
|
||||
|
||||
if (int_to_apicintpin[irq].ioapic != -1)
|
||||
panic("assign_apic_irq: inconsistent table");
|
||||
|
||||
int_to_apicintpin[irq].ioapic = apic;
|
||||
int_to_apicintpin[irq].int_pin = intpin;
|
||||
int_to_apicintpin[irq].apic_address = ioapic[apic];
|
||||
int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin;
|
||||
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) &&
|
||||
io_apic_ints[x].dst_apic_int == intpin)
|
||||
io_apic_ints[x].int_vector = irq;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* parse an Intel MP specification table
|
||||
*/
|
||||
@ -1041,6 +1071,50 @@ fix_mp_table(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_apic_irq_mapping(void)
|
||||
{
|
||||
int x;
|
||||
int int_vector;
|
||||
|
||||
/* Assign low level interrupt handlers */
|
||||
for (x = 0; x < APIC_INTMAPSIZE; x++) {
|
||||
int_to_apicintpin[x].ioapic = -1;
|
||||
int_to_apicintpin[x].int_pin = 0;
|
||||
int_to_apicintpin[x].apic_address = NULL;
|
||||
int_to_apicintpin[x].redirindex = 0;
|
||||
}
|
||||
for (x = 0; x < nintrs; x++) {
|
||||
if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE &&
|
||||
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
|
||||
io_apic_ints[x].int_vector == 0xff &&
|
||||
(io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3)) {
|
||||
assign_apic_irq(0,
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
io_apic_ints[x].dst_apic_int);
|
||||
}
|
||||
}
|
||||
int_vector = 0;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) {
|
||||
if ((io_apic_ints[x].int_type == 0 ||
|
||||
io_apic_ints[x].int_type == 3) &&
|
||||
io_apic_ints[x].int_vector == 0xff) {
|
||||
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
|
||||
io_apic_ints[x].dst_apic_int,
|
||||
int_vector);
|
||||
int_vector++;
|
||||
while (int_vector < APIC_INTMAPSIZE &&
|
||||
int_to_apicintpin[int_vector].ioapic != -1)
|
||||
int_vector++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
processor_entry(proc_entry_ptr entry, int cpu)
|
||||
{
|
||||
@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask)
|
||||
return 0;
|
||||
--isa_irq; /* make it zero based */
|
||||
|
||||
apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */
|
||||
apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */
|
||||
if (apic_pin == -1)
|
||||
return 0;
|
||||
|
||||
@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask)
|
||||
*/
|
||||
#define INTTYPE(I) (io_apic_ints[(I)].int_type)
|
||||
#define INTPIN(I) (io_apic_ints[(I)].dst_apic_int)
|
||||
#define INTIRQ(I) (io_apic_ints[(I)].int_vector)
|
||||
#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id))
|
||||
|
||||
#define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq)
|
||||
int
|
||||
isa_apic_pin(int isa_irq)
|
||||
isa_apic_irq(int isa_irq)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq)
|
||||
if (SRCBUSIRQ(intr) == isa_irq) {
|
||||
if (apic_int_is_bus_type(intr, ISA) ||
|
||||
apic_int_is_bus_type(intr, EISA))
|
||||
return INTPIN(intr); /* found */
|
||||
return INTIRQ(intr); /* found */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq)
|
||||
#define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f)
|
||||
#define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03)
|
||||
int
|
||||
pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
pci_apic_irq(int pciBus, int pciDevice, int pciInt)
|
||||
{
|
||||
int intr;
|
||||
|
||||
@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt)
|
||||
&& (SRCBUSDEVICE(intr) == pciDevice)
|
||||
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
|
||||
if (apic_int_is_bus_type(intr, PCI))
|
||||
return INTPIN(intr); /* exact match */
|
||||
return INTIRQ(intr); /* exact match */
|
||||
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
next_apic_pin(int pin)
|
||||
next_apic_irq(int irq)
|
||||
{
|
||||
int intr, ointr;
|
||||
int bus, bustype;
|
||||
@ -1230,7 +1306,7 @@ next_apic_pin(int pin)
|
||||
bus = 0;
|
||||
bustype = 0;
|
||||
for (intr = 0; intr < nintrs; intr++) {
|
||||
if (INTPIN(intr) != pin || INTTYPE(intr) != 0)
|
||||
if (INTIRQ(intr) != irq || INTTYPE(intr) != 0)
|
||||
continue;
|
||||
bus = SRCBUSID(intr);
|
||||
bustype = apic_bus_type(bus);
|
||||
@ -1265,7 +1341,7 @@ next_apic_pin(int pin)
|
||||
if (ointr >= nintrs) {
|
||||
return -1;
|
||||
}
|
||||
return INTPIN(ointr);
|
||||
return INTIRQ(ointr);
|
||||
}
|
||||
#undef SRCBUSLINE
|
||||
#undef SRCBUSDEVICE
|
||||
@ -1273,6 +1349,8 @@ next_apic_pin(int pin)
|
||||
#undef SRCBUSIRQ
|
||||
|
||||
#undef INTPIN
|
||||
#undef INTIRQ
|
||||
#undef INTAPIC
|
||||
#undef INTTYPE
|
||||
|
||||
|
||||
@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin)
|
||||
return -1; /* NOT found */
|
||||
}
|
||||
|
||||
int
|
||||
apic_irq(int apic, int pin)
|
||||
{
|
||||
int x;
|
||||
int res;
|
||||
|
||||
for (x = 0; x < nintrs; ++x)
|
||||
if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) &&
|
||||
(pin == io_apic_ints[x].dst_apic_int)) {
|
||||
res = io_apic_ints[x].int_vector;
|
||||
if (res == 0xff)
|
||||
return -1;
|
||||
if (apic != int_to_apicintpin[res].ioapic)
|
||||
panic("apic_irq: inconsistent table");
|
||||
if (pin != int_to_apicintpin[res].int_pin)
|
||||
panic("apic_irq inconsistent table (2)");
|
||||
return res;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* given a LOGICAL APIC# and pin#, return:
|
||||
@ -2127,9 +2226,11 @@ ap_init()
|
||||
* quite correct yet. We should have a bitfield for cpus willing
|
||||
* to accept TLB flush IPI's or something and sync them.
|
||||
*/
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
if (smp_cpus == mp_ncpus) {
|
||||
invltlb_ok = 1;
|
||||
smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */
|
||||
smp_active = 1; /* historic */
|
||||
}
|
||||
|
||||
curproc = NULL; /* make sure */
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pci.c,v 1.84 1998/07/22 08:40:46 dfr Exp $
|
||||
* $Id: pci.c,v 1.85 1998/08/13 19:12:20 gibbs Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -343,7 +343,7 @@ pci_readcfg(pcicfgregs *probe)
|
||||
if (cfg->intpin != 0) {
|
||||
int airq;
|
||||
|
||||
airq = pci_apic_pin(cfg->bus, cfg->slot, cfg->intpin);
|
||||
airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin);
|
||||
if (airq >= 0) {
|
||||
/* PCI specific entry found in MP table */
|
||||
if (airq != cfg->intline) {
|
||||
@ -357,7 +357,7 @@ pci_readcfg(pcicfgregs *probe)
|
||||
* same methods as used by the ISA devices
|
||||
* devices to find the proper IOAPIC int pin.
|
||||
*/
|
||||
airq = isa_apic_pin(cfg->intline);
|
||||
airq = isa_apic_irq(cfg->intline);
|
||||
if ((airq >= 0) && (airq != cfg->intline)) {
|
||||
/* XXX: undirect_pci_irq() ? */
|
||||
undirect_isa_irq(cfg->intline);
|
||||
|
@ -23,7 +23,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pci_compat.c,v 1.8 1998/07/22 08:39:08 dfr Exp $
|
||||
* $Id: pci_compat.c,v 1.9 1998/08/07 08:20:36 dfr Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -182,7 +182,7 @@ pci_map_int(pcici_t cfg, pci_inthand_t *func, void *arg, unsigned *maskptr)
|
||||
if (error != 0)
|
||||
return 0;
|
||||
#ifdef APIC_IO
|
||||
nextpin = next_apic_pin(irq);
|
||||
nextpin = next_apic_irq(irq);
|
||||
|
||||
if (nextpin < 0)
|
||||
return 1;
|
||||
@ -196,10 +196,10 @@ pci_map_int(pcici_t cfg, pci_inthand_t *func, void *arg, unsigned *maskptr)
|
||||
*/
|
||||
|
||||
muxcnt = 2;
|
||||
nextpin = next_apic_pin(nextpin);
|
||||
nextpin = next_apic_irq(nextpin);
|
||||
while (muxcnt < 5 && nextpin >= 0) {
|
||||
muxcnt++;
|
||||
nextpin = next_apic_pin(nextpin);
|
||||
nextpin = next_apic_irq(nextpin);
|
||||
}
|
||||
if (muxcnt >= 5) {
|
||||
printf("bogus MP table, more than 4 IO APIC pins connected to the same PCI device or ISA/EISA interrupt\n");
|
||||
@ -208,7 +208,7 @@ pci_map_int(pcici_t cfg, pci_inthand_t *func, void *arg, unsigned *maskptr)
|
||||
|
||||
printf("bogus MP table, %d IO APIC pins connected to the same PCI device or ISA/EISA interrupt\n", muxcnt);
|
||||
|
||||
nextpin = next_apic_pin(irq);
|
||||
nextpin = next_apic_irq(irq);
|
||||
while (nextpin >= 0) {
|
||||
idesc = intr_create(dev_instance, nextpin, func, arg,
|
||||
maskptr, 0);
|
||||
@ -216,7 +216,7 @@ pci_map_int(pcici_t cfg, pci_inthand_t *func, void *arg, unsigned *maskptr)
|
||||
if (error != 0)
|
||||
return 0;
|
||||
printf("Registered extra interrupt handler for int %d (in addition to int %d)\n", nextpin, irq);
|
||||
nextpin = next_apic_pin(nextpin);
|
||||
nextpin = next_apic_irq(nextpin);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -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.42 1998/04/01 21:07:36 tegge Exp $
|
||||
* $Id: smp.h,v 1.43 1998/05/17 22:12:05 tegge Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -103,6 +103,14 @@ extern u_int32_t io_apic_versions[];
|
||||
extern int cpu_num_to_apic_id[];
|
||||
extern int io_num_to_apic_id[];
|
||||
extern int apic_id_to_logical[];
|
||||
#define APIC_INTMAPSIZE 24
|
||||
struct apic_intmapinfo {
|
||||
int ioapic;
|
||||
int int_pin;
|
||||
volatile void *apic_address;
|
||||
int redirindex;
|
||||
};
|
||||
extern struct apic_intmapinfo int_to_apicintpin[];
|
||||
extern u_int all_cpus;
|
||||
extern u_char SMP_ioapic[];
|
||||
extern struct pcb stoppcbs[];
|
||||
@ -113,9 +121,10 @@ int mp_probe __P((void));
|
||||
void mp_start __P((void));
|
||||
void mp_announce __P((void));
|
||||
u_int isa_apic_mask __P((u_int));
|
||||
int isa_apic_pin __P((int));
|
||||
int pci_apic_pin __P((int, int, int));
|
||||
int next_apic_pin __P((int));
|
||||
int isa_apic_irq __P((int));
|
||||
int pci_apic_irq __P((int, int, int));
|
||||
int apic_irq __P((int, int));
|
||||
int next_apic_irq __P((int));
|
||||
int undirect_isa_irq __P((int));
|
||||
int undirect_pci_irq __P((int));
|
||||
int apic_bus_type __P((int));
|
||||
@ -141,12 +150,7 @@ void set_lapic_isrloc __P((int, int));
|
||||
|
||||
/* global data in mpapic.c */
|
||||
extern volatile lapic_t lapic;
|
||||
|
||||
#if defined(MULTIPLE_IOAPICS)
|
||||
#error MULTIPLE_IOAPICSXXX
|
||||
#else
|
||||
extern volatile ioapic_t *ioapic[];
|
||||
#endif /* MULTIPLE_IOAPICS */
|
||||
|
||||
/* functions in mpapic.c */
|
||||
void apic_dump __P((char*));
|
||||
|
Loading…
Reference in New Issue
Block a user