PERFORCE change 172675 for review

Rafal Jaworowski raj at FreeBSD.org
Wed Jan 6 21:54:05 UTC 2010


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

Change 172675 by raj at raj_fdt on 2010/01/06 21:53:13

	Refactor simplebus and MPC85XX definitions.
	
	- Merge sys/powerpc/include/ocpbus.h into mpc85xx.h (this is the first
	  step towards recycling ocbush.h)
	- Factor out a fdt_common.c from simplebus.c so that routines could be
	  used by other FDT drivers as well (the upcoming LBC rework)
	- Imrove fdtbus driver a bit.
	- Temporarily disconnect LBC driver from the build.

Affected files ...

.. //depot/projects/fdt/sys/conf/files.powerpc#10 edit
.. //depot/projects/fdt/sys/powerpc/booke/machdep.c#4 edit
.. //depot/projects/fdt/sys/powerpc/booke/platform_bare.c#2 edit
.. //depot/projects/fdt/sys/powerpc/mpc85xx/atpic.c#2 edit
.. //depot/projects/fdt/sys/powerpc/mpc85xx/fdt_common.c#1 add
.. //depot/projects/fdt/sys/powerpc/mpc85xx/fdt_common.h#1 add
.. //depot/projects/fdt/sys/powerpc/mpc85xx/fdtbus.c#4 edit
.. //depot/projects/fdt/sys/powerpc/mpc85xx/i2c.c#3 edit
.. //depot/projects/fdt/sys/powerpc/mpc85xx/mpc85xx.h#2 edit
.. //depot/projects/fdt/sys/powerpc/mpc85xx/ocpbus.c#2 edit
.. //depot/projects/fdt/sys/powerpc/mpc85xx/simplebus.c#5 edit

Differences ...

==== //depot/projects/fdt/sys/conf/files.powerpc#10 (text+ko) ====

@@ -119,10 +119,11 @@
 powerpc/mpc85xx/atpic.c		optional	mpc85xx isa
 powerpc/mpc85xx/ds1553_bus_lbc.c	optional	ds1553 mpc85xx
 powerpc/mpc85xx/ds1553_core.c	optional	ds1553
+powerpc/mpc85xx/fdt_common.c	optional	fdt
 powerpc/mpc85xx/fdtbus.c	optional	fdt
 powerpc/mpc85xx/i2c.c		optional	iicbus fdt
 powerpc/mpc85xx/isa.c		optional	mpc85xx isa
-powerpc/mpc85xx/lbc.c		optional	mpc85xx
+#powerpc/mpc85xx/lbc.c		optional	mpc85xx
 powerpc/mpc85xx/mpc85xx.c	optional	mpc85xx
 powerpc/mpc85xx/nexus.c		optional	mpc85xx
 powerpc/mpc85xx/ocpbus.c	optional	mpc85xx

==== //depot/projects/fdt/sys/powerpc/booke/machdep.c#4 (text+ko) ====

@@ -137,7 +137,6 @@
 
 #include <dev/ofw/openfirm.h>
 
-#include <powerpc/mpc85xx/ocpbus.h>
 #include <powerpc/mpc85xx/mpc85xx.h>
 
 #ifdef DDB

==== //depot/projects/fdt/sys/powerpc/booke/platform_bare.c#2 (text+ko) ====

@@ -46,7 +46,6 @@
 #include <machine/vmparam.h>
 
 #include <powerpc/mpc85xx/mpc85xx.h>
-#include <powerpc/mpc85xx/ocpbus.h>
 
 #include "platform_if.h"
 

==== //depot/projects/fdt/sys/powerpc/mpc85xx/atpic.c#2 (text+ko) ====

@@ -39,7 +39,7 @@
 #include <machine/intr_machdep.h>
 #include <machine/pio.h>
 
-#include <powerpc/mpc85xx/ocpbus.h>
+#include <powerpc/mpc85xx/mpc85xx.h>
 
 #include <dev/ic/i8259.h>
 

==== //depot/projects/fdt/sys/powerpc/mpc85xx/fdtbus.c#4 (text+ko) ====

@@ -43,6 +43,7 @@
 
 #include <machine/intr_machdep.h>
 
+#include "fdt_common.h"
 #include "ofw_bus_if.h"
 
 #define DEBUG
