aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2018-11-19 16:36:15 +1100
committerDavid Gibson <david@gibson.dropbear.id.au>2018-11-22 23:37:07 +1100
commit11738cf01f150afae913b88fb68675a272803d63 (patch)
treef18346b27dc6206d3c81af2f4c3110492389cd5b
parent86a288a7367086bb8dad60ea293811d62f59671b (diff)
downloaddtc-11738cf01f150afae913b88fb68675a272803d63.zip
dtc-11738cf01f150afae913b88fb68675a272803d63.tar.gz
dtc-11738cf01f150afae913b88fb68675a272803d63.tar.bz2
libfdt: Don't use memcpy to handle unaligned reads on ARM
6dcb8ba4 "libfdt: Add helpers for accessing unaligned words" introduced the fdt32_ld() and fdt64_ld() helpers for loading values from the FDT blob which might not be naturally aligned. This matters for ARM, where attempting a plain unaligned load will often cause an exception. However, it seems the memcpy() we used here was surprisingly expensive, making libfdt nearly 6x slower on at least some ARM platforms. This patch takes an alternative approach, using a bunch of 1-byte loads and shifts to implement the helpers. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r--libfdt/libfdt.h22
1 files changed, 15 insertions, 7 deletions
diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h
index face02c..fdaa3e6 100644
--- a/libfdt/libfdt.h
+++ b/libfdt/libfdt.h
@@ -163,18 +163,26 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
static inline uint32_t fdt32_ld(const fdt32_t *p)
{
- fdt32_t v;
+ const uint8_t *bp = (const uint8_t *)p;
- memcpy(&v, p, sizeof(v));
- return fdt32_to_cpu(v);
+ return ((uint32_t)bp[0] << 24)
+ | ((uint32_t)bp[1] << 16)
+ | ((uint32_t)bp[2] << 8)
+ | bp[3];
}
static inline uint64_t fdt64_ld(const fdt64_t *p)
{
- fdt64_t v;
-
- memcpy(&v, p, sizeof(v));
- return fdt64_to_cpu(v);
+ const uint8_t *bp = (const uint8_t *)p;
+
+ return ((uint64_t)bp[0] << 56)
+ | ((uint64_t)bp[1] << 48)
+ | ((uint64_t)bp[2] << 40)
+ | ((uint64_t)bp[3] << 32)
+ | ((uint64_t)bp[4] << 24)
+ | ((uint64_t)bp[5] << 16)
+ | ((uint64_t)bp[6] << 8)
+ | bp[7];
}
/**********************************************************************/