PERFORCE change 173821 for review

Rafal Jaworowski raj at FreeBSD.org
Thu Jan 28 11:46:36 UTC 2010


http://p4web.freebsd.org/chv.cgi?CH=173821

Change 173821 by raj at raj_fdt on 2010/01/28 11:46:08

	Refactor FDT infrastructure to better suit multiple platforms and
	architectures.
	
	- Move fdt_pic_table[] and IRQ info parsing routines to platform
	  specific files.
	- Introduce machine-specific fdt.h header which is a fron-end
	  interface between platform independent code of {fdt,simple}bus and
	  local platform-specific defines and other items (including IRQ lines
	  number, base VA of the internal registers etc.).
	- Make the [early access] fdt_is_compatible() a common public routine,
	  as there's multiple consumers besides uart(4) attachment.
	- Teach fdtbus, simplebus and helper code a bit more endian-safety.
	- Eliminate diag output from early access routines (where console can
	  be unavailable yet, which could lead to a hang).
	- Simplify parent #address-cells and #size-cells processing.
	- There's still a couple of rough edges, but we are capable of running
	  {fdt,simple}bus driver on both ARM and PowerPC systems.

Affected files ...

.. //depot/projects/fdt/sys/dev/fdt/fdt_common.c#7 edit
.. //depot/projects/fdt/sys/dev/fdt/fdt_common.h#3 edit
.. //depot/projects/fdt/sys/dev/fdt/fdt_powerpc.c#1 add
.. //depot/projects/fdt/sys/dev/fdt/fdtbus.c#3 edit
.. //depot/projects/fdt/sys/dev/fdt/simplebus.c#4 edit
.. //depot/projects/fdt/sys/dev/uart/uart_cpu_powerpc.c#3 edit
.. //depot/projects/fdt/sys/powerpc/include/fdt.h#1 add

Differences ...

==== //depot/projects/fdt/sys/dev/fdt/fdt_common.c#7 (text+ko) ====

@@ -32,12 +32,11 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/ktr.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/bus.h>
 
-#include <machine/intr_machdep.h>
+#include <machine/resource.h>
 
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
@@ -58,7 +57,48 @@
 #define debugf(fmt, args...)
 #endif
 
+/*
+ * This routine is an early-usage version of the ofw_bus_is_compatible() when
+ * the ofw_bus I/F is not available (like early console routines and similar).
+ * Note the buffer has to be on the stack since malloc() is usually not
+ * available in such cases either.
+ */
 int
+fdt_is_compatible(phandle_t node, const char *compatstr)
+{
+#define FDT_COMPAT_LEN 255
+	char *buf[FDT_COMPAT_LEN];
+	char *compat;
+	int len, onelen, l, rv;
+
+	if ((len = OF_getproplen(node, "compatible")) <= 0)
+		return (0);
+
+	compat = (char *)&buf;
+	bzero(compat, FDT_COMPAT_LEN);
+
+	if (OF_getprop(node, "compatible", compat, len) < 0)
+		return (0);
+
+	onelen = strlen(compatstr);
+	rv = 0;
+	while (len > 0) {
+		if (strncasecmp(compat, compatstr, onelen) == 0) {
+			/* Found it. */
+			rv = 1;
+			break;
+		}
+		/* Slide to the next sub-string. */
+		l = strlen(compat) + 1;
+		compat += l;
+		len -= l;
+	}
+
+	return (rv);
+}
+
+
+int
 fdt_is_enabled(phandle_t node)
 {
 	char *stat;
@@ -90,7 +130,7 @@
 	    sizeof(addr_cells)) <= 0)
 		addr_cells = 2;
 
-	return ((int)addr_cells);
+	return (fdt32_to_cpu((int)addr_cells));
 }
 
 void
@@ -156,11 +196,11 @@
 	cell_size = sizeof(cell);
 	if (OF_getprop(node, "#address-cells", &cell, cell_size) < cell_size)
 		cell = 2;
-	*addr_cells = (int)cell;
+	*addr_cells = fdt32_to_cpu((int)cell);
 
 	if (OF_getprop(node, "#size-cells", &cell, cell_size) < cell_size)
 		cell = 1;
-	*size_cells = (int)cell;
+	*size_cells = fdt32_to_cpu((int)cell);
 
 	if (*addr_cells > 2 || *size_cells > 2)
 		return (ERANGE);
