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:
parent
4164c44770
commit
82916a1126
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user