[rtems commit] libfdt: Don't use memcpy to handle unaligned reads on ARM

Sebastian Huber sebh at rtems.org
Mon Mar 2 06:52:33 UTC 2020


Module:    rtems
Branch:    master
Commit:    bef6dfc5889ba5f2123c558228072d99ae1d8418
Changeset: http://git.rtems.org/rtems/commit/?id=bef6dfc5889ba5f2123c558228072d99ae1d8418

Author:    David Gibson <david at gibson.dropbear.id.au>
Date:      Mon Nov 19 16:36:15 2018 +1100

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 at gibson.dropbear.id.au>

---

 cpukit/include/libfdt.h | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/cpukit/include/libfdt.h b/cpukit/include/libfdt.h
index face02c..fdaa3e6 100644
--- a/cpukit/include/libfdt.h
+++ b/cpukit/include/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];
 }
 
 /**********************************************************************/



More information about the vc mailing list