@@ -215,18 +255,16 @@
 {
 
 	/* Address portion. */
-	if (fdt_data_verify((void *)data, addr_cells)) {
-		debugf("tuple #%d: unsupported addr value\n", addr_cells);
+	if (fdt_data_verify((void *)data, addr_cells))
 		return (ERANGE);
-	}
+
 	*start = fdt_data_get((void *)data, addr_cells);
 	data += addr_cells;
 
 	/* Size portion. */
-	if (fdt_data_verify((void *)data, size_cells)) {
-		debugf("tuple #%d: unsupported size value\n", size_cells);
+	if (fdt_data_verify((void *)data, size_cells))
 		return (ERANGE);
-	}
+
 	*count = fdt_data_get((void *)data, size_cells);
 	return (0);
 }
@@ -240,14 +278,8 @@
 	int tuple_size, tuples;
 	int i, rv;
 
-	addr_cells = fdt_parent_addr_cells(node);
-	if (addr_cells > 0) {
-		rv = OF_searchprop(OF_parent(node), "#size-cells",
-		    &size_cells, sizeof(size_cells));
-		if (rv <= 0)
-			size_cells = 1;
-	} else
-		size_cells = 0;
+	if (fdt_addrsize_cells(OF_parent(node), &addr_cells, &size_cells) != 0)
+		return (ENXIO);
 
 	tuple_size = sizeof(pcell_t) * (addr_cells + size_cells);
 	tuples = OF_getprop_alloc(node, "reg", tuple_size, (void **)&reg);
@@ -286,81 +318,6 @@
 }
 
 static int
-fdt_pic_decode_iic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
-    int *pol)
-{
-
-	/* TODO */
-	return (ENXIO);
-}
-
-static int
-fdt_pic_decode_openpic(phandle_t node, pcell_t *intr, int *interrupt,
-    int *trig, int *pol)
-{
-	char *compat;
-	ssize_t prop_len;
-	int rv;
-
-	prop_len = OF_getprop_alloc(node, "compatible", 1, (void **)&compat);
-	if (prop_len <= 0)
-		return (ENXIO);
-
-	rv = 0;
-	if (strncmp("open-pic", compat, 8) < 0) {
-		rv = ENXIO;
-		goto out;
-	}
-
-	/*
-	 * XXX The interrupt number read out from the device tree is already
-	 * offset by 16 to reflect the 'internal' IRQ range shift on the
-	 * OpenPIC. We still however need to account for the ISA IRQ block,
-	 * potentially in use as well.
-	 */
-	*interrupt = ISA_IRQ_COUNT + intr[0];
-
-	switch (intr[1]) {
-	case 0:
-		/* L to H edge */
-		*trig = INTR_TRIGGER_EDGE;
-		*pol = INTR_POLARITY_HIGH;
-		break;
-	case 1:
-		/* Active L level */
-		*trig = INTR_TRIGGER_LEVEL;
-		*pol = INTR_POLARITY_LOW;
-		break;
-	case 2:
-		/* Active H level */
-		*trig = INTR_TRIGGER_LEVEL;
-		*pol = INTR_POLARITY_HIGH;
-		break;
-	case 3:
-		/* H to L edge */
-		*trig = INTR_TRIGGER_EDGE;
-		*pol = INTR_POLARITY_LOW;
-		break;
-	default:
-		*trig = INTR_TRIGGER_CONFORM;
-		*pol = INTR_POLARITY_CONFORM;
-	}
-
-out:
-	free(compat, M_OFWPROP);
-	return (rv);
-}
-
-typedef int (*fdt_pic_decode_t)(phandle_t, pcell_t *, int *, int *,
-    int *);
-
-static fdt_pic_decode_t fdt_pic_table[] = {
-	&fdt_pic_decode_iic,
-	&fdt_pic_decode_openpic,
-	NULL
-};
-
-static int
 fdt_intr_decode(phandle_t intr_parent, pcell_t *intr, int *interrupt,
     int *trig, int *pol)
 {
@@ -403,14 +360,17 @@
 	if (OF_getprop(node, "interrupt-parent", &iph, sizeof(iph)) <= 0) {
 		debugf("no intr-parent phandle\n");
 		intr_par = OF_parent(node);
-	} else
+	} else {
+		iph = fdt32_to_cpu(iph);
 		intr_par = OF_instance_to_package(iph);
+	}
 
 	if (OF_getprop(intr_par, "#interrupt-cells", &intr_cells,
 	    sizeof(intr_cells)) <= 0) {
 		debugf("no intr-cells defined, defaulting to 1\n");
 		intr_cells = 1;
 	}