@@ -60,10 +61,14 @@
 extern struct bus_space bs_be_tag;
 
 struct fdtbus_devinfo {
-	phandle_t	di_node;
-	const char     	*di_name;
-	const char     	*di_type;
-	const char     	*di_compat;
+	phandle_t		di_node;
+	char			*di_name;
+	char			*di_type;
+	char			*di_compat;
+	struct resource_list	di_res;
+
+	/* Interrupts sense-level info for this device */
+	struct sense_level	di_intr_sl[DI_MAX_INTR_NUM];
 };
 
 struct fdtbus_softc {
@@ -77,6 +82,7 @@
 static int fdtbus_probe(device_t);
 static int fdtbus_attach(device_t);
 
+static int fdtbus_print_child(device_t, device_t);
 static struct resource *fdtbus_alloc_resource(device_t, device_t, int,
     int *, u_long, u_long, u_long, u_int);
 static int fdtbus_release_resource(device_t, device_t, int, int,
@@ -113,6 +119,7 @@
 	DEVMETHOD(device_resume,	bus_generic_resume),
 
 	/* Bus interface */
+	DEVMETHOD(bus_print_child,	fdtbus_print_child),
 	DEVMETHOD(bus_alloc_resource,	fdtbus_alloc_resource),
 	DEVMETHOD(bus_release_resource,	fdtbus_release_resource),
 	DEVMETHOD(bus_activate_resource, fdtbus_activate_resource),
@@ -143,7 +150,7 @@
 fdtbus_probe(device_t dev)
 {
 
-	device_set_desc(dev, "FDTbus");
+	device_set_desc(dev, "FDT main bus");
 	if (!bootverbose)
 		device_quiet(dev);
 	return (BUS_PROBE_DEFAULT);
@@ -203,8 +210,6 @@
 		return (error);
 	}
 
-	debugf("rmans initialized\n");
-
 	/*
 	 * Walk the FDT root node and add top-level devices as our children.
 	 */
@@ -214,6 +219,16 @@
 	return (bus_generic_attach(dev));
 }
 
+static int
+fdtbus_print_child(device_t bus, device_t child)
+{
+	int rv;
+
+	rv = bus_print_child_header(bus, child);
+	rv += printf("\n");
+	return (rv);
+}
+
 /*
  * These FDT nodes do not need a corresponding newbus device object.
  */
@@ -223,6 +238,21 @@
 	NULL
 };
 
