ISA device drivers use the ISA source interrupt number in locations where

the low level interrupt handler number should be used.  Change
setup_apic_irq_mapping() to allocate low level interrupt handler X (Xintr${X})
for any ISA interrupt X mentioned in the MP table.

Remove an assumption in the driver for the system clock (clock.c) that
interrupts mentioned in the MP table as delivered to IOAPIC #0 intpin Y
is handled by low level interrupt handler Y (Xintr${Y}) but don't assume
that low level interrupt handler 0 (Xintr0) is used.

Don't allocate two low level interrupt handlers for the system clock.
Reviewed by:	NOKUBI Hirotaka <hnokubi@yyy.or.jp>
This commit is contained in:
Tor Egge 2000-01-04 22:24:59 +00:00
parent 4164c44770
commit 82916a1126
15 changed files with 610 additions and 108 deletions

View File

@ -335,6 +335,7 @@ static void init_locks(void);
static int start_all_aps(u_int boot_addr);
static void install_ap_tramp(u_int boot_addr);
static int start_ap(int logicalCpu, u_int boot_addr);
static int apic_int_is_bus_type(int intr, int bus_type);
/*
* Calculate usable address in base memory for AP trampoline code.
@ -960,7 +961,7 @@ mptable_pass2(void)
}
static void
void
assign_apic_irq(int apic, int intpin, int irq)
{
int x;
@ -983,6 +984,34 @@ assign_apic_irq(int apic, int intpin, int irq)
}
}
void
revoke_apic_irq(int irq)
{
int x;
int oldapic;
int oldintpin;
if (int_to_apicintpin[irq].ioapic == -1)
panic("assign_apic_irq: inconsistent table");
oldapic = int_to_apicintpin[irq].ioapic;
oldintpin = int_to_apicintpin[irq].int_pin;
int_to_apicintpin[irq].ioapic = -1;
int_to_apicintpin[irq].int_pin = 0;
int_to_apicintpin[irq].apic_address = NULL;
int_to_apicintpin[irq].redirindex = 0;
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(oldapic) &&
io_apic_ints[x].dst_apic_int == oldintpin)
io_apic_ints[x].int_vector = 0xff;
}
}
/*
* parse an Intel MP specification table
*/
@ -1049,37 +1078,66 @@ fix_mp_table(void)
}
/* Assign low level interrupt handlers */
static void
setup_apic_irq_mapping(void)
{
int x;
int int_vector;
/* Assign low level interrupt handlers */
/* Clear array */
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;
}
/* First assign ISA/EISA interrupts */
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) &&
int_vector = io_apic_ints[x].src_bus_irq;
if (int_vector < APIC_INTMAPSIZE &&
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,
int_to_apicintpin[int_vector].ioapic == -1 &&
(apic_int_is_bus_type(x, ISA) ||
apic_int_is_bus_type(x, EISA)) &&
io_apic_ints[x].int_type == 0) {
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
io_apic_ints[x].dst_apic_int,
io_apic_ints[x].dst_apic_int);
int_vector);
}
}
/* Assign interrupts on first 24 intpins on IOAPIC #0 */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[x].int_vector == 0xff &&
int_to_apicintpin[int_vector].ioapic == -1 &&
(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,
int_vector);
}
}
/*
* Assign interrupts for remaining intpins.
* Skip IOAPIC #0 intpin 0 if the type is ExtInt, since this indicates
* that an entry for ISA/EISA irq 0 exist, and a fallback to mixed mode
* due to 8254 interrupts not being delivered can reuse that low level
* interrupt handler.
*/
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_type == 3 &&
(io_apic_ints[x].dst_apic_id != IO_TO_ID(0) ||
io_apic_ints[x].dst_apic_int != 0))) &&
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,

View File

