[PATCH] ARM: add unaligned macros

Daniel Mack daniel at caiaq.de
Thu Jun 4 12:19:52 CEST 2009


Unaligned data access is evil on ARMs, especially when no magic foo like
Linux' traps clean up after us, hence choose the 'packed struct' way.

Signed-off-by: Daniel Mack <daniel at caiaq.de>
---
 include/asm-arm/unaligned.h             |   14 ++++++++++
 include/linux/unaligned/le_struct.h     |   36 +++++++++++++++++++++++++
 include/linux/unaligned/packed_struct.h |   44 +++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+), 0 deletions(-)
 create mode 100644 include/asm-arm/unaligned.h
 create mode 100644 include/linux/unaligned/le_struct.h
 create mode 100644 include/linux/unaligned/packed_struct.h

diff --git a/include/asm-arm/unaligned.h b/include/asm-arm/unaligned.h
new file mode 100644
index 0000000..569db55
--- /dev/null
+++ b/include/asm-arm/unaligned.h
@@ -0,0 +1,14 @@
+#ifndef _ASM_ARM_UNALIGNED_H
+#define _ASM_ARM_UNALIGNED_H
+
+#ifdef __KERNEL__
+
+#include <linux/unaligned/le_struct.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned	__get_unaligned_le
+#define put_unaligned	__put_unaligned_le
+
+#endif	/* __KERNEL__ */
+#endif	/* _ASM_ARM_UNALIGNED_H */
+
diff --git a/include/linux/unaligned/le_struct.h b/include/linux/unaligned/le_struct.h
new file mode 100644
index 0000000..088c457
--- /dev/null
+++ b/include/linux/unaligned/le_struct.h
@@ -0,0 +1,36 @@
+#ifndef _LINUX_UNALIGNED_LE_STRUCT_H
+#define _LINUX_UNALIGNED_LE_STRUCT_H
+
+#include <linux/unaligned/packed_struct.h>
+
+static inline u16 get_unaligned_le16(const void *p)
+{
+	return __get_unaligned_cpu16((const u8 *)p);
+}
+
+static inline u32 get_unaligned_le32(const void *p)
+{
+	return __get_unaligned_cpu32((const u8 *)p);
+}
+
+static inline u64 get_unaligned_le64(const void *p)
+{
+	return __get_unaligned_cpu64((const u8 *)p);
+}
+
+static inline void put_unaligned_le16(u16 val, void *p)
+{
+	__put_unaligned_cpu16(val, p);
+}
+
+static inline void put_unaligned_le32(u32 val, void *p)
+{
+	__put_unaligned_cpu32(val, p);
+}
+
+static inline void put_unaligned_le64(u64 val, void *p)
+{
+	__put_unaligned_cpu64(val, p);
+}
+
+#endif /* _LINUX_UNALIGNED_LE_STRUCT_H */
diff --git a/include/linux/unaligned/packed_struct.h b/include/linux/unaligned/packed_struct.h
new file mode 100644
index 0000000..5034257
--- /dev/null
+++ b/include/linux/unaligned/packed_struct.h
@@ -0,0 +1,44 @@
+#ifndef _LINUX_UNALIGNED_PACKED_STRUCT_H
+#define _LINUX_UNALIGNED_PACKED_STRUCT_H
+
+struct __una_u16 { u16 x __attribute__((packed)); } __attribute__((packed));
+struct __una_u32 { u32 x __attribute__((packed)); } __attribute__((packed));
+struct __una_u64 { u64 x __attribute__((packed)); } __attribute__((packed));
+
+static inline u16 __get_unaligned_cpu16(const void *p)
+{
+	const struct __una_u16 *ptr = (const struct __una_u16 *)p;
+	return ptr->x;
+}
+
+static inline u32 __get_unaligned_cpu32(const void *p)
+{
+	const struct __una_u32 *ptr = (const struct __una_u32 *)p;
+	return ptr->x;
+}
+
+static inline u64 __get_unaligned_cpu64(const void *p)
+{
+	const struct __una_u64 *ptr = (const struct __una_u64 *)p;
+	return ptr->x;
+}
+
+static inline void __put_unaligned_cpu16(u16 val, void *p)
+{
+	struct __una_u16 *ptr = (struct __una_u16 *)p;
+	ptr->x = val;
+}
+
+static inline void __put_unaligned_cpu32(u32 val, void *p)
+{
+	struct __una_u32 *ptr = (struct __una_u32 *)p;
+	ptr->x = val;
+}
+
+static inline void __put_unaligned_cpu64(u64 val, void *p)
+{
+	struct __una_u64 *ptr = (struct __una_u64 *)p;
+	ptr->x = val;
+}
+
+#endif /* _LINUX_UNALIGNED_PACKED_STRUCT_H */
-- 
1.6.3.1



More information about the U-Boot mailing list