+static void
+newbus_device_destroy(device_t dev)
+{
+	struct fdtbus_devinfo *di;
+
+	di = device_get_ivars(dev);
+
+	free(di->di_name, M_OFWPROP);
+	free(di->di_type, M_OFWPROP);
+	free(di->di_compat, M_OFWPROP);
+
+	resource_list_free(&di->di_res);
+	free(di, M_FDTBUS);
+}
+
 static device_t
 newbus_device_from_fdt_node(device_t parent, phandle_t node)
 {
@@ -249,8 +279,33 @@
 		di->di_name = name;
 		di->di_type = type;
 		di->di_compat = compat;
-		device_set_ivars(child, di);
-		debugf("added child name='%s', node=%p\n", name, (void *)node);
+
+		resource_list_init(&di->di_res);
+
+		/*
+		 * 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)) {
+			device_printf(child, "could not process 'reg' "
+			    "property\n");
+			newbus_device_destroy(child);
+			child = NULL;
+		}
+
+		if (fdt_intr_to_rl(node, &di->di_res, di->di_intr_sl)) {
+			device_printf(child, "could not process 'interrupts' "
+			    "property\n");
+			newbus_device_destroy(child);
+			child = NULL;
+		}
+
+		if (child != NULL) {
+			device_set_ivars(child, di);
+			debugf("added child name='%s', node=%p\n", name,
+			    (void *)node);
+		}
 	} else {
 		free(name, M_OFWPROP);
 		free(type, M_OFWPROP);
@@ -267,8 +322,32 @@
 	struct fdtbus_softc *sc;
 	struct resource *res;
 	struct rman *rm;
+	struct fdtbus_devinfo *di;
+	struct resource_list_entry *rle;
 	int needactivate;
 
+	/*
+	 * Request for the default allocation with a given rid: use resource
+	 * list stored in the local device info.
+	 */
+	if ((start == 0UL) && (end == ~0UL)) {
+		if ((di = device_get_ivars(child)) == NULL)
+			return (NULL);
+
+		if (type == SYS_RES_IOPORT)
+			type = SYS_RES_MEMORY;
+
+		rle = resource_list_find(&di->di_res, type, *rid);
+		if (rle == NULL) {
+			device_printf(bus, "no default resources for "
+			    "rid = %d, type = %d\n", *rid, type);
+			return (NULL);
+		}
+		start = rle->start;
+		end = rle->end;
+		count = rle->count;
+	}
+
 	sc = device_get_softc(bus);
 
 	needactivate = flags & RF_ACTIVE;

==== //depot/projects/fdt/sys/powerpc/mpc85xx/i2c.c#3 (text+ko) ====

@@ -36,7 +36,6 @@
 
 #include <machine/bus.h>
 #include <machine/resource.h>
-#include <machine/ocpbus.h>
 #include <sys/rman.h>
 
 #include <sys/lock.h>

==== //depot/projects/fdt/sys/powerpc/mpc85xx/mpc85xx.h#2 (text+ko) ====

@@ -1,5 +1,6 @@
 /*-
  * Copyright (C) 2008 Semihalf, Rafal Jaworowski
+ * Copyright 2006 by Juniper Networks.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -29,6 +30,109 @@
 #ifndef _MPC85XX_H_
 #define _MPC85XX_H_
 
+/*
+ * Configuration control and status registers
+ */
+#define	OCP85XX_CCSRBAR		(CCSRBAR_VA + 0x0)
+#define	OCP85XX_BPTR		(CCSRBAR_VA + 0x20)
+
+/*
+ * E500 Coherency Module registers
+ */
+#define	OCP85XX_EEBPCR		(CCSRBAR_VA + 0x1010)
+
+/*
+ * Local access registers
+ */
+#define	OCP85XX_LAWBAR(n)	(CCSRBAR_VA + 0xc08 + 0x20 * (n))
+#define	OCP85XX_LAWSR(n)	(CCSRBAR_VA + 0xc10 + 0x20 * (n))
+
+#define	OCP85XX_TGTIF_PCI0	2
+#define	OCP85XX_TGTIF_PCI1	1
+#define	OCP85XX_TGTIF_PCI2	0
+#if 0
+#define	OCP85XX_TGTIF_PCI0	0
+#define	OCP85XX_TGTIF_PCI1	1
+#define	OCP85XX_TGTIF_PCI2	2
+#endif
+
+#define	OCP85XX_TGTIF_LBC	4
+#define	OCP85XX_TGTIF_RAM_INTL	11
+#define	OCP85XX_TGTIF_RIO	12
+#define	OCP85XX_TGTIF_RAM1	15
+#define	OCP85XX_TGTIF_RAM2	22
+
+/*
+ * L2 cache registers
+ */
+#define OCP85XX_L2CTL		(CCSRBAR_VA + 0x20000)
+
+/*
+ * Power-On Reset configuration
+ */
+#define	OCP85XX_PORDEVSR	(CCSRBAR_VA + 0xe000c)
+#define OCP85XX_PORDEVSR_IO_SEL	0x00780000
+#define OCP85XX_PORDEVSR_IO_SEL_SHIFT 19
+
+#define	OCP85XX_PORDEVSR2	(CCSRBAR_VA + 0xe0014)
+
+#define	OCP85XX_DEVDISR		(CCSRBAR_VA + 0xe0070)
+#define	OCP85XX_DEVDISR_PCIE0	0x20000000
+#define	OCP85XX_DEVDISR_PCIE1	0x04000000
+#define	OCP85XX_DEVDISR_PCIE2	0x02000000
+
+/*
+ * Status Registers.
+ */
+#define	OCP85XX_RSTCR		(CCSRBAR_VA + 0xe00b0)
+
+/*
+ * OCP Bus Definitions
+ */
+#define	OCP85XX_I2C0_OFF	0x03000
+#define	OCP85XX_I2C1_OFF	0x03100
+#define	OCP85XX_I2C_SIZE	0x16
+#define	OCP85XX_UART0_OFF	0x04500
+#define	OCP85XX_UART1_OFF	0x04600
+#define	OCP85XX_UART_SIZE	0x10
+#define	OCP85XX_LBC_OFF		0x05000
+#define	OCP85XX_LBC_SIZE	0x1000
+
+#define	OCP85XX_PCI0_OFF	0x0A000
+#define	OCP85XX_PCI1_OFF	0x09000
+#define	OCP85XX_PCI2_OFF	0x08000
+#if 0
+#define	OCP85XX_PCI0_OFF	0x08000
+#define	OCP85XX_PCI1_OFF	0x09000
+#define	OCP85XX_PCI2_OFF	0x0A000
+#endif
+
+#define	OCP85XX_PCI_SIZE	0x1000
+#define	OCP85XX_TSEC0_OFF	0x24000
+#define	OCP85XX_TSEC1_OFF	0x25000
+#define	OCP85XX_TSEC2_OFF	0x26000
+#define	OCP85XX_TSEC3_OFF	0x27000
+#define	OCP85XX_TSEC_SIZE	0x1000
+#define	OCP85XX_OPENPIC_OFF	0x40000
+#define	OCP85XX_OPENPIC_SIZE	0x200B4
+#define	OCP85XX_QUICC_OFF	0x80000
+#define	OCP85XX_QUICC_SIZE	0x20000
+#define	OCP85XX_SEC_OFF		0x30000
+#define	OCP85XX_SEC_SIZE	0x10000
+
+/*
+ * PIC definitions
+ */
+#define	ISA_IRQ_START	0
+#define	PIC_IRQ_START	(ISA_IRQ_START + 16)
+
+#define	ISA_IRQ(n)	(ISA_IRQ_START + (n))
+#define	PIC_IRQ_EXT(n)	(PIC_IRQ_START + (n))
+#define	PIC_IRQ_INT(n)	(PIC_IRQ_START + 16 + (n))
+
+/*
+ * Prototypes.
+ */
 uint32_t ccsr_read4(uintptr_t addr);
 void ccsr_write4(uintptr_t addr, uint32_t val);
 int law_enable(int trgt, u_long addr, u_long size);

==== //depot/projects/fdt/sys/powerpc/mpc85xx/ocpbus.c#2 (text+ko) ====

@@ -45,7 +45,6 @@
 #include <machine/vmparam.h>
 #include <machine/bootinfo.h>
 
-#include <powerpc/mpc85xx/ocpbus.h>
 #include <powerpc/mpc85xx/mpc85xx.h>
 
 #include "pic_if.h"

==== //depot/projects/fdt/sys/powerpc/mpc85xx/simplebus.c#5 (text+ko) ====

@@ -48,7 +48,7 @@
 
 #include "ofw_bus_if.h"
 
-#include "../../contrib/dtc/libfdt/libfdt_env.h"
+#include "fdt_common.h"
 
 #define DEBUG
 #undef DEBUG
@@ -70,27 +70,14 @@
 	u_long	sc_size;
 };
 
