nexus/intr: Change the wrong cpuid backtrace to assertion
[dragonfly.git] / sys / platform / pc64 / x86_64 / nexus.c
index 9314d64..2ab6deb 100644 (file)
@@ -58,6 +58,8 @@
 
 #include <machine/nexusvar.h>
 #include <machine/smp.h>
+#include <machine/intr_machdep.h>
+#include <machine_base/apic/ioapic.h>
 
 #define I386_BUS_SPACE_IO       0       /* space is i/o space */
 #define I386_BUS_SPACE_MEM      1       /* space is mem space */
@@ -70,7 +72,7 @@ struct nexus_device {
 
 #define DEVTONX(dev)   ((struct nexus_device *)device_get_ivars(dev))
 
-static struct rman irq_rman, drq_rman, port_rman, mem_rman;
+static struct rman irq_rman[MAXCPU], drq_rman, port_rman, mem_rman;
 
 static int nexus_probe(device_t);
 static int nexus_attach(device_t);
@@ -79,7 +81,7 @@ static        int nexus_print_child(device_t, device_t);
 static device_t nexus_add_child(device_t bus, device_t parent, int order,
                                const char *name, int unit);
 static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
-                                             u_long, u_long, u_long, u_int);
+    u_long, u_long, u_long, u_int, int);
 static int nexus_read_ivar(device_t, device_t, int, uintptr_t *);
 static int nexus_write_ivar(device_t, device_t, int, uintptr_t);
 static int nexus_activate_resource(device_t, device_t, int, int,
@@ -95,7 +97,8 @@ static        int nexus_setup_intr(device_t, device_t, struct resource *, int flags,
                             void **, lwkt_serialize_t);
 static int nexus_teardown_intr(device_t, device_t, struct resource *,
                                void *);
-static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long);
+static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long,
+                              int);
 static int nexus_get_resource(device_t, device_t, int, int, u_long *, u_long *);
 static void nexus_delete_resource(device_t, device_t, int, int);
 
@@ -139,41 +142,27 @@ static driver_t nexus_driver = {
 };
 static devclass_t nexus_devclass;
 
-DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
+DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, NULL, NULL);
 
 static int
 nexus_probe(device_t dev)
 {
+       int cpuid;
+
        device_quiet(dev);      /* suppress attach message for neatness */
 
-       /*
-        * IRQ's are on the mainboard on old systems, but on the ISA part
-        * of PCI->ISA bridges.  There would be multiple sets of IRQs on
-        * multi-ISA-bus systems.  PCI interrupts are routed to the ISA
-        * component, so in a way, PCI can be a partial child of an ISA bus(!).
-        * APIC interrupts are global though.
-        * In the non-APIC case, disallow the use of IRQ 2.
-        */
-       irq_rman.rm_start = 0;
-       irq_rman.rm_type = RMAN_ARRAY;
-       irq_rman.rm_descr = "Interrupt request lines";
-#ifdef SMP /* APIC-IO */
-if (apic_io_enable) {
-       irq_rman.rm_end = APIC_INTMAPSIZE - 1;
-       if (rman_init(&irq_rman)
-           || rman_manage_region(&irq_rman,
-                                 irq_rman.rm_start, irq_rman.rm_end))
-               panic("nexus_probe irq_rman");
-} else {
-#endif
-       irq_rman.rm_end = 15;
-       if (rman_init(&irq_rman)
-           || rman_manage_region(&irq_rman, irq_rman.rm_start, 1)
-           || rman_manage_region(&irq_rman, 3, irq_rman.rm_end))
-               panic("nexus_probe irq_rman");
-#ifdef SMP /* APIC-IO */
-}
-#endif
+       for (cpuid = 0; cpuid < ncpus; ++cpuid) {
+               struct rman *rm = &irq_rman[cpuid];
+
+               rm->rm_start = 0;
+               rm->rm_end = IDT_HWI_VECTORS - 1;
+               rm->rm_type = RMAN_ARRAY;
+               rm->rm_descr = "Interrupt request lines";
+
+               if (rman_init(rm, cpuid))
+                       panic("nexus_probe rman_init");
+               MachIntrABI.rman_setup(rm);
+       }
 
        /*
         * ISA DMA on PCI systems is implemented in the ISA part of each
@@ -185,7 +174,7 @@ if (apic_io_enable) {
        drq_rman.rm_type = RMAN_ARRAY;
        drq_rman.rm_descr = "DMA request lines";
        /* XXX drq 0 not available on some machines */
-       if (rman_init(&drq_rman)
+       if (rman_init(&drq_rman, -1)
            || rman_manage_region(&drq_rman,
                                  drq_rman.rm_start, drq_rman.rm_end))
                panic("nexus_probe drq_rman");
@@ -199,7 +188,7 @@ if (apic_io_enable) {
        port_rman.rm_end = 0xffff;
        port_rman.rm_type = RMAN_ARRAY;
        port_rman.rm_descr = "I/O ports";
-       if (rman_init(&port_rman)
+       if (rman_init(&port_rman, -1)
            || rman_manage_region(&port_rman, 0, 0xffff))
                panic("nexus_probe port_rman");
 
@@ -207,7 +196,7 @@ if (apic_io_enable) {
        mem_rman.rm_end = ~0u;
        mem_rman.rm_type = RMAN_ARRAY;
        mem_rman.rm_descr = "I/O memory addresses";
-       if (rman_init(&mem_rman)
+       if (rman_init(&mem_rman, -1)
            || rman_manage_region(&mem_rman, 0, ~0))
                panic("nexus_probe mem_rman");
 
@@ -230,15 +219,9 @@ nexus_attach(device_t dev)
        bus_generic_attach(dev);
 
        /*
-        * And if we didn't see EISA or ISA on a pci bridge, create some
-        * connection points now so they show up "on motherboard".
+        * And if we didn't see ISA on a pci bridge, create a
+        * connection point now so it shows up "on motherboard".
         */
-       if (!devclass_get_device(devclass_find("eisa"), 0)) {
-               child = BUS_ADD_CHILD(dev, dev, 0, "eisa", 0);
-               if (child == NULL)
-                       panic("nexus_attach eisa");
-               device_probe_and_attach(child);
-       }
        if (!devclass_get_device(devclass_find("isa"), 0)) {
                child = BUS_ADD_CHILD(dev, dev, 0, "isa", 0);
                if (child == NULL)
@@ -339,7 +322,7 @@ nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
  */
 static struct resource *
 nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
-                    u_long start, u_long end, u_long count, u_int flags)
+    u_long start, u_long end, u_long count, u_int flags, int cpuid)
 {
        struct nexus_device *ndev = DEVTONX(child);
        struct  resource *rv;
@@ -361,13 +344,16 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
                start = rle->start;
                end = rle->end;
                count = rle->count;
+               cpuid = rle->cpuid;
        }
 
        flags &= ~RF_ACTIVE;
 
        switch (type) {
        case SYS_RES_IRQ:
-               rm = &irq_rman;
+               KASSERT(cpuid >= 0 || cpuid < ncpus,
+                   ("nexus invalid cpuid %d:\n", cpuid));
+               rm = &irq_rman[cpuid];
                break;
 
        case SYS_RES_DRQ:
@@ -514,7 +500,7 @@ nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
         */
        *cookiep = register_int(irq->r_start, (inthand2_t *)ihand, arg,
                                device_get_nameunit(child), serializer,
-                               icflags);
+                               icflags, rman_get_cpuid(irq));
        if (*cookiep == NULL)
                error = EINVAL;
        return (error);
@@ -524,20 +510,22 @@ static int
 nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
 {
        if (ih) {
-               unregister_int(ih);
+               unregister_int(ih, rman_get_cpuid(r));
                return (0);
        }
        return(-1);
 }
 
 static int
-nexus_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count)
+nexus_set_resource(device_t dev, device_t child, int type, int rid,
+    u_long start, u_long count, int cpuid)
 {
        struct nexus_device     *ndev = DEVTONX(child);
        struct resource_list    *rl = &ndev->nx_resources;
 
        /* XXX this should return a success/failure indicator */
-       resource_list_add(rl, type, rid, start, start + count - 1, count);
+       resource_list_add(rl, type, rid, start, start + count - 1, count,
+           cpuid);
        return(0);
 }