@ -335,6 +335,7 @@ static void init_locks(void);
static int start_all_aps(u_int boot_addr);
static void install_ap_tramp(u_int boot_addr);
static int start_ap(int logicalCpu, u_int boot_addr);
static int apic_int_is_bus_type(int intr, int bus_type);
/*
* Calculate usable address in base memory for AP trampoline code.
@ -960,7 +961,7 @@ mptable_pass2(void)
}
static void
void
assign_apic_irq(int apic, int intpin, int irq)
{
int x;
@ -983,6 +984,34 @@ assign_apic_irq(int apic, int intpin, int irq)
}
}
void
revoke_apic_irq(int irq)
{
int x;
int oldapic;
int oldintpin;
if (int_to_apicintpin[irq].ioapic == -1)
panic("assign_apic_irq: inconsistent table");
oldapic = int_to_apicintpin[irq].ioapic;
oldintpin = int_to_apicintpin[irq].int_pin;
int_to_apicintpin[irq].ioapic = -1;
int_to_apicintpin[irq].int_pin = 0;
int_to_apicintpin[irq].apic_address = NULL;
int_to_apicintpin[irq].redirindex = 0;
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(oldapic) &&
io_apic_ints[x].dst_apic_int == oldintpin)
io_apic_ints[x].int_vector = 0xff;
}
}
/*
* parse an Intel MP specification table
*/
@ -1049,37 +1078,66 @@ fix_mp_table(void)
}
/* Assign low level interrupt handlers */
static void
setup_apic_irq_mapping(void)
{
int x;
int int_vector;
/* Assign low level interrupt handlers */
/* Clear array */
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;
}
/* First assign ISA/EISA interrupts */
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) &&
int_vector = io_apic_ints[x].src_bus_irq;
if (int_vector < APIC_INTMAPSIZE &&
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,
int_to_apicintpin[int_vector].ioapic == -1 &&
(apic_int_is_bus_type(x, ISA) ||
apic_int_is_bus_type(x, EISA)) &&
io_apic_ints[x].int_type == 0) {
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
io_apic_ints[x].dst_apic_int,
io_apic_ints[x].dst_apic_int);
int_vector);
}
}
/* Assign interrupts on first 24 intpins on IOAPIC #0 */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[x].int_vector == 0xff &&
int_to_apicintpin[int_vector].ioapic == -1 &&
(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,
int_vector);
}
}
/*
* Assign interrupts for remaining intpins.
* Skip IOAPIC #0 intpin 0 if the type is ExtInt, since this indicates
* that an entry for ISA/EISA irq 0 exist, and a fallback to mixed mode
* due to 8254 interrupts not being delivered can reuse that low level
* interrupt handler.
*/
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_type == 3 &&
(io_apic_ints[x].dst_apic_id != IO_TO_ID(0) ||
io_apic_ints[x].dst_apic_int != 0))) &&
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,

View File

@ -1001,7 +1001,7 @@ cpu_initclocks()
} else {
/* look for ExtInt on pin 0 */
if (apic_int_type(0, 0) == 3) {
apic_8254_intr = 0;
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
} else
panic("APIC_IO: Cannot route 8254 interrupt to CPU");
@ -1062,21 +1062,39 @@ cpu_initclocks()
INTRDIS(1 << apic_8254_intr);
inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to IO APIC int pin %d\n",
apic_8254_intr);
apic_8254_intr = 0;
"8254 is not connected to "
"IOAPIC #%d intpin %d\n",
int_to_apicintpin[apic_8254_intr].ioapic,
int_to_apicintpin[apic_8254_intr].int_pin);
/*
* Revoke current ISA IRQ 0 assignment and
* configure a fallback interrupt routing from
* the 8254 Timer via the 8259 PIC to the
* an ExtInt interrupt line on IOAPIC #0 intpin 0.
* We reuse the low level interrupt handler number.
*/
if (apic_irq(0, 0) < 0) {
revoke_apic_irq(apic_8254_intr);
assign_apic_irq(0, 0, apic_8254_intr);
}
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
inthand_add("clk", apic_8254_intr,(inthand2_t *)clkintr,
inthand_add("clk", apic_8254_intr,
(inthand2_t *)clkintr,
NULL, &clk_imask, INTR_EXCL);
INTREN(1 << apic_8254_intr);
}
}
if (apic_8254_intr)
printf("APIC_IO: routing 8254 via pin %d\n",apic_8254_intr);
if (apic_int_type(0, 0) != 3 ||
int_to_apicintpin[apic_8254_intr].ioapic != 0 ||
int_to_apicintpin[apic_8254_intr].int_pin != 0)
printf("APIC_IO: routing 8254 via IOAPIC #%d intpin %d\n",
int_to_apicintpin[apic_8254_intr].ioapic,
int_to_apicintpin[apic_8254_intr].int_pin);
else
printf("APIC_IO: routing 8254 via 8259 on pin 0\n");
printf("APIC_IO: "
"routing 8254 via 8259 and IOAPIC #0 intpin 0\n");
#endif
}

