diff options
author | Will Deacon <will.deacon@arm.com> | 2013-11-06 14:32:13 -0500 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2013-12-19 12:43:08 -0500 |
commit | 7bc13fd33adb9536bd73965cd46bbf7377df097c (patch) | |
tree | 7b394763246d3362bc40836bf31f17069f5d6ab8 /arch/arm64/include | |
parent | 4da7a56c59f28e27e8dcff61b5d7b05f6e203606 (diff) |
arm64: dcache: select DCACHE_WORD_ACCESS for little-endian 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 in much the
same way as has been done for ARM, although big-endian systems are also
supported.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/include')
-rw-r--r-- | arch/arm64/include/asm/word-at-a-time.h | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/arm64/include/asm/word-at-a-time.h b/arch/arm64/include/asm/word-at-a-time.h index 27a167d044d9..aab5bf09e9d9 100644 --- a/arch/arm64/include/asm/word-at-a-time.h +++ b/arch/arm64/include/asm/word-at-a-time.h | |||
@@ -47,8 +47,48 @@ static inline unsigned long find_zero(unsigned long mask) | |||
47 | return fls64(mask) >> 3; | 47 | return fls64(mask) >> 3; |
48 | } | 48 | } |
49 | 49 | ||
50 | #define zero_bytemask(mask) (mask) | ||
51 | |||
50 | #else /* __AARCH64EB__ */ | 52 | #else /* __AARCH64EB__ */ |
51 | #include <asm-generic/word-at-a-time.h> | 53 | #include <asm-generic/word-at-a-time.h> |
52 | #endif | 54 | #endif |
53 | 55 | ||
56 | /* | ||
57 | * Load an unaligned word from kernel space. | ||
58 | * | ||
59 | * In the (very unlikely) case of the word being a page-crosser | ||
60 | * and the next page not being mapped, take the exception and | ||
61 | * return zeroes in the non-existing part. | ||
62 | */ | ||
63 | static inline unsigned long load_unaligned_zeropad(const void *addr) | ||
64 | { | ||
65 | unsigned long ret, offset; | ||
66 | |||
67 | /* Load word from unaligned pointer addr */ | ||
68 | asm( | ||
69 | "1: ldr %0, %3\n" | ||
70 | "2:\n" | ||
71 | " .pushsection .fixup,\"ax\"\n" | ||
72 | " .align 2\n" | ||
73 | "3: and %1, %2, #0x7\n" | ||
74 | " bic %2, %2, #0x7\n" | ||
75 | " ldr %0, [%2]\n" | ||
76 | " lsl %1, %1, #0x3\n" | ||
77 | #ifndef __AARCH64EB__ | ||
78 | " lsr %0, %0, %1\n" | ||
79 | #else | ||
80 | " lsl %0, %0, %1\n" | ||
81 | #endif | ||
82 | " b 2b\n" | ||
83 | " .popsection\n" | ||
84 | " .pushsection __ex_table,\"a\"\n" | ||
85 | " .align 3\n" | ||
86 | " .quad 1b, 3b\n" | ||
87 | " .popsection" | ||
88 | : "=&r" (ret), "=&r" (offset) | ||
89 | : "r" (addr), "Q" (*(unsigned long *)addr)); | ||
90 | |||
91 | return ret; | ||
92 | } | ||
93 | |||
54 | #endif /* __ASM_WORD_AT_A_TIME_H */ | 94 | #endif /* __ASM_WORD_AT_A_TIME_H */ |