+	intr_cells = fdt32_to_cpu(intr_cells);
 
 	intr_num = OF_getprop_alloc(node, "interrupts",
 	    intr_cells * sizeof(pcell_t), (void **)&intr);

==== //depot/projects/fdt/sys/dev/fdt/fdt_common.h#3 (text+ko) ====

@@ -39,6 +39,10 @@
 	enum intr_polarity	pol;
 };
 
+typedef int (*fdt_pic_decode_t)(phandle_t, pcell_t *, int *, int *, int *);
+
+extern fdt_pic_decode_t fdt_pic_table[];
+
 int fdt_addrsize_cells(phandle_t, int *, int *);
 u_long fdt_data_get(void *, int);
 int fdt_parent_addr_cells(phandle_t);
@@ -47,6 +51,7 @@
 int fdt_reg_to_rl(phandle_t, struct resource_list *, u_long);
 int fdt_intr_to_rl(phandle_t, struct resource_list *, struct sense_level *);
 int fdt_data_to_res(pcell_t *, int, int, u_long *, u_long *);
+int fdt_is_compatible(phandle_t, const char *);
 int fdt_is_enabled(phandle_t);
 
 #endif /* FDT_COMMON_H */

==== //depot/projects/fdt/sys/dev/fdt/fdtbus.c#3 (text+ko) ====

@@ -30,6 +30,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_platform.h"
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/ktr.h>
@@ -41,7 +42,7 @@
 
 #include <dev/ofw/openfirm.h>
 
-#include <machine/intr_machdep.h>
+#include <machine/fdt.h>
 
 #include "fdt_common.h"
 #include "ofw_bus_if.h"
@@ -58,8 +59,6 @@
 
 static MALLOC_DEFINE(M_FDTBUS, "fdtbus", "FDTbus devices information");
 
