summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/ofw
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-21 13:47:02 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:41 +0200
commitbcdce02d9bc8150e1d191ed5ca9da45b7604964a (patch)
tree3b2faf509db7672ee1fc98857736470be97e7ed8 /freebsd/sys/dev/ofw
parentUpdate to FreeBSD head 2018-04-01 (diff)
downloadrtems-libbsd-bcdce02d9bc8150e1d191ed5ca9da45b7604964a.tar.bz2
Update to FreeBSD head 2018-06-01
Git mirror commit fb63610a69b0eb7f69a201ba05c4c1a7a2739cf9. Update #3472.
Diffstat (limited to 'freebsd/sys/dev/ofw')
-rw-r--r--freebsd/sys/dev/ofw/ofw_bus_subr.c61
-rw-r--r--freebsd/sys/dev/ofw/ofw_bus_subr.h2
-rw-r--r--freebsd/sys/dev/ofw/ofw_fdt.c2
-rw-r--r--freebsd/sys/dev/ofw/openfirm.c63
-rw-r--r--freebsd/sys/dev/ofw/openfirm.h6
5 files changed, 97 insertions, 37 deletions
diff --git a/freebsd/sys/dev/ofw/ofw_bus_subr.c b/freebsd/sys/dev/ofw/ofw_bus_subr.c
index 8406988f..5038bb03 100644
--- a/freebsd/sys/dev/ofw/ofw_bus_subr.c
+++ b/freebsd/sys/dev/ofw/ofw_bus_subr.c
@@ -59,12 +59,12 @@ ofw_bus_gen_setup_devinfo(struct ofw_bus_devinfo *obd, phandle_t node)
if (obd == NULL)
return (ENOMEM);
/* The 'name' property is considered mandatory. */
- if ((OF_getprop_alloc(node, "name", 1, (void **)&obd->obd_name)) == -1)
+ if ((OF_getprop_alloc(node, "name", (void **)&obd->obd_name)) == -1)
return (EINVAL);
- OF_getprop_alloc(node, "compatible", 1, (void **)&obd->obd_compat);
- OF_getprop_alloc(node, "device_type", 1, (void **)&obd->obd_type);
- OF_getprop_alloc(node, "model", 1, (void **)&obd->obd_model);
- OF_getprop_alloc(node, "status", 1, (void **)&obd->obd_status);
+ OF_getprop_alloc(node, "compatible", (void **)&obd->obd_compat);
+ OF_getprop_alloc(node, "device_type", (void **)&obd->obd_type);
+ OF_getprop_alloc(node, "model", (void **)&obd->obd_model);
+ OF_getprop_alloc(node, "status", (void **)&obd->obd_status);
obd->obd_node = node;
return (0);
}
@@ -321,10 +321,10 @@ ofw_bus_setup_iinfo(phandle_t node, struct ofw_bus_iinfo *ii, int intrsz)
addrc = 2;
ii->opi_addrc = addrc * sizeof(pcell_t);
- ii->opi_imapsz = OF_getencprop_alloc(node, "interrupt-map", 1,
+ ii->opi_imapsz = OF_getencprop_alloc(node, "interrupt-map",
(void **)&ii->opi_imap);
if (ii->opi_imapsz > 0) {
- msksz = OF_getencprop_alloc(node, "interrupt-map-mask", 1,
+ msksz = OF_getencprop_alloc(node, "interrupt-map-mask",
(void **)&ii->opi_imapmsk);
/*
* Failure to get the mask is ignored; a full mask is used
@@ -451,7 +451,8 @@ ofw_bus_msimap(phandle_t node, uint16_t pci_rid, phandle_t *msi_parent,
int err, i;
/* TODO: This should be OF_searchprop_alloc if we had it */
- len = OF_getencprop_alloc(node, "msi-map", sizeof(*map), (void **)&map);
+ len = OF_getencprop_alloc_multi(node, "msi-map", sizeof(*map),
+ (void **)&map);
if (len < 0) {
if (msi_parent != NULL) {
*msi_parent = 0;
@@ -491,9 +492,9 @@ ofw_bus_msimap(phandle_t node, uint16_t pci_rid, phandle_t *msi_parent,
return (err);
}
-int
-ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
- struct resource_list *rl)
+static int
+ofw_bus_reg_to_rl_helper(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
+ struct resource_list *rl, const char *reg_source)
{
uint64_t phys, size;
ssize_t i, j, rid, nreg, ret;
@@ -504,11 +505,12 @@ ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
* This may be just redundant when having ofw_bus_devinfo
* but makes this routine independent of it.
*/
- ret = OF_getprop_alloc(node, "name", sizeof(*name), (void **)&name);
+ ret = OF_getprop_alloc(node, "name", (void **)&name);
if (ret == -1)
name = NULL;
- ret = OF_getencprop_alloc(node, "reg", sizeof(*reg), (void **)&reg);
+ ret = OF_getencprop_alloc_multi(node, reg_source, sizeof(*reg),
+ (void **)&reg);
nreg = (ret == -1) ? 0 : ret;
if (nreg % (acells + scells) != 0) {
@@ -539,6 +541,23 @@ ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
return (0);
}
+int
+ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
+ struct resource_list *rl)
+{
+
+ return (ofw_bus_reg_to_rl_helper(dev, node, acells, scells, rl, "reg"));
+}
+
+int
+ofw_bus_assigned_addresses_to_rl(device_t dev, phandle_t node, pcell_t acells,
+ pcell_t scells, struct resource_list *rl)
+{
+
+ return (ofw_bus_reg_to_rl_helper(dev, node, acells, scells,
+ rl, "assigned-addresses"));
+}
+
/*
* Get interrupt parent for given node.
* Returns 0 if interrupt parent doesn't exist.
@@ -569,7 +588,7 @@ ofw_bus_intr_to_rl(device_t dev, phandle_t node,
int err, i, irqnum, nintr, rid;
boolean_t extended;
- nintr = OF_getencprop_alloc(node, "interrupts", sizeof(*intr),
+ nintr = OF_getencprop_alloc_multi(node, "interrupts", sizeof(*intr),
(void **)&intr);
if (nintr > 0) {
iparent = ofw_bus_find_iparent(node);
@@ -592,7 +611,7 @@ ofw_bus_intr_to_rl(device_t dev, phandle_t node,
}
extended = false;
} else {
- nintr = OF_getencprop_alloc(node, "interrupts-extended",
+ nintr = OF_getencprop_alloc_multi(node, "interrupts-extended",
sizeof(*intr), (void **)&intr);
if (nintr <= 0)
return (0);
@@ -635,7 +654,7 @@ ofw_bus_intr_by_rid(device_t dev, phandle_t node, int wanted_rid,
int err, i, nintr, rid;
boolean_t extended;
- nintr = OF_getencprop_alloc(node, "interrupts", sizeof(*intr),
+ nintr = OF_getencprop_alloc_multi(node, "interrupts", sizeof(*intr),
(void **)&intr);
if (nintr > 0) {
iparent = ofw_bus_find_iparent(node);
@@ -658,7 +677,7 @@ ofw_bus_intr_by_rid(device_t dev, phandle_t node, int wanted_rid,
}
extended = false;
} else {
- nintr = OF_getencprop_alloc(node, "interrupts-extended",
+ nintr = OF_getencprop_alloc_multi(node, "interrupts-extended",
sizeof(*intr), (void **)&intr);
if (nintr <= 0)
return (ESRCH);
@@ -705,7 +724,7 @@ ofw_bus_find_child(phandle_t start, const char *child_name)
phandle_t child;
for (child = OF_child(start); child != 0; child = OF_peer(child)) {
- ret = OF_getprop_alloc(child, "name", sizeof(*name), (void **)&name);
+ ret = OF_getprop_alloc(child, "name", (void **)&name);
if (ret == -1)
continue;
if (strcmp(name, child_name) == 0) {
@@ -806,7 +825,7 @@ ofw_bus_parse_xref_list_internal(phandle_t node, const char *list_name,
int rv, i, j, nelems, cnt;
elems = NULL;
- nelems = OF_getencprop_alloc(node, list_name, sizeof(*elems),
+ nelems = OF_getencprop_alloc_multi(node, list_name, sizeof(*elems),
(void **)&elems);
if (nelems <= 0)
return (ENOENT);
@@ -901,7 +920,7 @@ ofw_bus_find_string_index(phandle_t node, const char *list_name,
int rv, i, cnt, nelems;
elems = NULL;
- nelems = OF_getprop_alloc(node, list_name, 1, (void **)&elems);
+ nelems = OF_getprop_alloc(node, list_name, (void **)&elems);
if (nelems <= 0)
return (ENOENT);
@@ -932,7 +951,7 @@ ofw_bus_string_list_to_array(phandle_t node, const char *list_name,
int i, cnt, nelems, len;
elems = NULL;
- nelems = OF_getprop_alloc(node, list_name, 1, (void **)&elems);
+ nelems = OF_getprop_alloc(node, list_name, (void **)&elems);
if (nelems <= 0)
return (nelems);
diff --git a/freebsd/sys/dev/ofw/ofw_bus_subr.h b/freebsd/sys/dev/ofw/ofw_bus_subr.h
index 04f5a75b..7bf66a10 100644
--- a/freebsd/sys/dev/ofw/ofw_bus_subr.h
+++ b/freebsd/sys/dev/ofw/ofw_bus_subr.h
@@ -95,6 +95,8 @@ int ofw_bus_msimap(phandle_t, uint16_t, phandle_t *, uint32_t *);
/* 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_assigned_addresses_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 *);
int ofw_bus_intr_by_rid(device_t, phandle_t, int, phandle_t *, int *,
pcell_t **);
diff --git a/freebsd/sys/dev/ofw/ofw_fdt.c b/freebsd/sys/dev/ofw/ofw_fdt.c
index 8878b5c9..b1bbadee 100644
--- a/freebsd/sys/dev/ofw/ofw_fdt.c
+++ b/freebsd/sys/dev/ofw/ofw_fdt.c
@@ -134,7 +134,7 @@ sysctl_register_fdt_oid(void *arg)
CTLTYPE_OPAQUE | CTLFLAG_RD, NULL, 0, sysctl_handle_dtb, "",
"Device Tree Blob");
}
-SYSINIT(dtb_oid, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_fdt_oid, 0);
+SYSINIT(dtb_oid, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_fdt_oid, NULL);
static int
ofw_fdt_init(ofw_t ofw, void *data)
diff --git a/freebsd/sys/dev/ofw/openfirm.c b/freebsd/sys/dev/ofw/openfirm.c
index 406e8dd6..9cc7dbdc 100644
--- a/freebsd/sys/dev/ofw/openfirm.c
+++ b/freebsd/sys/dev/ofw/openfirm.c
@@ -442,7 +442,7 @@ OF_searchprop(phandle_t node, const char *propname, void *buf, size_t len)
}
ssize_t
-OF_searchencprop(phandle_t node, const char *propname, void *buf, size_t len)
+OF_searchencprop(phandle_t node, const char *propname, pcell_t *buf, size_t len)
{
ssize_t rv;
@@ -454,11 +454,35 @@ OF_searchencprop(phandle_t node, const char *propname, void *buf, size_t len)
/*
* Store the value of a property of a package into newly allocated memory
+ * (using the M_OFWPROP malloc pool and M_WAITOK).
+ */
+ssize_t
+OF_getprop_alloc(phandle_t package, const char *propname, void **buf)
+{
+ int len;
+
+ *buf = NULL;
+ if ((len = OF_getproplen(package, propname)) == -1)
+ return (-1);
+
+ if (len > 0) {
+ *buf = malloc(len, M_OFWPROP, M_WAITOK);
+ if (OF_getprop(package, propname, *buf, len) == -1) {
+ free(*buf, M_OFWPROP);
+ *buf = NULL;
+ return (-1);
+ }
+ }
+ return (len);
+}
+
+/*
+ * Store the value of a property of a package into newly allocated memory
* (using the M_OFWPROP malloc pool and M_WAITOK). elsz is the size of a
* single element, the number of elements is return in number.
*/
ssize_t
-OF_getprop_alloc(phandle_t package, const char *propname, int elsz, void **buf)
+OF_getprop_alloc_multi(phandle_t package, const char *propname, int elsz, void **buf)
{
int len;
@@ -467,30 +491,41 @@ OF_getprop_alloc(phandle_t package, const char *propname, int elsz, void **buf)
len % elsz != 0)
return (-1);
- *buf = malloc(len, M_OFWPROP, M_WAITOK);
- if (OF_getprop(package, propname, *buf, len) == -1) {
- free(*buf, M_OFWPROP);
- *buf = NULL;
- return (-1);
+ if (len > 0) {
+ *buf = malloc(len, M_OFWPROP, M_WAITOK);
+ if (OF_getprop(package, propname, *buf, len) == -1) {
+ free(*buf, M_OFWPROP);
+ *buf = NULL;
+ return (-1);
+ }
}
return (len / elsz);
}
ssize_t
-OF_getencprop_alloc(phandle_t package, const char *name, int elsz, void **buf)
+OF_getencprop_alloc(phandle_t package, const char *name, void **buf)
+{
+ ssize_t ret;
+
+ ret = OF_getencprop_alloc_multi(package, name, sizeof(pcell_t),
+ buf);
+ if (ret < 0)
+ return (ret);
+ else
+ return (ret * sizeof(pcell_t));
+}
+
+ssize_t
+OF_getencprop_alloc_multi(phandle_t package, const char *name, int elsz,
+ void **buf)
{
ssize_t retval;
pcell_t *cell;
int i;
- retval = OF_getprop_alloc(package, name, elsz, buf);
+ retval = OF_getprop_alloc_multi(package, name, elsz, buf);
if (retval == -1)
return (-1);
- if (retval * elsz % 4 != 0) {
- free(*buf, M_OFWPROP);
- *buf = NULL;
- return (-1);
- }
cell = *buf;
for (i = 0; i < retval * elsz / 4; i++)
diff --git a/freebsd/sys/dev/ofw/openfirm.h b/freebsd/sys/dev/ofw/openfirm.h
index e1701164..f043197a 100644
--- a/freebsd/sys/dev/ofw/openfirm.h
+++ b/freebsd/sys/dev/ofw/openfirm.h
@@ -114,10 +114,14 @@ int OF_hasprop(phandle_t node, const char *propname);
ssize_t OF_searchprop(phandle_t node, const char *propname, void *buf,
size_t len);
ssize_t OF_searchencprop(phandle_t node, const char *propname,
- void *buf, size_t len);
+ pcell_t *buf, size_t len);
ssize_t OF_getprop_alloc(phandle_t node, const char *propname,
+ void **buf);
+ssize_t OF_getprop_alloc_multi(phandle_t node, const char *propname,
int elsz, void **buf);
ssize_t OF_getencprop_alloc(phandle_t node, const char *propname,
+ void **buf);
+ssize_t OF_getencprop_alloc_multi(phandle_t node, const char *propname,
int elsz, void **buf);
void OF_prop_free(void *buf);
int OF_nextprop(phandle_t node, const char *propname, char *buf,