-struct sense_level {
-	enum intr_trigger	trig;
-	enum intr_polarity	pol;
-};
-
-#define DI_MAX_INTR_NUM	8
-
 struct simplebus_devinfo {
 	struct ofw_bus_devinfo	di_ofw;
 	struct resource_list	di_res;
 
-	/* Interrupt-parent phandle */
-	phandle_t		di_intr_par;
-	int			di_intr_cells;
-
 	/* Interrupts sense-level info for this device */
 	struct sense_level	di_intr_sl[DI_MAX_INTR_NUM];
-	int			di_intr_num;
 };
 
-
 /*
  * Prototypes.
  */
@@ -155,371 +142,30 @@
 {
 
 	if (ofw_bus_is_compatible(dev, "simple-bus")) {
-		device_set_desc(dev, "Flattened Device Tree simple bus");
+		device_set_desc(dev, "Flattened device tree simple bus");
 		return (BUS_PROBE_DEFAULT);
 	}
 
 	return (ENXIO);
 }
 
-static int
-fdt_parent_addr_cells(phandle_t node)
-{
-	pcell_t addr_cells;
-
-	/* Find out #address-cells of the superior bus. */
-	if (OF_searchprop(node, "#address-cells", &addr_cells,
-	    sizeof(addr_cells)) <= 0)
-		addr_cells = 1;
-
-	return ((int)addr_cells);
-}
-
-static void
-fdt_ranges_dump(pcell_t *ranges, int tuples, int par_addr_cells,
-    int this_addr_cells, int this_size_cells)
-{
-#ifdef DEBUG
-	int i, n;
-
-	for (i = 0; i < tuples; i++) {
-		printf("par  addr = ");
-		for (n = 0; n < par_addr_cells; n++)
-			printf("%x ", ranges[n]);
-		printf("\n");
-
-		printf("this addr = ");
-		for (; n < par_addr_cells + this_addr_cells; n++)
-			printf("%x ", ranges[n]);
-		printf("\n");
-
-		printf("this size = ");
-		for (; n < par_addr_cells + this_addr_cells + this_size_cells;
-		    n++)
-			printf("%x ", ranges[n]);
-		printf("\n");
-	}
-#endif
-}
-
-static int
-fdt_data_verify(void *data, int cells)
-{
-	uint64_t d64;
-
-	if (cells > 1) {
-		d64 = fdt64_to_cpu(*((uint64_t *)data));
-		if (((d64 > 32) & 0xffffffffull) != 0)
-			return (ERANGE);
-	}
-
-	return (0);
-}
-
-static u_long
-fdt_data_get(void *data, int cells)
-{
-
-	if (cells == 1)
-		return (fdt32_to_cpu(*((uint32_t *)data)));
-
-	return (fdt64_to_cpu(*((uint64_t *)data)));
-}
-
-static int
-fdt_ranges_verify(pcell_t *ranges, int tuples, int par_addr_cells,
-    int this_addr_cells, int this_size_cells)
-{
-	int i, rv, ulsz;
-
-	if (par_addr_cells > 2 || this_addr_cells > 2 || this_size_cells > 2)
-		return (ERANGE);
-
-	/*
-	 * This is the max size the resource manager can handle for addresses
-	 * and sizes.
-	 */
-	ulsz = sizeof(u_long);
-	if (par_addr_cells <= ulsz && this_addr_cells <= ulsz &&
-	    this_size_cells <= ulsz)
-		/* We can handle everything */
-		return (0);
-
-	rv = 0;
-	for (i = 0; i < tuples; i++) {
-
-		if (fdt_data_verify((void *)ranges, par_addr_cells))
-			goto err;
-		ranges += par_addr_cells;
-
-		if (fdt_data_verify((void *)ranges, this_addr_cells))
-			goto err;
-		ranges += this_addr_cells;
-
-		if (fdt_data_verify((void *)ranges, this_size_cells))
-			goto err;
-		ranges += this_size_cells;
-	}
-
-	return (0);
-
-err:
-	printf("using address range >%d-bit not supported\n", ulsz * 8);
-	return (ERANGE);
-}
-
-static int
-simplebus_add_reg(phandle_t node, struct simplebus_devinfo *di,
-    struct simplebus_softc *sc)
-{
-	pcell_t *reg;
-	u_long start, end, count;
-	int tuple_size, tuples;
-	int i;
-
-	/* XXX free reg prop? */
-	tuple_size = sizeof(pcell_t) * (sc->sc_addr_cells + sc->sc_size_cells);
-	tuples = OF_getprop_alloc(node, "reg", tuple_size, (void **)&reg);
-	if (tuples <= 0)
-		/* No 'reg' property in this node. */
-		return (0);
-
-	for (i = 0; i < tuples; i++) {
-		/* Address portion. */
-		if (fdt_data_verify((void *)reg, sc->sc_addr_cells)) {
-			debugf("tuple #%d: unsupported addr value in 'reg' "
-			    "property\n", i);
-			goto err;
-		}
-		start = fdt_data_get((void *)reg, sc->sc_addr_cells);
-		reg += sc->sc_addr_cells;
-
-		/* Size portion. */
-		if (fdt_data_verify((void *)reg, sc->sc_size_cells)) {
-			debugf("tuple #%d: unsupported size value in 'reg' "
-			    "property\n", i);
-			goto err;
-		}
-		count = fdt_data_get((void *)reg, sc->sc_size_cells);
-		reg += sc->sc_size_cells;
-
-		/* Calculate address range relative to simple-bus VA base. */
-		start = sc->sc_start_va + start;
-		end = start + count - 1;
-
-		debugf("reg addr start = %lx, end = %lx, count = %lx\n", start,
-		    end, count);
-
-		if (end > sc->sc_start_va + sc->sc_size) {
-			debugf("end out of simple-bus range: %lx\n", end);
-			goto err;
-		}
-
-		resource_list_add(&di->di_res, SYS_RES_MEMORY, i, start, end,
-		    count);
-	}
-	return (0);
-
-err:
-	resource_list_free(&di->di_res);
-	return (ERANGE);
-}
-
-static int
-fdt_pic_decode_iic(phandle_t node, pcell_t *intr, int intr_cells,
-    int *interrupt, int *trig, int *pol)
-{
-
-	/* TODO */
-	return (ENXIO);
-}
-
-static int
-fdt_pic_decode_openpic(phandle_t node, pcell_t *intr, int intr_cells,
-    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];
-
-	if (intr_cells == 2)
-		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;
-		}
-	else {
-		*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 *,
-    int *);
-
-static fdt_pic_decode_t fdt_pic_table[] = {
-	&fdt_pic_decode_iic,
-	&fdt_pic_decode_openpic,
-	NULL
-};
-
-static int
-fdt_intr_decode(struct simplebus_devinfo *di, pcell_t *intr,
-    int *interrupt, int *trig, int *pol)
-{
-	fdt_pic_decode_t intr_decode;
-	int i, rv;
-
-	for (i = 0; fdt_pic_table[i] != NULL; i++) {
-
-		/* XXX check if pic_handle has interrupt-controller prop? */
-
-		intr_decode = fdt_pic_table[i];
-		rv = intr_decode(di->di_intr_par, intr, di->di_intr_cells,
-		    interrupt, trig, pol);
-
-		if (rv == 0)
-			/* This was recognized as our PIC and decoded. */
-			return (0);
-	}
-
-	return (ENXIO);
-}
-
-static int
-simplebus_add_one_intr(struct simplebus_devinfo *di, pcell_t *intr)
-{
-	int interrupt, trig, pol;
-	int intr_num;
-
-	intr_num = di->di_intr_num;
-
-	if (intr_num > DI_MAX_INTR_NUM) {
-		debugf("max intr num reached: %d\n", DI_MAX_INTR_NUM);
-		return (ENOMEM);
-	}
-
-	interrupt = trig = pol = 0;
-
-	if (fdt_intr_decode(di, intr, &interrupt, &trig, &pol) != 0)
-		return (ENXIO);
-
-	if (interrupt <= 0)
-		return (ERANGE);
-
-	debugf("decoded intr = %d, trig = %d, pol = %d\n", interrupt, trig,
-	    pol);
-
-	di->di_intr_sl[intr_num].trig = trig;
-	di->di_intr_sl[intr_num].pol = pol;
-
-	resource_list_add(&di->di_res, SYS_RES_IRQ, intr_num,
-	    interrupt, interrupt, 1);
-
-	di->di_intr_num++;
-
-	return (0);
-}
-
-static int
-simplebus_add_intr(phandle_t node, struct simplebus_devinfo *di)
-{
-	phandle_t intr_par;
-	ihandle_t iph;
-	pcell_t *intr;
-	pcell_t intr_cells;
-	int i, intr_num, rv;
-
-	if (OF_getproplen(node, "interrupts") <= 0)
-		/* Node does not have 'interrupts' property. */
-		return (0);
-
-	/*
-	 * Find #interrupt-cells of the interrupt domain.
-	 */
-	if (OF_getprop(node, "interrupt-parent", &iph, sizeof(iph)) <= 0) {
-		debugf("no intr-parent phandle\n");
-		intr_par = OF_parent(node);
-	} else
-		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_num = OF_getprop_alloc(node, "interrupts",
-	    intr_cells * sizeof(pcell_t), (void **)&intr);
-	if (intr_num <= 0)
-		return (ERANGE);
-
-	rv = 0;
-	di->di_intr_num = 0;
-	di->di_intr_par = intr_par;
-	di->di_intr_cells = intr_cells;
-	for (i = 0; i < intr_num; i++) {
-		rv = simplebus_add_one_intr(di, &intr[i * intr_cells]);
-		if (rv != 0) {
-			/* XXX resource_list_free(&di->di_res); ??? */
-			goto out;
-		}
-	}
-
-out:
-	free(intr, M_OFWPROP);
-	return (rv);
-}
-
 static void
 simplebus_fixup(phandle_t node)
 {
-	phandle_t cpus, child;
+	phandle_t cpus, child, root;
+	char *model;
 	pcell_t freq;
+	int len;
 
-	/* XXX this whole fixup should depend on 8555 SOC */
+	/* Fixup handling is platform specific. */
+	if ((root = OF_finddevice("/")) == 0)
+		panic("simplebus: no root node");
+	len = OF_getprop_alloc(root, "model", 1, (void **)&model);
+	if (len <= 0)
+		return;
+	if (!(strcmp(model, "fsl,MPC8572DS") == 0 ||
+	    strcmp(model, "MPC8555CDS") == 0))
+		goto out;
 
 	if ((cpus = OF_finddevice("/cpus")) == 0)
 		panic("simplebus: no /cpus node");
@@ -532,6 +178,8 @@
 		return;
 
 	OF_setprop(node, "bus-frequency", (void *)&freq, sizeof(freq));
+out:
+	free(model, M_OFWPROP);
 }
 
 static int