View File

@ -335,6 +335,7 @@ static void init_locks(void);
static int start_all_aps(u_int boot_addr);
static void install_ap_tramp(u_int boot_addr);
static int start_ap(int logicalCpu, u_int boot_addr);
static int apic_int_is_bus_type(int intr, int bus_type);
/*
* Calculate usable address in base memory for AP trampoline code.
@ -960,7 +961,7 @@ mptable_pass2(void)
}
static void
void
assign_apic_irq(int apic, int intpin, int irq)
{
int x;
@ -983,6 +984,34 @@ assign_apic_irq(int apic, int intpin, int irq)
}
}
void
revoke_apic_irq(int irq)
{
int x;
int oldapic;
int oldintpin;
if (int_to_apicintpin[irq].ioapic == -1)
panic("assign_apic_irq: inconsistent table");
oldapic = int_to_apicintpin[irq].ioapic;
oldintpin = int_to_apicintpin[irq].int_pin;
int_to_apicintpin[irq].ioapic = -1;
int_to_apicintpin[irq].int_pin = 0;
int_to_apicintpin[irq].apic_address = NULL;
int_to_apicintpin[irq].redirindex = 0;
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(oldapic) &&
io_apic_ints[x].dst_apic_int == oldintpin)
io_apic_ints[x].int_vector = 0xff;
}
}
/*
* parse an Intel MP specification table
*/
@ -1049,37 +1078,66 @@ fix_mp_table(void)
}
/* Assign low level interrupt handlers */
static void
setup_apic_irq_mapping(void)
{
int x;
int int_vector;
/* Assign low level interrupt handlers */
/* Clear array */
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;
}
/* First assign ISA/EISA interrupts */
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) &&
int_vector = io_apic_ints[x].src_bus_irq;
if (int_vector < APIC_INTMAPSIZE &&
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,
int_to_apicintpin[int_vector].ioapic == -1 &&
(apic_int_is_bus_type(x, ISA) ||
apic_int_is_bus_type(x, EISA)) &&
io_apic_ints[x].int_type == 0) {
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
io_apic_ints[x].dst_apic_int,
io_apic_ints[x].dst_apic_int);
int_vector);
}
}
/* Assign interrupts on first 24 intpins on IOAPIC #0 */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[x].int_vector == 0xff &&
int_to_apicintpin[int_vector].ioapic == -1 &&
(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,
int_vector);
}
}
/*
* Assign interrupts for remaining intpins.
* Skip IOAPIC #0 intpin 0 if the type is ExtInt, since this indicates
* that an entry for ISA/EISA irq 0 exist, and a fallback to mixed mode
* due to 8254 interrupts not being delivered can reuse that low level
* interrupt handler.
*/
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_type == 3 &&
(io_apic_ints[x].dst_apic_id != IO_TO_ID(0) ||
io_apic_ints[x].dst_apic_int != 0))) &&
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,

View File

@ -132,6 +132,8 @@ int apic_src_bus_irq __P((int, int));
int apic_int_type __P((int, int));
int apic_trigger __P((int, int));
int apic_polarity __P((int, int));
void assign_apic_irq __P((int apic, int intpin, int irq));
void revoke_apic_irq __P((int irq));
void bsp_apic_configure __P((void));
void init_secondary __P((void));
void smp_invltlb __P((void));

View File

