summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/mpc85xx/lbc.c
diff options
context:
space:
mode:
authorjhibbits <jhibbits@FreeBSD.org>2016-07-05 06:14:23 +0000
committerjhibbits <jhibbits@FreeBSD.org>2016-07-05 06:14:23 +0000
commit3720bcbd30f30d6094fb68f4fd070f0bb5489398 (patch)
treebe87953f94e6cec0faeaf4b443f04f0e9e574324 /sys/powerpc/mpc85xx/lbc.c
parent58667ff11c68ece556bfb71b54362c21beb187c9 (diff)
downloadFreeBSD-src-3720bcbd30f30d6094fb68f4fd070f0bb5489398.zip
FreeBSD-src-3720bcbd30f30d6094fb68f4fd070f0bb5489398.tar.gz
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)
Diffstat (limited to 'sys/powerpc/mpc85xx/lbc.c')
-rw-r--r--sys/powerpc/mpc85xx/lbc.c53
1 files changed, 32 insertions, 21 deletions
diff --git a/sys/powerpc/mpc85xx/lbc.c b/sys/powerpc/mpc85xx/lbc.c
index 2c5702b..576fe82 100644
--- a/sys/powerpc/mpc85xx/lbc.c
+++ b/sys/powerpc/mpc85xx/lbc.c
@@ -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, struct lbc_softc *sc,
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, struct lbc_softc *sc,
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;
OpenPOWER on IntegriCloud