diff options
author | Will Deacon <will.deacon@arm.com> | 2012-07-06 10:46:08 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-07-09 12:41:11 -0400 |
commit | b9a50f74905ad9126c91b495ece8a5f45434c643 (patch) | |
tree | 8ae821933d953f50b52de596e7281bf888c098ec /arch/arm/include/asm | |
parent | 8c56cc8be5b38e3684eba96dc9b3f7ca7e495755 (diff) |
ARM: 7450/1: dcache: select DCACHE_WORD_ACCESS for little-endian ARMv6+ CPUs
DCACHE_WORD_ACCESS uses the word-at-a-time API for optimised string
comparisons in the vfs layer.
This patch implements support for load_unaligned_zeropad for ARM CPUs
with native support for unaligned memory accesses (v6+) when running
little-endian.
Reviewed-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/include/asm')
-rw-r--r-- | arch/arm/include/asm/word-at-a-time.h | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/arch/arm/include/asm/word-at-a-time.h b/arch/arm/include/asm/word-at-a-time.h index 74b2d4578577..4d52f92967a6 100644 --- a/arch/arm/include/asm/word-at-a-time.h +++ b/arch/arm/include/asm/word-at-a-time.h | |||
@@ -48,6 +48,47 @@ static inline unsigned long find_zero(unsigned long mask) | |||
48 | return ret; | 48 | return ret; |
49 | } | 49 | } |
50 | 50 | ||
51 | #ifdef CONFIG_DCACHE_WORD_ACCESS | ||
52 | |||
53 | #define zero_bytemask(mask) (mask) | ||
54 | |||
55 | /* | ||
56 | * Load an unaligned word from kernel space. | ||
57 | * | ||
58 | * In the (very unlikely) case of the word being a page-crosser | ||
59 | * and the next page not being mapped, take the exception and | ||
60 | * return zeroes in the non-existing part. | ||
61 | */ | ||
62 | static inline unsigned long load_unaligned_zeropad(const void *addr) | ||
63 | { | ||
64 | unsigned long ret, offset; | ||
65 | |||
66 | /* Load word from unaligned pointer addr */ | ||
67 | asm( | ||
68 | "1: ldr %0, [%2]\n" | ||
69 | "2:\n" | ||
70 | " .pushsection .fixup,\"ax\"\n" | ||
71 | " .align 2\n" | ||
72 | "3: and %1, %2, #0x3\n" | ||
73 | " bic %2, %2, #0x3\n" | ||
74 | " ldr %0, [%2]\n" | ||
75 | " lsl %1, %1, #0x3\n" | ||
76 | " lsr %0, %0, %1\n" | ||
77 | " b 2b\n" | ||
78 | " .popsection\n" | ||
79 | " .pushsection __ex_table,\"a\"\n" | ||
80 | " .align 3\n" | ||
81 | " .long 1b, 3b\n" | ||
82 | " .popsection" | ||
83 | : "=&r" (ret), "=&r" (offset) | ||
84 | : "r" (addr), "Qo" (*(unsigned long *)addr)); | ||
85 | |||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | |||
90 | #endif /* DCACHE_WORD_ACCESS */ | ||
91 | |||
51 | #else /* __ARMEB__ */ | 92 | #else /* __ARMEB__ */ |
52 | #include <asm-generic/word-at-a-time.h> | 93 | #include <asm-generic/word-at-a-time.h> |
53 | #endif | 94 | #endif |