From f41c43c19e17ca807a28ba60b32364f1a40438f4 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 9 Jul 2009 17:09:21 +0800 Subject: [PATCH] IO APIC: Assign pins dedicated to PCI in the early stage. After this, we no longer need to reprogramme IO APIC every time an interrupt handler is to be registered, which is potentially dangerous. --- sys/kern/kern_intr.c | 10 +--------- sys/platform/pc32/apic/apic_abi.c | 2 ++ sys/platform/pc32/i386/mp_machdep.c | 17 ++++++++++++----- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index acc8651fb9..7417a8e888 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -286,16 +286,8 @@ register_int(int intr, inthand2_t *handler, void *arg, const char *name, /* * Setup the machine level interrupt vector - * - * XXX temporary workaround for some ACPI brokedness. ACPI installs - * its interrupt too early, before the IOAPICs have been configured, - * which means the IOAPIC is not enabled by the registration of the - * ACPI interrupt. Anything else sharing that IRQ will wind up not - * being enabled. Temporarily work around the problem by always - * installing and enabling on every new interrupt handler, even - * if one has already been setup on that irq. */ - if (intr < FIRST_SOFTINT /* && info->i_slow + info->i_fast == 1*/) { + if (intr < FIRST_SOFTINT && info->i_slow + info->i_fast == 1) { if (machintr_vector_setup(intr, intr_flags)) kprintf("machintr_vector_setup: failed on irq %d\n", intr); } diff --git a/sys/platform/pc32/apic/apic_abi.c b/sys/platform/pc32/apic/apic_abi.c index 68a22db566..4aa2945ab7 100644 --- a/sys/platform/pc32/apic/apic_abi.c +++ b/sys/platform/pc32/apic/apic_abi.c @@ -308,6 +308,8 @@ apic_vectorctl(int op, int intr, int flags) * clear the IRR bit. */ if (int_to_apicintpin[intr].ioapic >= 0) { + if (bootverbose) + kprintf("IOAPIC: try clearing IRR for irq %d\n", intr); imen_lock(); select = int_to_apicintpin[intr].redirindex; value = io_apic_read(int_to_apicintpin[intr].ioapic, select); diff --git a/sys/platform/pc32/i386/mp_machdep.c b/sys/platform/pc32/i386/mp_machdep.c index fb3bb9641c..224c13a59c 100644 --- a/sys/platform/pc32/i386/mp_machdep.c +++ b/sys/platform/pc32/i386/mp_machdep.c @@ -1254,7 +1254,6 @@ allocate_apic_irq(int intr) intpin = io_apic_ints[intr].dst_apic_int; assign_apic_irq(apic, intpin, irq); - io_apic_setup_intpin(apic, intpin); } @@ -1560,7 +1559,14 @@ setup_apic_irq_mapping(void) break; } } - /* PCI interrupt assignment is deferred */ + + /* Assign PCI interrupts */ + for (x = 0; x < nintrs; ++x) { + if (io_apic_ints[x].int_type == 0 && + io_apic_ints[x].int_vector == 0xff && + apic_int_is_bus_type(x, PCI)) + allocate_apic_irq(x); + } } #endif @@ -1767,10 +1773,11 @@ pci_apic_irq(int pciBus, int pciDevice, int pciInt) && (SRCBUSDEVICE(intr) == pciDevice) && (SRCBUSLINE(intr) == pciInt)) { /* a candidate IRQ */ if (apic_int_is_bus_type(intr, PCI)) { - if (INTIRQ(intr) == 0xff) - allocate_apic_irq(intr); - if (INTIRQ(intr) == 0xff) + if (INTIRQ(intr) == 0xff) { + kprintf("IOAPIC: pci_apic_irq() " + "failed\n"); return -1; /* unassigned */ + } return INTIRQ(intr); /* exact match */ } } -- 2.41.0