Introduce ofw_bus_reg_to_rl() to replace part of common bus code

Instead of reusing the same reg parsing code, create one, common function
that puts reg contents to the resource list. Address cells and size cells
are passed rather than acquired here so that any bus can have different
default values.

Obtained from:   Semihalf
Reviewed by:     andrew, ian, nwhitehorn
Sponsored by:    The FreeBSD Foundation
This commit is contained in:
Zbigniew Bodek 2015-01-13 00:00:09 +00:00
parent bacaccae69
commit 4b3d916086
4 changed files with 52 additions and 61 deletions

View File

@ -253,10 +253,6 @@ simplebus_setup_dinfo(device_t dev, phandle_t node)
{ {
struct simplebus_softc *sc; struct simplebus_softc *sc;
struct simplebus_devinfo *ndi; struct simplebus_devinfo *ndi;
uint32_t *reg;
uint64_t phys, size;
int i, j, k;
int nreg;
sc = device_get_softc(dev); sc = device_get_softc(dev);
@ -267,32 +263,7 @@ simplebus_setup_dinfo(device_t dev, phandle_t node)
} }
resource_list_init(&ndi->rl); resource_list_init(&ndi->rl);
nreg = OF_getencprop_alloc(node, "reg", sizeof(*reg), (void **)&reg); ofw_bus_reg_to_rl(dev, node, sc->acells, sc->scells, &ndi->rl);
if (nreg == -1)
nreg = 0;
if (nreg % (sc->acells + sc->scells) != 0) {
if (bootverbose)
device_printf(dev, "Malformed reg property on <%s>\n",
ndi->obdinfo.obd_name);
nreg = 0;
}
for (i = 0, k = 0; i < nreg; i += sc->acells + sc->scells, k++) {
phys = size = 0;
for (j = 0; j < sc->acells; j++) {
phys <<= 32;
phys |= reg[i + j];
}
for (j = 0; j < sc->scells; j++) {
size <<= 32;
size |= reg[i + sc->acells + j];
}
resource_list_add(&ndi->rl, SYS_RES_MEMORY, k,
phys, phys + size - 1, size);
}
free(reg, M_OFWPROP);
ofw_bus_intr_to_rl(dev, node, &ndi->rl); ofw_bus_intr_to_rl(dev, node, &ndi->rl);
return (ndi); return (ndi);

View File

@ -369,6 +369,54 @@ ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz,
return (0); return (0);
} }
int
ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
struct resource_list *rl)
{
uint64_t phys, size;
ssize_t i, j, rid, nreg, ret;
uint32_t *reg;
char *name;
/*
* This may be just redundant when having ofw_bus_devinfo
* but makes this routine independent of it.
*/
ret = OF_getencprop_alloc(node, "name", sizeof(*name), (void **)&name);
if (ret == -1)
name = NULL;
ret = OF_getencprop_alloc(node, "reg", sizeof(*reg), (void **)&reg);
nreg = (ret == -1) ? 0 : ret;
if (nreg % (acells + scells) != 0) {
if (bootverbose)
device_printf(dev, "Malformed reg property on <%s>\n",
(name == NULL) ? "unknown" : name);
nreg = 0;
}
for (i = 0, rid = 0; i < nreg; i += acells + scells, rid++) {
phys = size = 0;
for (j = 0; j < acells; j++) {
phys <<= 32;
phys |= reg[i + j];
}
for (j = 0; j < scells; j++) {
size <<= 32;
size |= reg[i + acells + j];
}
/* Skip the dummy reg property of glue devices like ssm(4). */
if (size != 0)
resource_list_add(rl, SYS_RES_MEMORY, rid,
phys, phys + size - 1, size);
}
free(name, M_OFWPROP);
free(reg, M_OFWPROP);
return (0);
}
int int
ofw_bus_intr_to_rl(device_t dev, phandle_t node, struct resource_list *rl) ofw_bus_intr_to_rl(device_t dev, phandle_t node, struct resource_list *rl)
{ {

View File

@ -73,6 +73,8 @@ int ofw_bus_search_intrmap(void *, int, void *, int, void *, int, void *,
void *, void *, int, phandle_t *); void *, void *, int, phandle_t *);
/* Routines for parsing device-tree data into resource lists. */ /* Routines for parsing device-tree data into resource lists. */
int ofw_bus_reg_to_rl(device_t, phandle_t, pcell_t, pcell_t,
struct resource_list *);
int ofw_bus_intr_to_rl(device_t, phandle_t, struct resource_list *); int ofw_bus_intr_to_rl(device_t, phandle_t, struct resource_list *);
/* Helper to get device status property */ /* Helper to get device status property */

View File

@ -442,10 +442,6 @@ ofwbus_setup_dinfo(device_t dev, phandle_t node)
struct ofwbus_softc *sc; struct ofwbus_softc *sc;
struct ofwbus_devinfo *ndi; struct ofwbus_devinfo *ndi;
const char *nodename; const char *nodename;
uint32_t *reg;
uint64_t phys, size;
int i, j, rid;
int nreg;
sc = device_get_softc(dev); sc = device_get_softc(dev);
@ -462,33 +458,7 @@ ofwbus_setup_dinfo(device_t dev, phandle_t node)
} }
resource_list_init(&ndi->ndi_rl); resource_list_init(&ndi->ndi_rl);
nreg = OF_getencprop_alloc(node, "reg", sizeof(*reg), (void **)&reg); ofw_bus_reg_to_rl(dev, node, sc->acells, sc->scells, &ndi->ndi_rl);
if (nreg == -1)
nreg = 0;
if (nreg % (sc->acells + sc->scells) != 0) {
if (bootverbose)
device_printf(dev, "Malformed reg property on <%s>\n",
nodename);
nreg = 0;
}
for (i = 0, rid = 0; i < nreg; i += sc->acells + sc->scells, rid++) {
phys = size = 0;
for (j = 0; j < sc->acells; j++) {
phys <<= 32;
phys |= reg[i + j];
}
for (j = 0; j < sc->scells; j++) {
size <<= 32;
size |= reg[i + sc->acells + j];
}
/* Skip the dummy reg property of glue devices like ssm(4). */
if (size != 0)
resource_list_add(&ndi->ndi_rl, SYS_RES_MEMORY, rid,
phys, phys + size - 1, size);
}
free(reg, M_OFWPROP);
ofw_bus_intr_to_rl(dev, node, &ndi->ndi_rl); ofw_bus_intr_to_rl(dev, node, &ndi->ndi_rl);
return (ndi); return (ndi);