1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-11 09:50:12 +00:00

Defer assignment of low level interrupt handlers for PCI interrupts

described in the MP table until something asks for the interrupt number
later on.
This commit is contained in:
Tor Egge 2001-01-28 01:07:54 +00:00
parent 99557a7988
commit 48bed92485
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=71727
11 changed files with 424 additions and 330 deletions

View File

@ -1068,6 +1068,37 @@ revoke_apic_irq(int irq)
}
static void
allocate_apic_irq(int intr)
{
int apic;
int intpin;
int irq;
if (io_apic_ints[intr].int_vector != 0xff)
return; /* Interrupt handler already assigned */
if (io_apic_ints[intr].int_type != 0 &&
(io_apic_ints[intr].int_type != 3 ||
(io_apic_ints[intr].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[intr].dst_apic_int == 0)))
return; /* Not INT or ExtInt on != (0, 0) */
irq = 0;
while (irq < APIC_INTMAPSIZE &&
int_to_apicintpin[irq].ioapic != -1)
irq++;
if (irq >= APIC_INTMAPSIZE)
return; /* No free interrupt handlers */
apic = ID_TO_IO(io_apic_ints[intr].dst_apic_id);
intpin = io_apic_ints[intr].dst_apic_int;
assign_apic_irq(apic, intpin, irq);
io_apic_setup_intpin(apic, intpin);
}
static void
swap_apic_id(int apic, int oldid, int newid)
@ -1310,46 +1341,18 @@ setup_apic_irq_mapping(void)
}
}
/* Assign first set of interrupts to intpins on IOAPIC #0 */
/* Assign ExtInt entry if no ISA/EISA interrupt 0 entry */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
if (io_apic_ints[x].dst_apic_int == 0 &&
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].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,
int_vector);
int_vector++;
while (int_vector < APIC_INTMAPSIZE &&
int_to_apicintpin[int_vector].ioapic != -1)
int_vector++;
int_to_apicintpin[0].ioapic == -1 &&
io_apic_ints[x].int_type == 3) {
assign_apic_irq(0, 0, 0);
break;
}
}
/* PCI interrupt assignment is deferred */
}
@ -1522,8 +1525,11 @@ isa_apic_irq(int isa_irq)
if (INTTYPE(intr) == 0) { /* standard INT */
if (SRCBUSIRQ(intr) == isa_irq) {
if (apic_int_is_bus_type(intr, ISA) ||
apic_int_is_bus_type(intr, EISA))
apic_int_is_bus_type(intr, EISA)) {
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* found */
}
}
}
}
@ -1549,8 +1555,13 @@ pci_apic_irq(int pciBus, int pciDevice, int pciInt)
&& (SRCBUSID(intr) == pciBus)
&& (SRCBUSDEVICE(intr) == pciDevice)
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
if (apic_int_is_bus_type(intr, PCI))
if (apic_int_is_bus_type(intr, PCI)) {
if (INTIRQ(intr) == 0xff)
allocate_apic_irq(intr);
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* exact match */
}
return -1; /* NOT found */
}

View File

