From 8843b343e66ad85232a61eb3687ce898616adb6f Mon Sep 17 00:00:00 2001 From: andreast Date: Thu, 12 Dec 2013 12:17:20 +0000 Subject: MFC: r256932, r256938, r256953 r256932: Add a new function (OF_getencprop()) that undoes the transformation applied by encode-int. Specifically, it takes a set of 32-bit cell values and changes them to host byte order. Most non-string instances of OF_getprop() should be using this function, which is a no-op on big-endian platforms. r256938: A few other common cases for encode-int decoding: OF_getencprop_alloc() and OF_searchencprop(). I thought about using the element size parameter to OF_getprop_alloc() to do endian-switching automatically, but it breaks use with structs and a *lot* of FDT code (which can hopefully be moved to these new APIs). r256953: Fix build. --- sys/dev/ofw/openfirm.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ sys/dev/ofw/openfirm.h | 6 ++++++ 2 files changed, 53 insertions(+) diff --git a/sys/dev/ofw/openfirm.c b/sys/dev/ofw/openfirm.c index 0760854..a88b07b 100644 --- a/sys/dev/ofw/openfirm.c +++ b/sys/dev/ofw/openfirm.c @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -280,6 +281,21 @@ OF_getprop(phandle_t package, const char *propname, void *buf, size_t buflen) return (OFW_GETPROP(ofw_obj, package, propname, buf, buflen)); } +ssize_t +OF_getencprop(phandle_t node, const char *propname, pcell_t *buf, size_t len) +{ + ssize_t retval; + int i; + + KASSERT(len % 4 == 0, ("Need a multiple of 4 bytes")); + + retval = OF_getprop(node, propname, buf, len); + for (i = 0; i < len/4; i++) + buf[i] = be32toh(buf[i]); + + return (retval); +} + /* * Recursively search the node and its parent for the given property, working * downward from the node to the device tree root. Returns the value of the @@ -296,6 +312,17 @@ OF_searchprop(phandle_t node, const char *propname, void *buf, size_t len) return (-1); } +ssize_t +OF_searchencprop(phandle_t node, const char *propname, void *buf, size_t len) +{ + ssize_t rv; + + for (; node != 0; node = OF_parent(node)) + if ((rv = OF_getencprop(node, propname, buf, len)) != -1) + return (rv); + return (-1); +} + /* * 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 @@ -320,6 +347,26 @@ OF_getprop_alloc(phandle_t package, const char *propname, int elsz, void **buf) return (len / elsz); } +ssize_t +OF_getencprop_alloc(phandle_t package, const char *name, int elsz, void **buf) +{ + ssize_t retval; + pcell_t *cell; + int i; + + KASSERT(elsz % 4 == 0, ("Need a multiple of 4 bytes")); + + retval = OF_getprop_alloc(package, name, elsz, buf); + if (retval == -1) + return (retval); + + cell = *buf; + for (i = 0; i < retval*elsz/4; i++) + cell[i] = be32toh(cell[i]); + + return (retval); +} + /* Get the next property of a package. */ int OF_nextprop(phandle_t package, const char *previous, char *buf, size_t size) diff --git a/sys/dev/ofw/openfirm.h b/sys/dev/ofw/openfirm.h index e6ede1d..5ac08fe 100644 --- a/sys/dev/ofw/openfirm.h +++ b/sys/dev/ofw/openfirm.h @@ -105,11 +105,17 @@ phandle_t OF_parent(phandle_t node); ssize_t OF_getproplen(phandle_t node, const char *propname); ssize_t OF_getprop(phandle_t node, const char *propname, void *buf, size_t len); +ssize_t OF_getencprop(phandle_t node, const char *prop, pcell_t *buf, + size_t len); /* Same as getprop, but maintains endianness */ 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); ssize_t OF_getprop_alloc(phandle_t node, const char *propname, int elsz, void **buf); +ssize_t OF_getencprop_alloc(phandle_t node, const char *propname, + int elsz, void **buf); int OF_nextprop(phandle_t node, const char *propname, char *buf, size_t len); int OF_setprop(phandle_t node, const char *name, const void *buf, -- cgit v1.1