summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/apic_vector.S17
-rw-r--r--sys/amd64/amd64/mp_machdep.c129
-rw-r--r--sys/amd64/amd64/mpboot.S8
-rw-r--r--sys/amd64/amd64/mptable.c129
-rw-r--r--sys/amd64/amd64/tsc.c6
-rw-r--r--sys/amd64/include/apicreg.h8
-rw-r--r--sys/amd64/include/mptable.h129
-rw-r--r--sys/amd64/include/smp.h22
-rw-r--r--sys/amd64/isa/clock.c6
-rw-r--r--sys/amd64/isa/intr_machdep.c13
-rw-r--r--sys/amd64/isa/nmi.c13
-rw-r--r--sys/dev/pci/pci.c6
-rw-r--r--sys/i386/i386/apic_vector.s17
-rw-r--r--sys/i386/i386/mp_machdep.c129
-rw-r--r--sys/i386/i386/mpapic.c101
-rw-r--r--sys/i386/i386/mpboot.s8
-rw-r--r--sys/i386/i386/mptable.c129
-rw-r--r--sys/i386/i386/tsc.c6
-rw-r--r--sys/i386/include/apic.h8
-rw-r--r--sys/i386/include/apicreg.h8
-rw-r--r--sys/i386/include/mptable.h129
-rw-r--r--sys/i386/include/smp.h22
-rw-r--r--sys/i386/isa/apic_ipl.s18
-rw-r--r--sys/i386/isa/apic_vector.s17
-rw-r--r--sys/i386/isa/clock.c6
-rw-r--r--sys/i386/isa/intr_machdep.c13
-rw-r--r--sys/i386/isa/nmi.c13
-rw-r--r--sys/isa/atrtc.c6
-rw-r--r--sys/kern/subr_smp.c129
-rw-r--r--sys/pci/pci.c6
-rw-r--r--sys/pci/pci_compat.c12
-rw-r--r--sys/sys/smp.h22
32 files changed, 1010 insertions, 275 deletions
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S
index 4bd4f77..17f8942 100644
--- a/sys/amd64/amd64/apic_vector.S
+++ b/sys/amd64/amd64/apic_vector.S
@@ -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
/*
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index 04e3c69..e00c2f4 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -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 */
}
diff --git a/sys/amd64/amd64/mpboot.S b/sys/amd64/amd64/mpboot.S
index e3661f2..1c311fe 100644
--- a/sys/amd64/amd64/mpboot.S
+++ b/sys/amd64/amd64/mpboot.S
@@ -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
diff --git a/sys/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c
index 04e3c69..e00c2f4 100644
--- a/sys/amd64/amd64/mptable.c
+++ b/sys/amd64/amd64/mptable.c
@@ -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 */
}
diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c
index 4e14052..3d8f8cd 100644
--- a/sys/amd64/amd64/tsc.c
+++ b/sys/amd64/amd64/tsc.c
@@ -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 */
diff --git a/sys/amd64/include/apicreg.h b/sys/amd64/include/apicreg.h
index 50f8416..55e44e0 100644
--- a/sys/amd64/include/apicreg.h
+++ b/sys/amd64/include/apicreg.h
@@ -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
diff --git a/sys/amd64/include/mptable.h b/sys/amd64/include/mptable.h
index 04e3c69..e00c2f4 100644
--- a/sys/amd64/include/mptable.h
+++ b/sys/amd64/include/mptable.h
@@ -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 */
}
diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h
index f258630..0f4f915 100644
--- a/sys/amd64/include/smp.h
+++ b/sys/amd64/include/smp.h
@@ -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*));
diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c
index 4e14052..3d8f8cd 100644
--- a/sys/amd64/isa/clock.c
+++ b/sys/amd64/isa/clock.c
@@ -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 */
diff --git a/sys/amd64/isa/intr_machdep.c b/sys/amd64/isa/intr_machdep.c
index 49c7f24..3f891f2 100644
--- a/sys/amd64/isa/intr_machdep.c
+++ b/sys/amd64/isa/intr_machdep.c
@@ -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],
diff --git a/sys/amd64/isa/nmi.c b/sys/amd64/isa/nmi.c
index 49c7f24..3f891f2 100644
--- a/sys/amd64/isa/nmi.c
+++ b/sys/amd64/isa/nmi.c
@@ -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],
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 2dac6de..fceb220 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -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);
diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s
index 4bd4f77..17f8942 100644
--- a/sys/i386/i386/apic_vector.s
+++ b/sys/i386/i386/apic_vector.s
@@ -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
/*
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index 04e3c69..e00c2f4 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -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 */
}
diff --git a/sys/i386/i386/mpapic.c b/sys/i386/i386/mpapic.c
index a101a2c..48663a4 100644
--- a/sys/i386/i386/mpapic.c
+++ b/sys/i386/i386/mpapic.c
@@ -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) {
- maxpin = REDIRCNT_IOAPIC(apic); /* pins in APIC */
- for (pin = 0; pin < maxpin; ++pin) {
- int bus, bustype;
-
- /* 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);
+ if (apic == 0)
+ apic_pin_trigger = 0; /* default to edge-triggered */
+
+ 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;
+
+ 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 */
diff --git a/sys/i386/i386/mpboot.s b/sys/i386/i386/mpboot.s
index e3661f2..1c311fe 100644
--- a/sys/i386/i386/mpboot.s
+++ b/sys/i386/i386/mpboot.s
@@ -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
diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c
index 04e3c69..e00c2f4 100644
--- a/sys/i386/i386/mptable.c
+++ b/sys/i386/i386/mptable.c
@@ -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 */
}
diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c
index 4e14052..3d8f8cd 100644
--- a/sys/i386/i386/tsc.c
+++ b/sys/i386/i386/tsc.c
@@ -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 */
diff --git a/sys/i386/include/apic.h b/sys/i386/include/apic.h
index 50f8416..55e44e0 100644
--- a/sys/i386/include/apic.h
+++ b/sys/i386/include/apic.h
@@ -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
diff --git a/sys/i386/include/apicreg.h b/sys/i386/include/apicreg.h
index 50f8416..55e44e0 100644
--- a/sys/i386/include/apicreg.h
+++ b/sys/i386/include/apicreg.h
@@ -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
diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h
index 04e3c69..e00c2f4 100644
--- a/sys/i386/include/mptable.h
+++ b/sys/i386/include/mptable.h
@@ -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 */
}
diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h
index f258630..0f4f915 100644
--- a/sys/i386/include/smp.h
+++ b/sys/i386/include/smp.h
@@ -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*));
diff --git a/sys/i386/isa/apic_ipl.s b/sys/i386/isa/apic_ipl.s
index 5bbdca6..8d9b9d8 100644
--- a/sys/i386/isa/apic_ipl.s
+++ b/sys/i386/isa/apic_ipl.s
@@ -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 */
diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s
index 4bd4f77..17f8942 100644
--- a/sys/i386/isa/apic_vector.s
+++ b/sys/i386/isa/apic_vector.s
@@ -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
/*
diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c
index 4e14052..3d8f8cd 100644
--- a/sys/i386/isa/clock.c
+++ b/sys/i386/isa/clock.c
@@ -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 */
diff --git a/sys/i386/isa/intr_machdep.c b/sys/i386/isa/intr_machdep.c
index 49c7f24..3f891f2 100644
--- a/sys/i386/isa/intr_machdep.c
+++ b/sys/i386/isa/intr_machdep.c
@@ -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],
diff --git a/sys/i386/isa/nmi.c b/sys/i386/isa/nmi.c
index 49c7f24..3f891f2 100644
--- a/sys/i386/isa/nmi.c
+++ b/sys/i386/isa/nmi.c
@@ -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],
diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c
index 4e14052..3d8f8cd 100644
--- a/sys/isa/atrtc.c
+++ b/sys/isa/atrtc.c
@@ -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 */
diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c
index 04e3c69..e00c2f4 100644
--- a/sys/kern/subr_smp.c
+++ b/sys/kern/subr_smp.c
@@ -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 */
}
diff --git a/sys/pci/pci.c b/sys/pci/pci.c
index 2dac6de..fceb220 100644
--- a/sys/pci/pci.c
+++ b/sys/pci/pci.c
@@ -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);
diff --git a/sys/pci/pci_compat.c b/sys/pci/pci_compat.c
index 51e450e..4dfe6fd 100644
--- a/sys/pci/pci_compat.c
+++ b/sys/pci/pci_compat.c
@@ -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
}
diff --git a/sys/sys/smp.h b/sys/sys/smp.h
index f258630..0f4f915 100644
--- a/sys/sys/smp.h
+++ b/sys/sys/smp.h
@@ -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*));
OpenPOWER on IntegriCloud