@ -1068,6 +1068,37 @@ revoke_apic_irq(int irq)
}
static void
allocate_apic_irq(int intr)
{
int apic;
int intpin;
int irq;
if (io_apic_ints[intr].int_vector != 0xff)
return; /* Interrupt handler already assigned */
if (io_apic_ints[intr].int_type != 0 &&
(io_apic_ints[intr].int_type != 3 ||
(io_apic_ints[intr].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[intr].dst_apic_int == 0)))
return; /* Not INT or ExtInt on != (0, 0) */
irq = 0;
while (irq < APIC_INTMAPSIZE &&
int_to_apicintpin[irq].ioapic != -1)
irq++;
if (irq >= APIC_INTMAPSIZE)
return; /* No free interrupt handlers */
apic = ID_TO_IO(io_apic_ints[intr].dst_apic_id);
intpin = io_apic_ints[intr].dst_apic_int;
assign_apic_irq(apic, intpin, irq);
io_apic_setup_intpin(apic, intpin);
}
static void
swap_apic_id(int apic, int oldid, int newid)
@ -1310,46 +1341,18 @@ setup_apic_irq_mapping(void)
}
}
/* Assign first set of interrupts to intpins on IOAPIC #0 */
/* Assign ExtInt entry if no ISA/EISA interrupt 0 entry */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
if (io_apic_ints[x].dst_apic_int == 0 &&
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].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,
int_vector);
int_vector++;
while (int_vector < APIC_INTMAPSIZE &&
int_to_apicintpin[int_vector].ioapic != -1)
int_vector++;
int_to_apicintpin[0].ioapic == -1 &&
io_apic_ints[x].int_type == 3) {
assign_apic_irq(0, 0, 0);
break;
}
}
/* PCI interrupt assignment is deferred */
}
@ -1522,8 +1525,11 @@ isa_apic_irq(int isa_irq)
if (INTTYPE(intr) == 0) { /* standard INT */
if (SRCBUSIRQ(intr) == isa_irq) {
if (apic_int_is_bus_type(intr, ISA) ||
apic_int_is_bus_type(intr, EISA))
apic_int_is_bus_type(intr, EISA)) {
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* found */
}
}
}
}
@ -1549,8 +1555,13 @@ pci_apic_irq(int pciBus, int pciDevice, int pciInt)
&& (SRCBUSID(intr) == pciBus)
&& (SRCBUSDEVICE(intr) == pciDevice)
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
if (apic_int_is_bus_type(intr, PCI))
if (apic_int_is_bus_type(intr, PCI)) {
if (INTIRQ(intr) == 0xff)
allocate_apic_irq(intr);
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* exact match */
}
return -1; /* NOT found */
}

View File

@ -1068,6 +1068,37 @@ revoke_apic_irq(int irq)
}
static void
allocate_apic_irq(int intr)
{
int apic;
int intpin;
int irq;
if (io_apic_ints[intr].int_vector != 0xff)
return; /* Interrupt handler already assigned */
if (io_apic_ints[intr].int_type != 0 &&
(io_apic_ints[intr].int_type != 3 ||
(io_apic_ints[intr].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[intr].dst_apic_int == 0)))
return; /* Not INT or ExtInt on != (0, 0) */
irq = 0;
while (irq < APIC_INTMAPSIZE &&
int_to_apicintpin[irq].ioapic != -1)
irq++;
if (irq >= APIC_INTMAPSIZE)
return; /* No free interrupt handlers */
apic = ID_TO_IO(io_apic_ints[intr].dst_apic_id);
intpin = io_apic_ints[intr].dst_apic_int;
assign_apic_irq(apic, intpin, irq);
io_apic_setup_intpin(apic, intpin);
}
static void
swap_apic_id(int apic, int oldid, int newid)
@ -1310,46 +1341,18 @@ setup_apic_irq_mapping(void)
}
}
/* Assign first set of interrupts to intpins on IOAPIC #0 */
/* Assign ExtInt entry if no ISA/EISA interrupt 0 entry */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
if (io_apic_ints[x].dst_apic_int == 0 &&
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].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,
int_vector);
int_vector++;
while (int_vector < APIC_INTMAPSIZE &&
int_to_apicintpin[int_vector].ioapic != -1)
int_vector++;
int_to_apicintpin[0].ioapic == -1 &&
io_apic_ints[x].int_type == 3) {
assign_apic_irq(0, 0, 0);
break;
}
}
/* PCI interrupt assignment is deferred */
}
@ -1522,8 +1525,11 @@ isa_apic_irq(int isa_irq)
if (INTTYPE(intr) == 0) { /* standard INT */
if (SRCBUSIRQ(intr) == isa_irq) {
if (apic_int_is_bus_type(intr, ISA) ||
apic_int_is_bus_type(intr, EISA))
apic_int_is_bus_type(intr, EISA)) {
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* found */
}
}
}
}
@ -1549,8 +1555,13 @@ pci_apic_irq(int pciBus, int pciDevice, int pciInt)
&& (SRCBUSID(intr) == pciBus)
&& (SRCBUSDEVICE(intr) == pciDevice)
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
if (apic_int_is_bus_type(intr, PCI))
if (apic_int_is_bus_type(intr, PCI)) {
if (INTIRQ(intr) == 0xff)
allocate_apic_irq(intr);
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* exact match */
}
return -1; /* NOT found */
}

View File