@ -1001,7 +1001,7 @@ cpu_initclocks()
} else {
/* look for ExtInt on pin 0 */
if (apic_int_type(0, 0) == 3) {
apic_8254_intr = 0;
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
} else
panic("APIC_IO: Cannot route 8254 interrupt to CPU");
@ -1062,21 +1062,39 @@ cpu_initclocks()
INTRDIS(1 << apic_8254_intr);
inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to IO APIC int pin %d\n",
apic_8254_intr);
apic_8254_intr = 0;
"8254 is not connected to "
"IOAPIC #%d intpin %d\n",
int_to_apicintpin[apic_8254_intr].ioapic,
int_to_apicintpin[apic_8254_intr].int_pin);
/*
* Revoke current ISA IRQ 0 assignment and
* configure a fallback interrupt routing from
* the 8254 Timer via the 8259 PIC to the
* an ExtInt interrupt line on IOAPIC #0 intpin 0.
* We reuse the low level interrupt handler number.
*/
if (apic_irq(0, 0) < 0) {
revoke_apic_irq(apic_8254_intr);
assign_apic_irq(0, 0, apic_8254_intr);
}
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
inthand_add("clk", apic_8254_intr,(inthand2_t *)clkintr,
inthand_add("clk", apic_8254_intr,
(inthand2_t *)clkintr,
NULL, &clk_imask, INTR_EXCL);
INTREN(1 << apic_8254_intr);
}
}
if (apic_8254_intr)
printf("APIC_IO: routing 8254 via pin %d\n",apic_8254_intr);
if (apic_int_type(0, 0) != 3 ||
int_to_apicintpin[apic_8254_intr].ioapic != 0 ||
int_to_apicintpin[apic_8254_intr].int_pin != 0)
printf("APIC_IO: routing 8254 via IOAPIC #%d intpin %d\n",
int_to_apicintpin[apic_8254_intr].ioapic,
int_to_apicintpin[apic_8254_intr].int_pin);
else
printf("APIC_IO: routing 8254 via 8259 on pin 0\n");
printf("APIC_IO: "
"routing 8254 via 8259 and IOAPIC #0 intpin 0\n");
#endif
}

View File

@ -335,6 +335,7 @@ static void init_locks(void);
static int start_all_aps(u_int boot_addr);
static void install_ap_tramp(u_int boot_addr);
static int start_ap(int logicalCpu, u_int boot_addr);
static int apic_int_is_bus_type(int intr, int bus_type);
/*
* Calculate usable address in base memory for AP trampoline code.
@ -960,7 +961,7 @@ mptable_pass2(void)
}
static void
void
assign_apic_irq(int apic, int intpin, int irq)
{
int x;
@ -983,6 +984,34 @@ assign_apic_irq(int apic, int intpin, int irq)
}
}
void
revoke_apic_irq(int irq)
{
int x;
int oldapic;
int oldintpin;
if (int_to_apicintpin[irq].ioapic == -1)
panic("assign_apic_irq: inconsistent table");
oldapic = int_to_apicintpin[irq].ioapic;
oldintpin = int_to_apicintpin[irq].int_pin;
int_to_apicintpin[irq].ioapic = -1;
int_to_apicintpin[irq].int_pin = 0;
int_to_apicintpin[irq].apic_address = NULL;
int_to_apicintpin[irq].redirindex = 0;
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(oldapic) &&
io_apic_ints[x].dst_apic_int == oldintpin)
io_apic_ints[x].int_vector = 0xff;
}
}
/*
* parse an Intel MP specification table
*/
@ -1049,37 +1078,66 @@ fix_mp_table(void)
}
/* Assign low level interrupt handlers */
static void
setup_apic_irq_mapping(void)
{
int x;
int int_vector;
/* Assign low level interrupt handlers */
/* Clear array */
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;
}
/* First assign ISA/EISA interrupts */
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) &&
int_vector = io_apic_ints[x].src_bus_irq;
if (int_vector < APIC_INTMAPSIZE &&
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,
int_to_apicintpin[int_vector].ioapic == -1 &&
(apic_int_is_bus_type(x, ISA) ||
apic_int_is_bus_type(x, EISA)) &&
io_apic_ints[x].int_type == 0) {
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
io_apic_ints[x].dst_apic_int,
io_apic_ints[x].dst_apic_int);
int_vector);
}
}
/* Assign interrupts on first 24 intpins on IOAPIC #0 */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[x].int_vector == 0xff &&
int_to_apicintpin[int_vector].ioapic == -1 &&
(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,
int_vector);
}
}
/*
* Assign interrupts for remaining intpins.
* Skip IOAPIC #0 intpin 0 if the type is ExtInt, since this indicates
* that an entry for ISA/EISA irq 0 exist, and a fallback to mixed mode
* due to 8254 interrupts not being delivered can reuse that low level
* interrupt handler.
*/
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_type == 3 &&
(io_apic_ints[x].dst_apic_id != IO_TO_ID(0) ||
io_apic_ints[x].dst_apic_int != 0))) &&
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,

