IO APIC: Assign pins dedicated to PCI in the early stage.
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Thu, 9 Jul 2009 09:09:21 +0000 (17:09 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 11 Jul 2009 02:27:16 +0000 (10:27 +0800)
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
sys/platform/pc32/apic/apic_abi.c
sys/platform/pc32/i386/mp_machdep.c

index acc8651..7417a8e 100644 (file)
@@ -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);
     }
index 68a22db..4aa2945 100644 (file)
@@ -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);
index fb3bb96..224c13a 100644 (file)
@@ -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 */
                        }
                }