@ -135,6 +135,7 @@ void imen_dump __P((void));
int apic_ipi __P((int, int, int));
int selected_apic_ipi __P((u_int, int, int));
int io_apic_setup __P((int));
void io_apic_setup_intpin __P((int, int));
void io_apic_set_id __P((int, int));
int io_apic_get_id __P((int));
int ext_int_setup __P((int, int));

View File

@ -1068,6 +1068,37 @@ revoke_apic_irq(int irq)
}
static void
allocate_apic_irq(int intr)
{
int apic;
int intpin;
int irq;
if (io_apic_ints[intr].int_vector != 0xff)
return; /* Interrupt handler already assigned */
if (io_apic_ints[intr].int_type != 0 &&
(io_apic_ints[intr].int_type != 3 ||
(io_apic_ints[intr].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[intr].dst_apic_int == 0)))
return; /* Not INT or ExtInt on != (0, 0) */
irq = 0;
while (irq < APIC_INTMAPSIZE &&
int_to_apicintpin[irq].ioapic != -1)
irq++;
if (irq >= APIC_INTMAPSIZE)
return; /* No free interrupt handlers */
apic = ID_TO_IO(io_apic_ints[intr].dst_apic_id);
intpin = io_apic_ints[intr].dst_apic_int;
assign_apic_irq(apic, intpin, irq);
io_apic_setup_intpin(apic, intpin);
}
static void
swap_apic_id(int apic, int oldid, int newid)
@ -1310,46 +1341,18 @@ setup_apic_irq_mapping(void)
}
}
/* Assign first set of interrupts to intpins on IOAPIC #0 */
/* Assign ExtInt entry if no ISA/EISA interrupt 0 entry */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
if (io_apic_ints[x].dst_apic_int == 0 &&
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].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,
int_vector);
int_vector++;
while (int_vector < APIC_INTMAPSIZE &&
int_to_apicintpin[int_vector].ioapic != -1)
int_vector++;
int_to_apicintpin[0].ioapic == -1 &&
io_apic_ints[x].int_type == 3) {
assign_apic_irq(0, 0, 0);
break;
}
}
/* PCI interrupt assignment is deferred */
}
@ -1522,8 +1525,11 @@ isa_apic_irq(int isa_irq)
if (INTTYPE(intr) == 0) { /* standard INT */
if (SRCBUSIRQ(intr) == isa_irq) {
if (apic_int_is_bus_type(intr, ISA) ||
apic_int_is_bus_type(intr, EISA))
apic_int_is_bus_type(intr, EISA)) {
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* found */
}
}
}
}
@ -1549,8 +1555,13 @@ pci_apic_irq(int pciBus, int pciDevice, int pciInt)
&& (SRCBUSID(intr) == pciBus)
&& (SRCBUSDEVICE(intr) == pciDevice)
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
if (apic_int_is_bus_type(intr, PCI))
if (apic_int_is_bus_type(intr, PCI)) {
if (INTIRQ(intr) == 0xff)
allocate_apic_irq(intr);
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* exact match */
}
return -1; /* NOT found */
}

View File