@@ -543,34 +191,19 @@
 	struct simplebus_devinfo *di;
 	struct simplebus_softc *sc;
 	phandle_t node, child;
-	pcell_t cell;
-	ssize_t prop_len;
-	int cell_size, tuple_size, tuples;
+	int tuple_size, tuples;
 	int par_addr_cells;
 
 	sc = device_get_softc(dev);
 	node = ofw_bus_get_node(dev);
-	cell_size = sizeof(cell);
+
+	if ((fdt_addrsize_cells(node, &sc->sc_addr_cells,
+	    &sc->sc_size_cells)) != 0)
+		return (ENXIO);
 
 	simplebus_fixup(node);
 
 	/*
-	 * Retrieve #{address,size}-cells.
-	 */
-	if (OF_getprop(node, "#address-cells", &cell, cell_size) < cell_size)
-		cell = 2;
-	sc->sc_addr_cells = (int)cell;
-
-	if (OF_getprop(node, "#size-cells", &cell, cell_size) < cell_size)
-		cell = 1;
-	sc->sc_size_cells = (int)cell;
-
-	if (sc->sc_addr_cells > 2 || sc->sc_size_cells > 2) {
-		device_printf(dev, "unsupported # of cells\n");
-		return (ERANGE);
-	}
-
-	/*
 	 * Process 'ranges' property.
 	 */
 	par_addr_cells = fdt_parent_addr_cells(node);
