Skip site navigation (1)Skip section navigation (2)
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>