View File

@ -335,6 +335,7 @@ static void init_locks(void);
static int start_all_aps(u_int boot_addr);
static void install_ap_tramp(u_int boot_addr);
static int start_ap(int logicalCpu, u_int boot_addr);
static int apic_int_is_bus_type(int intr, int bus_type);
/*
* Calculate usable address in base memory for AP trampoline code.
@ -960,7 +961,7 @@ mptable_pass2(void)
}
static void
void
assign_apic_irq(int apic, int intpin, int irq)
{
int x;
@ -983,6 +984,34 @@ assign_apic_irq(int apic, int intpin, int irq)
}
}
void
revoke_apic_irq(int irq)
{
int x;
int oldapic;
int oldintpin;
if (int_to_apicintpin[irq].ioapic == -1)
panic("assign_apic_irq: inconsistent table");
oldapic = int_to_apicintpin[irq].ioapic;
oldintpin = int_to_apicintpin[irq].int_pin;
int_to_apicintpin[irq].ioapic = -1;
int_to_apicintpin[irq].int_pin = 0;
int_to_apicintpin[irq].apic_address = NULL;
int_to_apicintpin[irq].redirindex = 0;
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(oldapic) &&
io_apic_ints[x].dst_apic_int == oldintpin)
io_apic_ints[x].int_vector = 0xff;
}
}
/*
* parse an Intel MP specification table
*/
@ -1049,37 +1078,66 @@ fix_mp_table(void)
}
/* Assign low level interrupt handlers */
static void
setup_apic_irq_mapping(void)
{
int x;
int int_vector;
/* Assign low level interrupt handlers */
/* Clear array */
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;
}
/* First assign ISA/EISA interrupts */
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) &&
int_vector = io_apic_ints[x].src_bus_irq;
if (int_vector < APIC_INTMAPSIZE &&
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,
int_to_apicintpin[int_vector].ioapic == -1 &&
(apic_int_is_bus_type(x, ISA) ||
apic_int_is_bus_type(x, EISA)) &&
io_apic_ints[x].int_type == 0) {
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
io_apic_ints[x].dst_apic_int,
io_apic_ints[x].dst_apic_int);
int_vector);
}
}
/* Assign interrupts on first 24 intpins on IOAPIC #0 */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[x].int_vector == 0xff &&
int_to_apicintpin[int_vector].ioapic == -1 &&
(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,
int_vector);
}
}
/*
* Assign interrupts for remaining intpins.
* Skip IOAPIC #0 intpin 0 if the type is ExtInt, since this indicates
* that an entry for ISA/EISA irq 0 exist, and a fallback to mixed mode
* due to 8254 interrupts not being delivered can reuse that low level
* interrupt handler.
*/
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_type == 3 &&
(io_apic_ints[x].dst_apic_id != IO_TO_ID(0) ||
io_apic_ints[x].dst_apic_int != 0))) &&
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,

View File

