diff options
author | tegge <tegge@FreeBSD.org> | 2000-01-04 22:24:59 +0000 |
---|---|---|
committer | tegge <tegge@FreeBSD.org> | 2000-01-04 22:24:59 +0000 |
commit | 8bfa846d9356da2586f4a6e1d554c39177f59e14 (patch) | |
tree | c6080f3bb42c4a733d4d4ce7c0d651f056f6f374 /sys/amd64/include | |
parent | 4f702e355c9a539bf4c04e5f1f2a333c2bc4fe25 (diff) | |
download | FreeBSD-src-8bfa846d9356da2586f4a6e1d554c39177f59e14.zip FreeBSD-src-8bfa846d9356da2586f4a6e1d554c39177f59e14.tar.gz |
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>
Diffstat (limited to 'sys/amd64/include')
-rw-r--r-- | sys/amd64/include/mptable.h | 70 | ||||
-rw-r--r-- | sys/amd64/include/smp.h | 2 |
2 files changed, 66 insertions, 6 deletions
diff --git a/sys/amd64/include/mptable.h b/sys/amd64/include/mptable.h index b565cee..48d716a 100644 --- a/sys/amd64/include/mptable.h +++ b/sys/amd64/include/mptable.h @@ -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++) { + int_vector = io_apic_ints[x].src_bus_irq; + if (int_vector < APIC_INTMAPSIZE && + io_apic_ints[x].int_vector == 0xff && + 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, + int_vector); + } + } + + /* Assign interrupts on first 24 intpins on IOAPIC #0 */ for (x = 0; x < nintrs; x++) { - if (io_apic_ints[x].dst_apic_int < APIC_INTMAPSIZE && + 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, + assign_apic_irq(0, io_apic_ints[x].dst_apic_int, - 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, diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index 8f0a2f8..c2340ae 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -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)); |