Date: Tue, 8 May 2007 01:42:53 GMT From: Bruce M Simpson <bms@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 119456 for review Message-ID: <200705080142.l481grpa087991@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=119456 Change 119456 by bms@bms_anglepoise on 2007/05/08 01:42:25 Numerous nexus changes: Bring in nexus_[set|get]_resource() from amd64 to deal with setting resources on direct children of nexus. Track virtual addresses for resource allocations; these are assumed to be in KSEG1 so client device code can use the right mapping. Bring in code to deal with hinted resource allocations (mostly from ia64/sun4v). Implement nexus_hinted_child(). Call bus_enumerate_hinted_children() to probe and attach children which are hard-wired on nexus. Use a RID of 0x20 for bus space reservations hard-wired on nexus. Force rman_debug to 1 for now. Add various debugging printfs. Sort prototypes and bus/device methods. Affected files ... .. //depot/projects/mips2/src/sys/mips/mips/nexus.c#8 edit Differences ... ==== //depot/projects/mips2/src/sys/mips/mips/nexus.c#8 (text+ko) ==== @@ -65,20 +65,30 @@ }; #define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev)) +#define NUM_MIPS_IRQS 6 +#define MIPS_MEM_RID 0x20 static struct rman irq_rman; static struct rman mem_rman; -static int nexus_probe(device_t); -static int nexus_attach(device_t); -static int nexus_print_child(device_t, device_t); -static int nexus_print_all_resources(device_t dev); -static device_t nexus_add_child(device_t, int, const char *, int); static struct resource * nexus_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); static int nexus_activate_resource(device_t, device_t, int, int, struct resource *); +static device_t nexus_add_child(device_t, int, const char *, int); +static int nexus_attach(device_t); +static void nexus_delete_resource(device_t, device_t, int, int); +static struct resource_list * + nexus_get_reslist(device_t, device_t); +static int nexus_get_resource(device_t, device_t, int, int, u_long *, + u_long *); +static void nexus_hinted_child(device_t, const char *, int); +static int nexus_print_child(device_t, device_t); +static int nexus_print_all_resources(device_t dev); +static int nexus_probe(device_t); +static int nexus_set_resource(device_t, device_t, int, int, u_long, + u_long); static int nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep); @@ -89,13 +99,20 @@ /* Device interface */ DEVMETHOD(device_probe, nexus_probe), DEVMETHOD(device_attach, nexus_attach), + /* Bus interface */ - DEVMETHOD(bus_print_child, nexus_print_child), DEVMETHOD(bus_add_child, nexus_add_child), + DEVMETHOD(bus_activate_resource,nexus_activate_resource), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), - DEVMETHOD(bus_activate_resource, nexus_activate_resource), + DEVMETHOD(bus_delete_resource, nexus_delete_resource), + DEVMETHOD(bus_get_resource, nexus_get_resource), + DEVMETHOD(bus_get_resource_list, nexus_get_reslist), + DEVMETHOD(bus_hinted_child, nexus_hinted_child), + DEVMETHOD(bus_print_child, nexus_print_child), + DEVMETHOD(bus_set_resource, nexus_set_resource), DEVMETHOD(bus_setup_intr, nexus_setup_intr), DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), + { 0, 0 } }; @@ -106,18 +123,22 @@ }; static devclass_t nexus_devclass; +extern int rman_debug; /* XXX XXX */ + static int nexus_probe(device_t dev) { device_set_desc(dev, "MIPS32 root nexus"); + rman_debug = 1; /* XXX XXX */ + irq_rman.rm_start = 0; - irq_rman.rm_end = 5; + irq_rman.rm_end = NUM_MIPS_IRQS - 1; irq_rman.rm_type = RMAN_ARRAY; irq_rman.rm_descr = "Hardware IRQs"; if (rman_init(&irq_rman) != 0 || - rman_manage_region(&irq_rman, 0, 5) != 0) { + rman_manage_region(&irq_rman, 0, NUM_MIPS_IRQS - 1) != 0) { panic("nexus_probe irq_rman"); } @@ -140,7 +161,7 @@ register_t sr = intr_disable(); irq = rman_get_start(res); - if (irq > 5) + if (irq >= NUM_MIPS_IRQS) return (0); cpu_establish_hardintr(device_get_nameunit(child), filt, intr, arg, @@ -162,8 +183,13 @@ nexus_attach(device_t dev) { + /* + * XXX: next line needed to probe clock (intr 5), + * otherwise no clock and lots of stray hard interrupt 5 + * once compare counts down. + */ + bus_generic_probe(dev); bus_enumerate_hinted_children(dev); - bus_generic_probe(dev); bus_generic_attach(dev); return (0); @@ -199,6 +225,34 @@ return (retval); } +static void +nexus_hinted_child(device_t bus, const char *dname, int dunit) +{ + device_t child; + long maddr; + int msize; + int result; + + child = BUS_ADD_CHILD(bus, 0, dname, dunit); + + /* + * Set hard-wired resources for hinted child using + * specific RIDs. + */ + resource_long_value(dname, dunit, "maddr", &maddr); + resource_int_value(dname, dunit, "msize", &msize); + + printf("%s: discovered hinted child %s at maddr %p(%d)\n", + __func__, device_get_nameunit(child), + (void *)(intptr_t)maddr, msize); + + result = bus_set_resource(child, SYS_RES_MEMORY, MIPS_MEM_RID, + maddr, msize); + if (result != 0) { + device_printf(bus, "warning: bus_set_resource() failed\n"); + } +} + static device_t nexus_add_child(device_t bus, int order, const char *name, int unit) { @@ -227,31 +281,70 @@ 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) { - struct resource *rv; - struct rman *rm; - int needactivate = flags & RF_ACTIVE; + struct nexus_device *ndev = DEVTONX(child); + struct resource *rv; + struct resource_list_entry *rle; + struct rman *rm; + int isdefault, needactivate, passthrough; + + printf("%s: entry (%p, %p, %d, %p, %p, %p, %ld, %d)\n", + __func__, bus, child, type, rid, (void *)(intptr_t)start, + (void *)(intptr_t)end, count, flags); + printf("%s: requested rid is %d\n", __func__, *rid); + + isdefault = (start == 0UL && end == ~0UL && count == 1); + needactivate = flags & RF_ACTIVE; + passthrough = (device_get_parent(child) != bus); + rle = NULL; + + /* + * If this is an allocation of the "default" range for a given RID, + * and we know what the resources for this device are (ie. they aren't + * maintained by a child bus), then work out the start/end values. + */ + if (isdefault) { + rle = resource_list_find(&ndev->nx_resources, type, *rid); + if (rle == NULL) + return (NULL); + if (rle->res != NULL) { + /* XXX panic? */ + printf("%s: resource entry is busy\n", __func__); + return (NULL); + } + start = rle->start; + end = rle->end; + count = rle->count; + } switch (type) { case SYS_RES_IRQ: rm = &irq_rman; break; - case SYS_RES_MEMORY: rm = &mem_rman; break; - default: + printf("%s: unknown resource type %d\n", __func__, type); return (0); } rv = rman_reserve_resource(rm, start, end, count, flags, child); - if (rv == 0) + if (rv == 0) { + printf("%s: could not reserve resource\n", __func__); return (0); + } rman_set_rid(rv, *rid); +#if 0 + if (type == SYS_RES_MEMORY) { + rman_set_bustag(rv, &nexus_bustag); + rman_set_bushandle(rv, rman_get_start(rv)); + } +#endif if (needactivate) { if (bus_activate_resource(child, type, *rid, rv)) { + printf("%s: could not activate resource\n", __func__); rman_release_resource(rv); return (0); } @@ -266,7 +359,8 @@ { /* - * If this is a memory resource, track the virtual direct mapping. + * If this is a memory resource, track the direct mapping + * in the uncached MIPS KSEG1 segment. * XXX is this correct? */ if (type == SYS_RES_MEMORY) { @@ -281,4 +375,58 @@ return (rman_activate_resource(r)); } +static struct resource_list * +nexus_get_reslist(device_t dev, device_t child) +{ + struct nexus_device *ndev = DEVTONX(child); + + return (&ndev->nx_resources); +} + +static int +nexus_set_resource(device_t dev, device_t child, int type, int rid, + u_long start, u_long count) +{ + struct nexus_device *ndev = DEVTONX(child); + struct resource_list *rl = &ndev->nx_resources; + struct resource_list_entry *rle; + + printf("%s: entry (%p, %p, %d, %d, %p, %ld)\n", + __func__, dev, child, type, rid, (void *)(intptr_t)start, count); + + rle = resource_list_add(rl, type, rid, start, start + count - 1, + count); + if (rle == NULL) + return (ENXIO); + + return (0); +} + +static int +nexus_get_resource(device_t dev, device_t child, int type, int rid, + u_long *startp, u_long *countp) +{ + struct nexus_device *ndev = DEVTONX(child); + struct resource_list *rl = &ndev->nx_resources; + struct resource_list_entry *rle; + + rle = resource_list_find(rl, type, rid); + if (!rle) + return(ENOENT); + if (startp) + *startp = rle->start; + if (countp) + *countp = rle->count; + return (0); +} + +static void +nexus_delete_resource(device_t dev, device_t child, int type, int rid) +{ + struct nexus_device *ndev = DEVTONX(child); + struct resource_list *rl = &ndev->nx_resources; + + resource_list_delete(rl, type, rid); +} + DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200705080142.l481grpa087991>