@ -1001,7 +1001,7 @@ cpu_initclocks()
} else {
/* look for ExtInt on pin 0 */
if (apic_int_type(0, 0) == 3) {
apic_8254_intr = 0;
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
} else
panic("APIC_IO: Cannot route 8254 interrupt to CPU");
@ -1062,21 +1062,39 @@ cpu_initclocks()
INTRDIS(1 << apic_8254_intr);
inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to IO APIC int pin %d\n",
apic_8254_intr);
apic_8254_intr = 0;
"8254 is not connected to "
"IOAPIC #%d intpin %d\n",
int_to_apicintpin[apic_8254_intr].ioapic,
int_to_apicintpin[apic_8254_intr].int_pin);
/*
* Revoke current ISA IRQ 0 assignment and
* configure a fallback interrupt routing from
* the 8254 Timer via the 8259 PIC to the
* an ExtInt interrupt line on IOAPIC #0 intpin 0.
* We reuse the low level interrupt handler number.
*/
if (apic_irq(0, 0) < 0) {
revoke_apic_irq(apic_8254_intr);
assign_apic_irq(0, 0, apic_8254_intr);
}
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
inthand_add("clk", apic_8254_intr,(inthand2_t *)clkintr,
inthand_add("clk", apic_8254_intr,
(inthand2_t *)clkintr,
NULL, &clk_imask, INTR_EXCL);
INTREN(1 << apic_8254_intr);
}
}
if (apic_8254_intr)
printf("APIC_IO: routing 8254 via pin %d\n",apic_8254_intr);
if (apic_int_type(0, 0) != 3 ||
int_to_apicintpin[apic_8254_intr].ioapic != 0 ||
int_to_apicintpin[apic_8254_intr].int_pin != 0)
printf("APIC_IO: routing 8254 via IOAPIC #%d intpin %d\n",
int_to_apicintpin[apic_8254_intr].ioapic,
int_to_apicintpin[apic_8254_intr].int_pin);
else
printf("APIC_IO: routing 8254 via 8259 on pin 0\n");
printf("APIC_IO: "
"routing 8254 via 8259 and IOAPIC #0 intpin 0\n");
#endif
}

View File

@ -335,6 +335,7 @@ static void init_locks(void);
static int start_all_aps(u_int boot_addr);
static void install_ap_tramp(u_int boot_addr);
static int start_ap(int logicalCpu, u_int boot_addr);
static int apic_int_is_bus_type(int intr, int bus_type);
/*
* Calculate usable address in base memory for AP trampoline code.
@ -960,7 +961,7 @@ mptable_pass2(void)
}
static void
void
assign_apic_irq(int apic, int intpin, int irq)
{
int x;
@ -983,6 +984,34 @@ assign_apic_irq(int apic, int intpin, int irq)
}
}
void
revoke_apic_irq(int irq)
{
int x;
int oldapic;
int oldintpin;
if (int_to_apicintpin[irq].ioapic == -1)
panic("assign_apic_irq: inconsistent table");
oldapic = int_to_apicintpin[irq].ioapic;
oldintpin = int_to_apicintpin[irq].int_pin;
int_to_apicintpin[irq].ioapic = -1;
int_to_apicintpin[irq].int_pin = 0;
int_to_apicintpin[irq].apic_address = NULL;
int_to_apicintpin[irq].redirindex = 0;
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(oldapic) &&
io_apic_ints[x].dst_apic_int == oldintpin)
io_apic_ints[x].int_vector = 0xff;
}
}
/*
* parse an Intel MP specification table
*/
@ -1049,37 +1078,66 @@ fix_mp_table(void)
}
/* Assign low level interrupt handlers */
static void
setup_apic_irq_mapping(void)
{
int x;
int int_vector;
/* Assign low level interrupt handlers */
/* Clear array */
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;
}
/* First assign ISA/EISA interrupts */
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) &&
int_vector = io_apic_ints[x].src_bus_irq;
if (int_vector < APIC_INTMAPSIZE &&
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,
int_to_apicintpin[int_vector].ioapic == -1 &&
(apic_int_is_bus_type(x, ISA) ||
apic_int_is_bus_type(x, EISA)) &&
io_apic_ints[x].int_type == 0) {
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
io_apic_ints[x].dst_apic_int,
io_apic_ints[x].dst_apic_int);
int_vector);
}
}
/* Assign interrupts on first 24 intpins on IOAPIC #0 */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[x].int_vector == 0xff &&
int_to_apicintpin[int_vector].ioapic == -1 &&
(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,
int_vector);
}
}
/*
* Assign interrupts for remaining intpins.
* Skip IOAPIC #0 intpin 0 if the type is ExtInt, since this indicates
* that an entry for ISA/EISA irq 0 exist, and a fallback to mixed mode
* due to 8254 interrupts not being delivered can reuse that low level
* interrupt handler.
*/
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_type == 3 &&
(io_apic_ints[x].dst_apic_id != IO_TO_ID(0) ||
io_apic_ints[x].dst_apic_int != 0))) &&
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,

