ARM: dcache: select DCACHE_WORD_ACCESS for big-endian CPUs
PATCH 1/2 ARM: dcache: select DCACHE_WORD_ACCESS for big-endian CPUs
With commit 11ec50caedb5 ("word-at-a-time: provide generic big-endian zero_bytemask implementation"), the asm-generic word-at-a-time code now provides a zero_bytemask implementation, allowing us to make use of DCACHE_WORD_ACCESS on big-endian CPUs, providing our load_unaligned_zeropad function is endianness-clean.
This patch reworks the load_unaligned_zeropad fixup code to work for both big- and little-endian CPUs, then removes the !CPU_BIG_ENDIAN check when selecting DCACHE_WORD_ACCESS.
--- arch/arm/Kconfig | 2 +- arch/arm/include/asm/word-at-a-time.h | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-)
arch/arm/Kconfig +1 -1
@@ -11,7 +11,7 @@ config ARM select BUILDTIME_EXTABLE_SORT if MMU select CLONE_BACKWARDS select CPU_PM if (SUSPEND || CPU_IDLE) - select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN && MMU + select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI) select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_IDLE_POLL_SETUP
arch/arm/include/asm/word-at-a-time.h +10 -8
@@ -48,10 +48,14 @@ static inline unsigned long find_zero(unsigned long mask) return ret; } -#ifdef CONFIG_DCACHE_WORD_ACCESS -#define zero_bytemask (mask) (mask) +#else /* __ARMEB__ */ +#include <asm-generic/word-at-a-time.h> +#endif + +#ifdef CONFIG_DCACHE_WORD_ACCESS +/* * Load an unaligned word from kernel space. *
@@ -73,7 +77,11 @@ static inline unsigned long load_unaligned_zeropad(const void *addr) " bic %2, %2, #0x3\n" " ldr %0, [%2]\n" " lsl %1, %1, #0x3\n" +#ifndef __ARMEB__ " lsr %0, %0, %1\n" +#else +" lsl %0, %0, %1\n" +#endif" b 2b\n" " .popsection\n" " .pushsection __ex_table,\"a\"\n"
@@ -86,11 +94,5 @@ static inline unsigned long load_unaligned_zeropad(const void *addr)return ret; } -#endif /* DCACHE_WORD_ACCESS */ - -#else /* __ARMEB__ */ -#include <asm-generic/word-at-a-time.h> -#endif -#endif /* __ASM_ARM_WORD_AT_A_TIME_H */
Signature · 1 line
1.8.2.2
PATCH 2/2 ARM: kconfig: select HAVE_EFFICIENT_UNALIGNED_ACCESS for CPUv6+ && MMU
Modern ARM CPUs can perform efficient unaligned memory accesses in hardware and this feature is relied up on by code such as the dcache word-at-a-time name hashing.
This patch selects HAVE_EFFICIENT_UNALIGNED_ACCESS for these cores and reworks the kconfig select logic for DCACHE_WORD_ACCESS to use the new symbol.
--- arch/arm/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/Kconfig +2 -1
@@ -11,7 +11,7 @@ config ARM select BUILDTIME_EXTABLE_SORT if MMU select CLONE_BACKWARDS select CPU_PM if (SUSPEND || CPU_IDLE) - select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU + select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI) select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_IDLE_POLL_SETUP
@@ -35,6 +35,7 @@ config ARM select HAVE_DMA_ATTRS select HAVE_DMA_CONTIGUOUS if MMU select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) + select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL) select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
Signature · 1 line
1.8.2.2
PATCH 2/2 ARM: kconfig: select HAVE_EFFICIENT_UNALIGNED_ACCESS for CPUv6+ && MMU
Quoted 9 lines · Will Deacon
Modern ARM CPUs can perform efficient unaligned memory accesses in hardware and this feature is relied up on by code such as the dcache word-at-a-time name hashing.
This patch selects
HAVE_EFFICIENT_UNALIGNED_ACCESSfor these cores and reworks the kconfig select logic forDCACHE_WORD_ACCESSto use the new symbol.Signed-off-by Will Deacon <[email protected]>
This symbol could be used in some more places too. For example this would make the code a bit clearer:
arch/arm/include/asm/uaccess.h +1 -1
@@ -19,7 +19,7 @@#include <asm/unified.h> #include <asm/compiler.h> -#if __LINUX_ARM_ARCH__ <6 +#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS #include <asm-generic/uaccess-unaligned.h> #else #define __get_user_unaligned __get_user
Nicolas
PATCH 2/2 ARM: kconfig: select HAVE_EFFICIENT_UNALIGNED_ACCESS for CPUv6+ && MMU
Hi Nicolas,
Quoted 6 lines · Nicolas Pitre
Quoted 4 lines · Will Deacon
Modern ARM CPUs can perform efficient unaligned memory accesses in hardware and this feature is relied up on by code such as the dcache word-at-a-time name hashing.
Quoted 8 lines
Quoted 5 lines
This patch selects
HAVE_EFFICIENT_UNALIGNED_ACCESSfor these cores and reworks the kconfig select logic forDCACHE_WORD_ACCESSto use the new symbol.Signed-off-by Will Deacon <[email protected]>This symbol could be used in some more places too. For example this would make the code a bit clearer:
Well spotted.
arch/arm/include/asm/uaccess.h line 25
Quoted 13 lines
arch/arm/include/asm/uaccess.h +1
-1@@ -19,7 +19,7 @@#include <asm/unified.h> #include <asm/compiler.h> -#if __LINUX_ARM_ARCH__ <6 +#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS #include <asm-generic/uaccess-unaligned.h> #else #define __get_user_unaligned __get_user
The original patch is now queued, so we can add this hunk as a follow-up cleanup patch. I've got you as the author, but can I add your S-o-B please?
Cheers,
Will
PATCH 2/2 ARM: kconfig: select HAVE_EFFICIENT_UNALIGNED_ACCESS for CPUv6+ && MMU
Quoted 28 lines · Will Deacon
Hi Nicolas,
Quoted 6 lines · Nicolas Pitre
Quoted 4 lines · Will Deacon
Modern ARM CPUs can perform efficient unaligned memory accesses in hardware and this feature is relied up on by code such as the dcache word-at-a-time name hashing.
Quoted 8 lines
Quoted 5 lines
This patch selects
HAVE_EFFICIENT_UNALIGNED_ACCESSfor these cores and reworks the kconfig select logic forDCACHE_WORD_ACCESSto use the new symbol.Signed-off-by Will Deacon <[email protected]>This symbol could be used in some more places too. For example this would make the code a bit clearer:
Well spotted.
Quoted 8 lines
arch/arm/include/asm/uaccess.h +0
-0@@ -19,7 +19,7 @@#include <asm/unified.h> #include <asm/compiler.h>
Quoted 8 lines
arch/arm/include/asm/uaccess.h line 25
Quoted 5 lines
arch/arm/include/asm/uaccess.h +1
-1-#if __LINUX_ARM_ARCH__ <6 +#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS #include <asm-generic/uaccess-unaligned.h> #else #define __get_user_unaligned __get_userThe original patch is now queued, so we can add this hunk as a follow-up cleanup patch. I've got you as the author, but can I add your S-o-B please?
Quoted 5 lines
Cheers,
Will
PATCH 1/2 ARM: dcache: select DCACHE_WORD_ACCESS for big-endian CPUs
In reply to Will DeaconQuoted 11 lines · Will Deacon
With commit
11ec50caedb5("word-at-a-time: provide generic big-endianzero_bytemaskimplementation"), the asm-generic word-at-a-time code now provides azero_bytemaskimplementation, allowing us to make use ofDCACHE_WORD_ACCESSon big-endian CPUs, providing ourload_unaligned_zeropadfunction is endianness-clean.This patch reworks the
load_unaligned_zeropadfixup code to work for both big- and little-endian CPUs, then removes the !CPU_BIG_ENDIAN check when selectingDCACHE_WORD_ACCESS.Signed-off-by Will Deacon <[email protected]>
Small comment below.
Quoted 40 lines
--- arch/arm/Kconfig | 2 +- arch/arm/include/asm/word-at-a-time.h | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-)arch/arm/Kconfig +1
-1@@ -11,7 +11,7 @@ config ARM select BUILDTIME_EXTABLE_SORT if MMU select CLONE_BACKWARDS select CPU_PM if (SUSPEND || CPU_IDLE) - select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN && MMU + select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI) select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_IDLE_POLL_SETUParch/arm/include/asm/word-at-a-time.h +6
-2@@ -48,10 +48,14 @@ static inline unsigned long find_zero(unsigned long mask) return ret; } -#ifdef CONFIG_DCACHE_WORD_ACCESS -#define zero_bytemask (mask) (mask) +#else /* __ARMEB__ */ +#include <asm-generic/word-at-a-time.h> +#endif + +#ifdef CONFIG_DCACHE_WORD_ACCESS +/* * Load an unaligned word from kernel space. *
arch/arm/include/asm/word-at-a-time.h static inline unsigned long load_unaligned_zeropad(const void *addr) · line 84
Quoted 8 lines
arch/arm/include/asm/word-at-a-time.h +4
-0@@ -73,7 +77,11 @@ static inline unsigned long load_unaligned_zeropad(const void *addr) " bic %2, %2, #0x3\n" " ldr %0, [%2]\n" " lsl %1, %1, #0x3\n" +#ifndef __ARMEB__ " lsr %0, %0, %1\n" +#else +" lsl %0, %0, %1\n" +#endif
You could get rid of the #ifdef by using:
pull %0, %0, %1
Except this is not a pure assembly file and can't rely on <asm/assembler.h>. Bah. In that case...
Nicolas
PATCH 1/2 ARM: dcache: select DCACHE_WORD_ACCESS for big-endian CPUs
In reply to Will DeaconQuoted 12 lines · Will Deacon
With commit
11ec50caedb5("word-at-a-time: provide generic big-endianzero_bytemaskimplementation"), the asm-generic word-at-a-time code now provides azero_bytemaskimplementation, allowing us to make use ofDCACHE_WORD_ACCESSon big-endian CPUs, providing ourload_unaligned_zeropadfunction is endianness-clean.This patch reworks the
load_unaligned_zeropadfixup code to work for both big- and little-endian CPUs, then removes the !CPU_BIG_ENDIAN check when selectingDCACHE_WORD_ACCESS.
arch/arm/include/asm/word-at-a-time.h static inline unsigned long load_unaligned_zeropad(const void *addr) · line 84
Quoted 8 lines
arch/arm/include/asm/word-at-a-time.h +4
-0@@ -73,7 +77,11 @@ static inline unsigned long load_unaligned_zeropad(const void *addr) " bic %2, %2, #0x3\n" " ldr %0, [%2]\n" " lsl %1, %1, #0x3\n" +#ifndef __ARMEB__ " lsr %0, %0, %1\n" +#else +" lsl %0, %0, %1\n" +#endif
IIRC we have ARM_BE() and ARM_LE() helpers for this
Signature · 2 lines
Ben Dooks http://www.codethink.co.uk/ Senior Engineer Codethink - Providing Genius