PERFORCE change 119456 for review
Bruce M Simpson
bms at FreeBSD.org
Tue May 8 01:42:54 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=119456
Change 119456 by bms at 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);
More information about the p4-projects
mailing list