View File

@ -132,6 +132,8 @@ int apic_src_bus_irq __P((int, int));
int apic_int_type __P((int, int));
int apic_trigger __P((int, int));
int apic_polarity __P((int, int));
void assign_apic_irq __P((int apic, int intpin, int irq));
void revoke_apic_irq __P((int irq));
void bsp_apic_configure __P((void));
void init_secondary __P((void));
void smp_invltlb __P((void));

View File

@ -1001,7 +1001,7 @@ cpu_initclocks()
} else {
/* look for ExtInt on pin 0 */
if (apic_int_type(0, 0) == 3) {
apic_8254_intr = 0;
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
} else
panic("APIC_IO: Cannot route 8254 interrupt to CPU");
@ -1062,21 +1062,39 @@ cpu_initclocks()
INTRDIS(1 << apic_8254_intr);
inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to IO APIC int pin %d\n",
apic_8254_intr);
apic_8254_intr = 0;
"8254 is not connected to "
"IOAPIC #%d intpin %d\n",
int_to_apicintpin[apic_8254_intr].ioapic,
int_to_apicintpin[apic_8254_intr].int_pin);
/*
* Revoke current ISA IRQ 0 assignment and
* configure a fallback interrupt routing from
* the 8254 Timer via the 8259 PIC to the
* an ExtInt interrupt line on IOAPIC #0 intpin 0.
* We reuse the low level interrupt handler number.
*/
if (apic_irq(0, 0) < 0) {
revoke_apic_irq(apic_8254_intr);
assign_apic_irq(0, 0, apic_8254_intr);
}
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
inthand_add("clk", apic_8254_intr,(inthand2_t *)clkintr,
inthand_add("clk", apic_8254_intr,
(inthand2_t *)clkintr,
NULL, &clk_imask, INTR_EXCL);
INTREN(1 << apic_8254_intr);
}
}
if (apic_8254_intr)
printf("APIC_IO: routing 8254 via pin %d\n",apic_8254_intr);
if (apic_int_type(0, 0) != 3 ||
int_to_apicintpin[apic_8254_intr].ioapic != 0 ||
int_to_apicintpin[apic_8254_intr].int_pin != 0)
printf("APIC_IO: routing 8254 via IOAPIC #%d intpin %d\n",
int_to_apicintpin[apic_8254_intr].ioapic,
int_to_apicintpin[apic_8254_intr].int_pin);
else
printf("APIC_IO: routing 8254 via 8259 on pin 0\n");
printf("APIC_IO: "
"routing 8254 via 8259 and IOAPIC #0 intpin 0\n");
#endif
}

View File

@ -1001,7 +1001,7 @@ cpu_initclocks()
} else {
/* look for ExtInt on pin 0 */
if (apic_int_type(0, 0) == 3) {
apic_8254_intr = 0;
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
} else
panic("APIC_IO: Cannot route 8254 interrupt to CPU");
@ -1062,21 +1062,39 @@ cpu_initclocks()
INTRDIS(1 << apic_8254_intr);
inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to IO APIC int pin %d\n",
apic_8254_intr);
apic_8254_intr = 0;
"8254 is not connected to "
"IOAPIC #%d intpin %d\n",
int_to_apicintpin[apic_8254_intr].ioapic,
int_to_apicintpin[apic_8254_intr].int_pin);
/*
* Revoke current ISA IRQ 0 assignment and
* configure a fallback interrupt routing from
* the 8254 Timer via the 8259 PIC to the
* an ExtInt interrupt line on IOAPIC #0 intpin 0.
* We reuse the low level interrupt handler number.
*/
if (apic_irq(0, 0) < 0) {
revoke_apic_irq(apic_8254_intr);
assign_apic_irq(0, 0, apic_8254_intr);
}
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
inthand_add("clk", apic_8254_intr,(inthand2_t *)clkintr,
inthand_add("clk", apic_8254_intr,
(inthand2_t *)clkintr,
NULL, &clk_imask, INTR_EXCL);
INTREN(1 << apic_8254_intr);
}
}
if (apic_8254_intr)
printf("APIC_IO: routing 8254 via pin %d\n",apic_8254_intr);
if (apic_int_type(0, 0) != 3 ||
int_to_apicintpin[apic_8254_intr].ioapic != 0 ||
int_to_apicintpin[apic_8254_intr].int_pin != 0)
printf("APIC_IO: routing 8254 via IOAPIC #%d intpin %d\n",
int_to_apicintpin[apic_8254_intr].ioapic,
int_to_apicintpin[apic_8254_intr].int_pin);
else
printf("APIC_IO: routing 8254 via 8259 on pin 0\n");
printf("APIC_IO: "
"routing 8254 via 8259 and IOAPIC #0 intpin 0\n");
#endif
}

