svn commit: r302340 - head/sys/powerpc/mpc85xx

Justin Hibbits jhibbits at FreeBSD.org
Tue Jul 5 06:14:25 UTC 2016


Author: jhibbits
Date: Tue Jul  5 06:14:23 2016
New Revision: 302340
URL: https://svnweb.freebsd.org/changeset/base/302340

Log:
  Unbreak the LBC driver, broken with the large RMan and 36-bit physical address changes.
  
  Remove the use of fdt_data_to_res(), and instead construct the resources
  manually.  Additionally, avoid the 32-bit size limitation of fdt_data_get(), by
  building physical addresses manually from the lbc ranges property.
  
  Approved by:	re@(gjb)

Modified:
  head/sys/powerpc/mpc85xx/lbc.c

Modified: head/sys/powerpc/mpc85xx/lbc.c
==============================================================================
--- head/sys/powerpc/mpc85xx/lbc.c	Tue Jul  5 01:29:24 2016	(r302339)
+++ head/sys/powerpc/mpc85xx/lbc.c	Tue Jul  5 06:14:23 2016	(r302340)
@@ -362,17 +362,17 @@ static int
 fdt_lbc_reg_decode(phandle_t node, struct lbc_softc *sc,
     struct lbc_devinfo *di)
 {
-	u_long start, end, count;
+	rman_res_t start, end, count;
 	pcell_t *reg, *regptr;
 	pcell_t addr_cells, size_cells;
 	int tuple_size, tuples;
-	int i, rv, bank;
+	int i, j, rv, bank;
 
 	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);
+	tuples = OF_getencprop_alloc(node, "reg", tuple_size, (void **)&reg);
 	debugf("addr_cells = %d, size_cells = %d\n", addr_cells, size_cells);
 	debugf("tuples = %d, tuple size = %d\n", tuples, tuple_size);
 	if (tuples <= 0)
@@ -387,11 +387,14 @@ fdt_lbc_reg_decode(phandle_t node, struc
 		reg += 1;
 
 		/* Get address/size. */
-		rv = fdt_data_to_res(reg, addr_cells - 1, size_cells, &start,
-		    &count);
-		if (rv != 0) {
-			resource_list_free(&di->di_res);
-			goto out;
+		start = count = 0;
+		for (j = 0; j < addr_cells; j++) {
+			start <<= 32;
+			start |= reg[j];
+		}
+		for (j = 0; j < size_cells; j++) {
+			count <<= 32;
+			count |= reg[addr_cells + j - 1];
 		}
 		reg += addr_cells - 1 + size_cells;
 
@@ -399,15 +402,14 @@ fdt_lbc_reg_decode(phandle_t node, struc
 		start = sc->sc_banks[bank].kva + start;
 		end = start + count - 1;
 
-		debugf("reg addr bank = %d, start = %lx, end = %lx, "
-		    "count = %lx\n", bank, start, end, count);
+		debugf("reg addr bank = %d, start = %jx, end = %jx, "
+		    "count = %jx\n", bank, start, end, count);
 
 		/* Use bank (CS) cell as rid. */
 		resource_list_add(&di->di_res, SYS_RES_MEMORY, bank, start,
 		    end, count);
 	}
 	rv = 0;
-out:
 	OF_prop_free(regptr);
 	return (rv);
 }
@@ -442,13 +444,14 @@ lbc_attach(device_t dev)
 	struct lbc_softc *sc;
 	struct lbc_devinfo *di;
 	struct rman *rm;
-	u_long offset, start, size;
+	uintmax_t offset, size;
+	vm_paddr_t start;
 	device_t cdev;
 	phandle_t node, child;
 	pcell_t *ranges, *rangesptr;
 	int tuple_size, tuples;
 	int par_addr_cells;
-	int bank, error, i;
+	int bank, error, i, j;
 
 	sc = device_get_softc(dev);
 	sc->sc_dev = dev;
@@ -540,7 +543,7 @@ lbc_attach(device_t dev)
 	tuple_size = sizeof(pcell_t) * (sc->sc_addr_cells + par_addr_cells +
 	    sc->sc_size_cells);
 
-	tuples = OF_getprop_alloc(node, "ranges", tuple_size,
+	tuples = OF_getencprop_alloc(node, "ranges", tuple_size,
 	    (void **)&ranges);
 	if (tuples < 0) {
 		device_printf(dev, "could not retrieve 'ranges' property\n");
@@ -558,7 +561,7 @@ lbc_attach(device_t dev)
 	for (i = 0; i < tuples; i++) {
 
 		/* The first cell is the bank (chip select) number. */
-		bank = fdt_data_get((void *)ranges, 1);
+		bank = fdt_data_get(ranges, 1);
 		if (bank < 0 || bank > LBC_DEV_MAX) {
 			device_printf(dev, "bank out of range: %d\n", bank);
 			error = ERANGE;
@@ -570,17 +573,25 @@ lbc_attach(device_t dev)
 		 * Remaining cells of the child address define offset into
 		 * this CS.
 		 */
-		offset = fdt_data_get((void *)ranges, sc->sc_addr_cells - 1);
-		ranges += sc->sc_addr_cells - 1;
+		offset = 0;
+		for (j = 0; j < sc->sc_addr_cells - 1; j++) {
+			offset <<= sizeof(pcell_t) * 8;
+			offset |= *ranges;
+			ranges++;
+		}
 
 		/* Parent bus start address of this bank. */
-		start = fdt_data_get((void *)ranges, par_addr_cells);
-		ranges += par_addr_cells;
+		start = 0;
+		for (j = 0; j < par_addr_cells; j++) {
+			start <<= sizeof(pcell_t) * 8;
+			start |= *ranges;
+			ranges++;
+		}
 
 		size = fdt_data_get((void *)ranges, sc->sc_size_cells);
 		ranges += sc->sc_size_cells;
-		debugf("bank = %d, start = %lx, size = %lx\n", bank,
-		    start, size);
+		debugf("bank = %d, start = %jx, size = %jx\n", bank,
+		    (uintmax_t)start, size);
 
 		sc->sc_banks[bank].addr = start + offset;
 		sc->sc_banks[bank].size = size;


More information about the svn-src-all mailing list