summaryrefslogtreecommitdiffstats
path: root/cpukit/include/libfdt.h
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2018-06-21 15:32:40 +1000
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-07-19 07:01:12 +0200
commit78ad0488f8895a79b8262f06b31c83c0929d845e (patch)
tree5742cf5b9a8b710a0c2532237cdd8b0ba389250e /cpukit/include/libfdt.h
parentpylibfdt: Add functions to update properties (diff)
downloadrtems-78ad0488f8895a79b8262f06b31c83c0929d845e.tar.bz2
libfdt: Add helpers for accessing unaligned words
This adds some helpers to load (32 or 64 bit) words from an fdt blob, even if they're unaligned and we're on a platform that doesn't like plain unaligned loads and stores. We then use the helpers in a number of places. There are two purposes for this: 1) This makes libfdt more robust against a blob loaded at an unaligned address. It's usually good practice to load a blob at a 64-bit alignment, but it's nice to work even then. 2) Users can use these helpers to load integer values from within property values. These can often be unaligned, even if the blob as a whole is aligned, since some property encodings have integers and strings mixed together without any alignment gaps. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'cpukit/include/libfdt.h')
-rw-r--r--cpukit/include/libfdt.h25
1 files changed, 24 insertions, 1 deletions
diff --git a/cpukit/include/libfdt.h b/cpukit/include/libfdt.h
index c99d28fea5..38ec313094 100644
--- a/cpukit/include/libfdt.h
+++ b/cpukit/include/libfdt.h
@@ -154,6 +154,29 @@ static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
+/*
+ * Alignment helpers:
+ * These helpers access words from a device tree blob. They're
+ * built to work even with unaligned pointers on platforms (ike
+ * ARM) that don't like unaligned loads and stores
+ */
+
+static inline uint32_t fdt32_ld(const fdt32_t *p)
+{
+ fdt32_t v;
+
+ memcpy(&v, p, sizeof(v));
+ return fdt32_to_cpu(v);
+}
+
+static inline uint64_t fdt64_ld(const fdt64_t *p)
+{
+ fdt64_t v;
+
+ memcpy(&v, p, sizeof(v));
+ return fdt64_to_cpu(v);
+}
+
/**********************************************************************/
/* Traversal functions */
/**********************************************************************/
@@ -214,7 +237,7 @@ int fdt_next_subnode(const void *fdt, int offset);
/* General functions */
/**********************************************************************/
#define fdt_get_header(fdt, field) \
- (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
+ (fdt32_ld(&((const struct fdt_header *)(fdt))->field))
#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))