View File

@ -335,6 +335,7 @@ static void init_locks(void);
static int start_all_aps(u_int boot_addr);
static void install_ap_tramp(u_int boot_addr);
static int start_ap(int logicalCpu, u_int boot_addr);
static int apic_int_is_bus_type(int intr, int bus_type);
/*
* Calculate usable address in base memory for AP trampoline code.
@ -960,7 +961,7 @@ mptable_pass2(void)
}
static void
void
assign_apic_irq(int apic, int intpin, int irq)
{
int x;
@ -983,6 +984,34 @@ assign_apic_irq(int apic, int intpin, int irq)
}
}
void
revoke_apic_irq(int irq)
{
int x;
int oldapic;
int oldintpin;
if (int_to_apicintpin[irq].ioapic == -1)
panic("assign_apic_irq: inconsistent table");
oldapic = int_to_apicintpin[irq].ioapic;
oldintpin = int_to_apicintpin[irq].int_pin;
int_to_apicintpin[irq].ioapic = -1;
int_to_apicintpin[irq].int_pin = 0;
int_to_apicintpin[irq].apic_address = NULL;
int_to_apicintpin[irq].redirindex = 0;
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(oldapic) &&
io_apic_ints[x].dst_apic_int == oldintpin)
io_apic_ints[x].int_vector = 0xff;
}
}
/*
* parse an Intel MP specification table
*/
@ -1049,37 +1078,66 @@ fix_mp_table(void)
}
/* Assign low level interrupt handlers */
static void
setup_apic_irq_mapping(void)
{
int x;
int int_vector;
/* Assign low level interrupt handlers */
/* Clear array */
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;
}
/* First assign ISA/EISA interrupts */
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) &&
int_vector = io_apic_ints[x].src_bus_irq;
if (int_vector < APIC_INTMAPSIZE &&
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,
int_to_apicintpin[int_vector].ioapic == -1 &&
(apic_int_is_bus_type(x, ISA) ||
apic_int_is_bus_type(x, EISA)) &&
io_apic_ints[x].int_type == 0) {
assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id),
io_apic_ints[x].dst_apic_int,
io_apic_ints[x].dst_apic_int);
int_vector);
}
}
/* Assign interrupts on first 24 intpins on IOAPIC #0 */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
io_apic_ints[x].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[x].int_vector == 0xff &&
int_to_apicintpin[int_vector].ioapic == -1 &&
(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,
int_vector);
}
}
/*
* Assign interrupts for remaining intpins.
* Skip IOAPIC #0 intpin 0 if the type is ExtInt, since this indicates
* that an entry for ISA/EISA irq 0 exist, and a fallback to mixed mode
* due to 8254 interrupts not being delivered can reuse that low level
* interrupt handler.
*/
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_type == 3 &&
(io_apic_ints[x].dst_apic_id != IO_TO_ID(0) ||
io_apic_ints[x].dst_apic_int != 0))) &&
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,

View File

@ -132,6 +132,8 @@ int apic_src_bus_irq __P((int, int));
int apic_int_type __P((int, int));
int apic_trigger __P((int, int));
int apic_polarity __P((int, int));
void assign_apic_irq __P((int apic, int intpin, int irq));
void revoke_apic_irq __P((int irq));
void bsp_apic_configure __P((void));
void init_secondary __P((void));
void smp_invltlb __P((void));