@ -29,6 +29,7 @@
#include <sys/bus.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <machine/smptests.h> /** TEST_TEST1 */
#include <machine/smp.h>
@ -177,19 +178,98 @@ io_apic_get_id(int apic)
/*
* Setup the IO APIC.
*/
extern int apic_pin_trigger; /* 'opaque' */
int
io_apic_setup(int apic)
void
io_apic_setup_intpin(int apic, int pin)
{
int maxpin;
int bus, bustype, irq;
u_char select; /* the select register is 8 bits */
u_int32_t flags; /* the window register is 32 bits */
u_int32_t target; /* the window register is 32 bits */
u_int32_t vector; /* the window register is 32 bits */
int pin, level;
int level;
target = IOART_DEST;
select = pin * 2 + IOAPIC_REDTBL0; /* register */
/*
* Always disable interrupts, and by default map
* pin X to IRQX because the disable doesn't stick
* and the uninitialize vector will get translated
* into a panic.
*
* This is correct for IRQs 1 and 3-15. In the other cases,
* any robust driver will handle the spurious interrupt, and
* the effective NOP beats a panic.
*
* A dedicated "bogus interrupt" entry in the IDT would
* be a nicer hack, although some one should find out
* why some systems are generating interrupts when they
* shouldn't and stop the carnage.
*/
vector = NRSVIDT + pin; /* IDT vec */
mtx_enter(&imen_mtx, MTX_SPIN);
io_apic_write(apic, select,
(io_apic_read(apic, select) & ~IOART_INTMASK
& ~0xff)|IOART_INTMSET|vector);
mtx_exit(&imen_mtx, MTX_SPIN);
/* we only deal with vectored INTs here */
if (apic_int_type(apic, pin) != 0)
return;
irq = apic_irq(apic, pin);
if (irq < 0)
return;
/* determine the bus type for this pin */
bus = apic_src_bus_id(apic, pin);
if (bus == -1)
return;
bustype = apic_bus_type(bus);
if ((bustype == ISA) &&
(pin < IOAPIC_ISA_INTS) &&
(irq == pin) &&
(apic_polarity(apic, pin) == 0x1) &&
(apic_trigger(apic, pin) == 0x3)) {
/*
* A broken BIOS might describe some ISA
* interrupts as active-high level-triggered.
* Use default ISA flags for those interrupts.
*/
flags = DEFAULT_ISA_FLAGS;
} else {
/*
* Program polarity and trigger mode according to
* interrupt entry.
*/
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 intpin %d -> irq %d\n",
apic, pin, irq);
vector = NRSVIDT + irq; /* IDT vec */
mtx_enter(&imen_mtx, MTX_SPIN);
io_apic_write(apic, select, flags | vector);
io_apic_write(apic, select + 1, target);
mtx_exit(&imen_mtx, MTX_SPIN);
}
int
io_apic_setup(int apic)
{
int maxpin;
int pin;
if (apic == 0)
apic_pin_trigger = 0; /* default to edge-triggered */
@ -197,73 +277,7 @@ io_apic_setup(int apic)
printf("Programming %d pins in IOAPIC #%d\n", maxpin, apic);
for (pin = 0; pin < maxpin; ++pin) {
int bus, bustype, irq;
select = pin * 2 + IOAPIC_REDTBL0; /* register */
/*
* Always disable interrupts, and by default map
* pin X to IRQX because the disable doesn't stick
* and the uninitialize vector will get translated
* into a panic.
*
* This is correct for IRQs 1 and 3-15. In the other cases,
* any robust driver will handle the spurious interrupt, and
* the effective NOP beats a panic.
*
* A dedicated "bogus interrupt" entry in the IDT would
* be a nicer hack, although some one should find out
* why some systems are generating interrupts when they
* shouldn't and stop the carnage.
*/
vector = NRSVIDT + pin; /* IDT vec */
io_apic_write(apic, select,
(io_apic_read(apic, select) & ~IOART_INTMASK
& ~0xff)|IOART_INTMSET|vector);
/* we only deal with vectored INTs here */
if (apic_int_type(apic, pin) != 0)
continue;
irq = apic_irq(apic, pin);
if (irq < 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);
if ((bustype == ISA) &&
(pin < IOAPIC_ISA_INTS) &&
(irq == pin) &&
(apic_polarity(apic, pin) == 0x1) &&
(apic_trigger(apic, pin) == 0x3)) {
/*
* A broken BIOS might describe some ISA
* interrupts as active-high level-triggered.
* Use default ISA flags for those interrupts.
*/
flags = DEFAULT_ISA_FLAGS;
} else {
/*
* Program polarity and trigger mode according to
* interrupt entry.
*/
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 intpin %d -> irq %d\n",
apic, pin, irq);
vector = NRSVIDT + irq; /* IDT vec */
io_apic_write(apic, select, flags | vector);
io_apic_write(apic, select + 1, target);
io_apic_setup_intpin(apic, pin);
}
/* return GOOD status */

View File

@ -1068,6 +1068,37 @@ revoke_apic_irq(int irq)
}
static void
allocate_apic_irq(int intr)
{
int apic;
int intpin;
int irq;
if (io_apic_ints[intr].int_vector != 0xff)
return; /* Interrupt handler already assigned */
if (io_apic_ints[intr].int_type != 0 &&
(io_apic_ints[intr].int_type != 3 ||
(io_apic_ints[intr].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[intr].dst_apic_int == 0)))
return; /* Not INT or ExtInt on != (0, 0) */
irq = 0;
while (irq < APIC_INTMAPSIZE &&
int_to_apicintpin[irq].ioapic != -1)
irq++;
if (irq >= APIC_INTMAPSIZE)
return; /* No free interrupt handlers */
apic = ID_TO_IO(io_apic_ints[intr].dst_apic_id);
intpin = io_apic_ints[intr].dst_apic_int;
assign_apic_irq(apic, intpin, irq);
io_apic_setup_intpin(apic, intpin);
}
static void
swap_apic_id(int apic, int oldid, int newid)
@ -1310,46 +1341,18 @@ setup_apic_irq_mapping(void)
}
}
/* Assign first set of interrupts to intpins on IOAPIC #0 */
/* Assign ExtInt entry if no ISA/EISA interrupt 0 entry */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
if (io_apic_ints[x].dst_apic_int == 0 &&
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].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,
int_vector);
int_vector++;
while (int_vector < APIC_INTMAPSIZE &&
int_to_apicintpin[int_vector].ioapic != -1)
int_vector++;
int_to_apicintpin[0].ioapic == -1 &&
io_apic_ints[x].int_type == 3) {
assign_apic_irq(0, 0, 0);
break;
}
}
/* PCI interrupt assignment is deferred */
}
@ -1522,8 +1525,11 @@ isa_apic_irq(int isa_irq)
if (INTTYPE(intr) == 0) { /* standard INT */
if (SRCBUSIRQ(intr) == isa_irq) {
if (apic_int_is_bus_type(intr, ISA) ||
apic_int_is_bus_type(intr, EISA))
apic_int_is_bus_type(intr, EISA)) {
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* found */
}
}
}
}
@ -1549,8 +1555,13 @@ pci_apic_irq(int pciBus, int pciDevice, int pciInt)
&& (SRCBUSID(intr) == pciBus)
&& (SRCBUSDEVICE(intr) == pciDevice)
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
if (apic_int_is_bus_type(intr, PCI))
if (apic_int_is_bus_type(intr, PCI)) {
if (INTIRQ(intr) == 0xff)
allocate_apic_irq(intr);
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* exact match */
}
return -1; /* NOT found */
}

