|
@@ -48,6 +48,47 @@ static inline unsigned long find_zero(unsigned long mask)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_DCACHE_WORD_ACCESS
|
|
|
+
|
|
|
+#define zero_bytemask(mask) (mask)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Load an unaligned word from kernel space.
|
|
|
+ *
|
|
|
+ * In the (very unlikely) case of the word being a page-crosser
|
|
|
+ * and the next page not being mapped, take the exception and
|
|
|
+ * return zeroes in the non-existing part.
|
|
|
+ */
|
|
|
+static inline unsigned long load_unaligned_zeropad(const void *addr)
|
|
|
+{
|
|
|
+ unsigned long ret, offset;
|
|
|
+
|
|
|
+ /* Load word from unaligned pointer addr */
|
|
|
+ asm(
|
|
|
+ "1: ldr %0, [%2]\n"
|
|
|
+ "2:\n"
|
|
|
+ " .pushsection .fixup,\"ax\"\n"
|
|
|
+ " .align 2\n"
|
|
|
+ "3: and %1, %2, #0x3\n"
|
|
|
+ " bic %2, %2, #0x3\n"
|
|
|
+ " ldr %0, [%2]\n"
|
|
|
+ " lsl %1, %1, #0x3\n"
|
|
|
+ " lsr %0, %0, %1\n"
|
|
|
+ " b 2b\n"
|
|
|
+ " .popsection\n"
|
|
|
+ " .pushsection __ex_table,\"a\"\n"
|
|
|
+ " .align 3\n"
|
|
|
+ " .long 1b, 3b\n"
|
|
|
+ " .popsection"
|
|
|
+ : "=&r" (ret), "=&r" (offset)
|
|
|
+ : "r" (addr), "Qo" (*(unsigned long *)addr));
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+#endif /* DCACHE_WORD_ACCESS */
|
|
|
+
|
|
|
#else /* __ARMEB__ */
|
|
|
#include <asm-generic/word-at-a-time.h>
|
|
|
#endif
|