From 3720bcbd30f30d6094fb68f4fd070f0bb5489398 Mon Sep 17 00:00:00 2001 From: jhibbits Date: Tue, 5 Jul 2016 06:14:23 +0000 Subject: 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) --- sys/powerpc/mpc85xx/lbc.c | 53 ++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 21 deletions(-) (limited to 'sys/powerpc/mpc85xx/lbc.c') 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 **)®); + tuples = OF_getencprop_alloc(node, "reg", tuple_size, (void **)®); 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; -- cgit v1.1