View File

@ -1068,6 +1068,37 @@ revoke_apic_irq(int irq)
}
static void
allocate_apic_irq(int intr)
{
int apic;
int intpin;
int irq;
if (io_apic_ints[intr].int_vector != 0xff)
return; /* Interrupt handler already assigned */
if (io_apic_ints[intr].int_type != 0 &&
(io_apic_ints[intr].int_type != 3 ||
(io_apic_ints[intr].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[intr].dst_apic_int == 0)))
return; /* Not INT or ExtInt on != (0, 0) */
irq = 0;
while (irq < APIC_INTMAPSIZE &&
int_to_apicintpin[irq].ioapic != -1)
irq++;
if (irq >= APIC_INTMAPSIZE)
return; /* No free interrupt handlers */
apic = ID_TO_IO(io_apic_ints[intr].dst_apic_id);
intpin = io_apic_ints[intr].dst_apic_int;
assign_apic_irq(apic, intpin, irq);
io_apic_setup_intpin(apic, intpin);
}
static void
swap_apic_id(int apic, int oldid, int newid)
@ -1310,46 +1341,18 @@ setup_apic_irq_mapping(void)
}
}
/* Assign first set of interrupts to intpins on IOAPIC #0 */
/* Assign ExtInt entry if no ISA/EISA interrupt 0 entry */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
if (io_apic_ints[x].dst_apic_int == 0 &&
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].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,
int_vector);
int_vector++;
while (int_vector < APIC_INTMAPSIZE &&
int_to_apicintpin[int_vector].ioapic != -1)
int_vector++;
int_to_apicintpin[0].ioapic == -1 &&
io_apic_ints[x].int_type == 3) {
assign_apic_irq(0, 0, 0);
break;
}
}
/* PCI interrupt assignment is deferred */
}
@ -1522,8 +1525,11 @@ isa_apic_irq(int isa_irq)
if (INTTYPE(intr) == 0) { /* standard INT */
if (SRCBUSIRQ(intr) == isa_irq) {
if (apic_int_is_bus_type(intr, ISA) ||
apic_int_is_bus_type(intr, EISA))
apic_int_is_bus_type(intr, EISA)) {
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* found */
}
}
}
}
@ -1549,8 +1555,13 @@ pci_apic_irq(int pciBus, int pciDevice, int pciInt)
&& (SRCBUSID(intr) == pciBus)
&& (SRCBUSDEVICE(intr) == pciDevice)
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
if (apic_int_is_bus_type(intr, PCI))
if (apic_int_is_bus_type(intr, PCI)) {
if (INTIRQ(intr) == 0xff)
allocate_apic_irq(intr);
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* exact match */
}
return -1; /* NOT found */
}

