X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/9241a843d5f6f30bc4a6032b6c7ce5ab966f0107..828d8bb00bd92773daeae970dce4078bf307b207:/sys/platform/pc64/x86_64/nexus.c diff --git a/sys/platform/pc64/x86_64/nexus.c b/sys/platform/pc64/x86_64/nexus.c index b9b8c68cbc..2ab6deb681 100644 --- a/sys/platform/pc64/x86_64/nexus.c +++ b/sys/platform/pc64/x86_64/nexus.c @@ -58,7 +58,8 @@ #include #include -#include +#include +#include #define I386_BUS_SPACE_IO 0 /* space is i/o space */ #define I386_BUS_SPACE_MEM 1 /* space is mem space */ @@ -71,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); @@ -80,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, @@ -96,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); @@ -140,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 @@ -186,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"); @@ -200,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"); @@ -208,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"); @@ -231,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) @@ -340,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; @@ -362,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: @@ -515,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); @@ -525,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); }