summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandreast <andreast@FreeBSD.org>2013-12-12 12:17:20 +0000
committerandreast <andreast@FreeBSD.org>2013-12-12 12:17:20 +0000
commit8843b343e66ad85232a61eb3687ce898616adb6f (patch)
treea5b1659dcbf4f44425eb3eb7c2589029ccfb2265
parentcf9afebc6a89230e1c6e4972c4ca3bccd81a4750 (diff)
downloadFreeBSD-src-8843b343e66ad85232a61eb3687ce898616adb6f.zip
FreeBSD-src-8843b343e66ad85232a61eb3687ce898616adb6f.tar.gz
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.
-rw-r--r--sys/dev/ofw/openfirm.c47
-rw-r--r--sys/dev/ofw/openfirm.h6
2 files changed, 53 insertions, 0 deletions
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 <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/systm.h>
+#include <sys/endian.h>
#include <machine/stdarg.h>
@@ -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,
OpenPOWER on IntegriCloud