View File

@ -135,6 +135,7 @@ void imen_dump __P((void));
int apic_ipi __P((int, int, int));
int selected_apic_ipi __P((u_int, int, int));
int io_apic_setup __P((int));
void io_apic_setup_intpin __P((int, int));
void io_apic_set_id __P((int, int));
int io_apic_get_id __P((int));
int ext_int_setup __P((int, int));

View File

@ -1068,6 +1068,37 @@ revoke_apic_irq(int irq)
}
static void
allocate_apic_irq(int intr)
{
int apic;
int intpin;
int irq;
if (io_apic_ints[intr].int_vector != 0xff)
return; /* Interrupt handler already assigned */
if (io_apic_ints[intr].int_type != 0 &&
(io_apic_ints[intr].int_type != 3 ||
(io_apic_ints[intr].dst_apic_id == IO_TO_ID(0) &&
io_apic_ints[intr].dst_apic_int == 0)))
return; /* Not INT or ExtInt on != (0, 0) */
irq = 0;
while (irq < APIC_INTMAPSIZE &&
int_to_apicintpin[irq].ioapic != -1)
irq++;
if (irq >= APIC_INTMAPSIZE)
return; /* No free interrupt handlers */
apic = ID_TO_IO(io_apic_ints[intr].dst_apic_id);
intpin = io_apic_ints[intr].dst_apic_int;
assign_apic_irq(apic, intpin, irq);
io_apic_setup_intpin(apic, intpin);
}
static void
swap_apic_id(int apic, int oldid, int newid)
@ -1310,46 +1341,18 @@ setup_apic_irq_mapping(void)
}
}
/* Assign first set of interrupts to intpins on IOAPIC #0 */
/* Assign ExtInt entry if no ISA/EISA interrupt 0 entry */
for (x = 0; x < nintrs; x++) {
int_vector = io_apic_ints[x].dst_apic_int;
if (int_vector < APIC_INTMAPSIZE &&
if (io_apic_ints[x].dst_apic_int == 0 &&
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].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,
int_vector);
int_vector++;
while (int_vector < APIC_INTMAPSIZE &&
int_to_apicintpin[int_vector].ioapic != -1)
int_vector++;
int_to_apicintpin[0].ioapic == -1 &&
io_apic_ints[x].int_type == 3) {
assign_apic_irq(0, 0, 0);
break;
}
}
/* PCI interrupt assignment is deferred */
}
@ -1522,8 +1525,11 @@ isa_apic_irq(int isa_irq)
if (INTTYPE(intr) == 0) { /* standard INT */
if (SRCBUSIRQ(intr) == isa_irq) {
if (apic_int_is_bus_type(intr, ISA) ||
apic_int_is_bus_type(intr, EISA))
apic_int_is_bus_type(intr, EISA)) {
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* found */
}
}
}
}
@ -1549,8 +1555,13 @@ pci_apic_irq(int pciBus, int pciDevice, int pciInt)
&& (SRCBUSID(intr) == pciBus)
&& (SRCBUSDEVICE(intr) == pciDevice)
&& (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */
if (apic_int_is_bus_type(intr, PCI))
if (apic_int_is_bus_type(intr, PCI)) {
if (INTIRQ(intr) == 0xff)
allocate_apic_irq(intr);
if (INTIRQ(intr) == 0xff)
return -1; /* unassigned */
return INTIRQ(intr); /* exact match */
}
return -1; /* NOT found */
}

View File

@ -135,6 +135,7 @@ void imen_dump __P((void));
int apic_ipi __P((int, int, int));
int selected_apic_ipi __P((u_int, int, int));
int io_apic_setup __P((int));
void io_apic_setup_intpin __P((int, int));
void io_apic_set_id __P((int, int));
int io_apic_get_id __P((int));
int ext_int_setup __P((int, int));