-extern struct bus_space bs_be_tag;
-
 struct fdtbus_devinfo {
 	phandle_t		di_node;
 	char			*di_name;
@@ -174,7 +173,7 @@
 	 * IRQ rman.
 	 */
 	start = 0;
-	end = INTR_VECTORS - 1;
+	end = FDT_INTR_MAX - 1;
 	sc->sc_irq.rm_start = start;
 	sc->sc_irq.rm_end = end;
 	sc->sc_irq.rm_type = RMAN_ARRAY;
@@ -261,6 +260,7 @@
 static device_t
 newbus_device_from_fdt_node(device_t parent, phandle_t node)
 {
+	u_long base;
 	device_t child;
 	struct fdtbus_devinfo *di;
 	char *name, *type, *compat;
@@ -286,13 +286,17 @@
 		di->di_compat = compat;
 
 		resource_list_init(&di->di_res);
-
+#ifdef MPC85XX
 		/*
 		 * XXX this 0x1ef00000 offset is a gross hack, which assumes:
 		 * - physical addresses in the DTS are 0xe0000000 range, and
 		 * - virtual CCSR base in kernel is 0xfef00000
 		 */
-		if (fdt_reg_to_rl(node, &di->di_res, 0x1ef00000)) {
+		base = 0x1ef00000;
+#else
+		base = 0;
+#endif
+		if (fdt_reg_to_rl(node, &di->di_res, base)) {
 			device_printf(child, "could not process 'reg' "
 			    "property\n");
 			newbus_device_destroy(child);
@@ -383,7 +387,7 @@
 
 	if (type == SYS_RES_IOPORT || type == SYS_RES_MEMORY) {
 		/* XXX endianess should be set based on SOC node */
-		rman_set_bustag(res, &bs_be_tag);
+		rman_set_bustag(res, fdtbus_bs_tag);
 		rman_set_bushandle(res, rman_get_start(res));
 	}
 
@@ -427,8 +431,12 @@
 	if (err)
 		return (err);
 
+#if defined(__powerpc__)
 	err = powerpc_setup_intr(device_get_nameunit(child),
 	    rman_get_start(res), filter, ihand, arg, flags, cookiep);
+#elif defined(__arm__)
+	/* TODO */
+#endif
 
 	return (err);
 }
@@ -455,7 +463,11 @@
     void *cookie)
 {
 
+#if defined(__powerpc__)
 	return (powerpc_teardown_intr(cookie));
+#elif defined(__arm__)
+	return (arm_remove_irqhandler(rman_get_start(res), cookie));
+#endif
 }
 
 static const char *

==== //depot/projects/fdt/sys/dev/fdt/simplebus.c#4 (text+ko) ====

@@ -30,6 +30,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_platform.h"
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/ktr.h>
@@ -39,8 +40,7 @@
 #include <sys/rman.h>
 #include <sys/malloc.h>
 
-#include <machine/intr_machdep.h>
-#include <machine/vmparam.h>
+#include <machine/fdt.h>
 
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
@@ -140,11 +140,16 @@
 static int
 simplebus_probe(device_t dev)
 {
+	struct simplebus_softc *sc;
 
 	if (!ofw_bus_is_compatible(dev, "simple-bus"))
 		return (ENXIO);
 
 	device_set_desc(dev, "Flattened device tree simple bus");
+
+	sc = device_get_softc(dev);
+	sc->sc_start_va = FDT_SIMPLEBUS_VA;
+
 	return (BUS_PROBE_DEFAULT);
 }
 
@@ -240,7 +245,6 @@
 	}
 	debugf("start = %lx, size = %lx\n", start, size);
 	sc->sc_start_pa = start;
-	sc->sc_start_va = CCSRBAR_VA;
 	sc->sc_size = size;
 
 	/*
@@ -387,7 +391,13 @@
 
 	debugf("intr config: irq = %d, trig = %d, pol = %d\n", irq, trig, pol);
 
+#if defined(__powerpc__)
 	err = powerpc_config_intr(irq, trig, pol);
+#elif defined(__arm__)
+	arm_setup_irqhandler(device_get_nameunit(child), filter, ihand, arg,
+	    irq, flags, cookiep);
+	return (0);
+#endif
 	if (err)
 		return (err);
 

==== //depot/projects/fdt/sys/dev/uart/uart_cpu_powerpc.c#3 (text) ====

@@ -40,7 +40,7 @@
 #include <sys/bus.h>
 #include <dev/fdt/fdt_common.h>
 #include <dev/ofw/ofw_bus.h>
-#include <machine/vmparam.h>
+#include <machine/fdt.h>
 #endif
 
 #include <dev/ofw/openfirm.h>
@@ -92,45 +92,6 @@
 }
 
 #ifdef FDT
-/*
- * Since ofw_bus_is_compatible() cannot be used at this early stage, we need
- * a similar function locally. Note the buffer has to be on the stack since
- * malloc() is not yet available.
- */
-static int
-fdt_is_compatible(phandle_t node, const char *compatstr)
-{
-#define FDT_COMPAT_LEN 255
-	char *buf[FDT_COMPAT_LEN];
-	char *compat;
-	int len, onelen, l, rv;
-
-	if ((len = OF_getproplen(node, "compatible")) <= 0)
-		return (0);
-
-	compat = (char *)&buf;
-	bzero(compat, FDT_COMPAT_LEN);
-
-	if (OF_getprop(node, "compatible", compat, len) < 0)
-		return (0);
-
-	onelen = strlen(compatstr);
-	rv = 0;
-	while (len > 0) {
-		if (strncasecmp(compat, compatstr, onelen) == 0) {
-			/* Found it. */
-			rv = 1;
-			break;
-		}
-		/* Slide to the next sub-string. */
-		l = strlen(compat) + 1;
-		compat += l;
-		len -= l;
-	}
-
-	return (rv);
-}
-
 static int
 fdt_uart_addr(phandle_t node, bus_space_tag_t *tag, bus_space_handle_t *handle)
 {
@@ -179,8 +140,7 @@
 	rv = fdt_data_to_res(prop, par_addr_cells, par_size_cells,
 	    &start, &size);
 
-	/* XXX this is an MPC85XX specific hack and needs to go away. */
-	start += CCSRBAR_VA;
+	start += FDT_SIMPLEBUS_VA;
 
 	rv = bus_space_map(*tag, start, size, 0, handle);
 	if (rv)


More information about the p4-projects mailing list