@@ -578,22 +211,16 @@
 		device_printf(dev, "unsupported parent #addr-cells\n");
 		return (ERANGE);
 	}
-	tuple_size = cell_size * (sc->sc_addr_cells + par_addr_cells +
+	tuple_size = sizeof(pcell_t) * (sc->sc_addr_cells + par_addr_cells +
 	    sc->sc_size_cells);
 
-	/* XXX free ranges prop? */
-	prop_len = OF_getprop_alloc(node, "ranges", 1, (void **)&ranges);
+	/* TODO free ranges prop */
+	tuples = OF_getprop_alloc(node, "ranges", tuple_size,
+	    (void **)&ranges);
 
 	start = 0;
 	size = 0;
-	if (prop_len >= 0) {
-
-		if (prop_len % tuple_size) {
-			device_printf(dev, "inconsistent 'ranges' property\n");
-			return (ENXIO);
-		}
-		tuples = prop_len / tuple_size;
-
+	if (tuples > 0) {
 		fdt_ranges_dump(ranges, tuples, par_addr_cells,
 		    sc->sc_addr_cells, sc->sc_size_cells);
 
@@ -631,14 +258,15 @@
 
 		resource_list_init(&di->di_res);
 
-		if (simplebus_add_reg(child, di, sc)) {
+		if (fdt_reg_to_rl(child, &di->di_res, sc->sc_start_va)) {
 			device_printf(dev, "could not process 'reg' "
 			    "property\n");
 			ofw_bus_gen_destroy_devinfo(&di->di_ofw);
 			free(di, M_SIMPLEBUS);
 			continue;
 		}
-		if (simplebus_add_intr(child, di)) {
+
+		if (fdt_intr_to_rl(child, &di->di_res, di->di_intr_sl)) {
 			device_printf(dev, "could not process 'interrupts' "
 			    "property\n");
 			resource_list_free(&di->di_res);


More information about the p4-projects mailing list