From 43bc61d86f8ea6edef2e02d1dc47617883fa9a9c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 15 Aug 2009 01:57:36 +0900 Subject: [PATCH] sh: Add register alignment helpers for shared flushers. This plugs in some register alignment helpers for the shared flushers, allowing them to also be used on SH-5. The main rationale here is that in the SH-5 case we have a variable ABI, where the pointer size may not equal the register width. This register extension is taken care of by the SH-5 code already today, and is otherwise unused on the SH-4 code. This combines the two and allows us to kill off the SH-5 implementation. Signed-off-by: Paul Mundt --- arch/sh/include/asm/system_32.h | 5 +++++ arch/sh/include/asm/system_64.h | 5 +++++ arch/sh/include/asm/types.h | 2 ++ arch/sh/mm/flush-sh4.c | 21 ++++++++++++--------- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h index 6c68a51..d7299d6 100644 --- a/arch/sh/include/asm/system_32.h +++ b/arch/sh/include/asm/system_32.h @@ -198,6 +198,11 @@ do { \ }) #endif +static inline reg_size_t register_align(void *val) +{ + return (unsigned long)(signed long)val; +} + int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, struct mem_access *ma); diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h index 943acf5..218b54d 100644 --- a/arch/sh/include/asm/system_64.h +++ b/arch/sh/include/asm/system_64.h @@ -37,4 +37,9 @@ do { \ #define jump_to_uncached() do { } while (0) #define back_to_cached() do { } while (0) +static inline reg_size_t register_align(void *val) +{ + return (unsigned long long)(signed long long)(signed long)val; +} + #endif /* __ASM_SH_SYSTEM_64_H */ diff --git a/arch/sh/include/asm/types.h b/arch/sh/include/asm/types.h index c7f3c94..f8421f7 100644 --- a/arch/sh/include/asm/types.h +++ b/arch/sh/include/asm/types.h @@ -11,8 +11,10 @@ #ifdef CONFIG_SUPERH32 typedef u16 insn_size_t; +typedef u32 reg_size_t; #else typedef u32 insn_size_t; +typedef u64 reg_size_t; #endif #endif /* __ASSEMBLY__ */ diff --git a/arch/sh/mm/flush-sh4.c b/arch/sh/mm/flush-sh4.c index edefc53..1b6b6a1 100644 --- a/arch/sh/mm/flush-sh4.c +++ b/arch/sh/mm/flush-sh4.c @@ -10,10 +10,11 @@ */ void __weak __flush_wback_region(void *start, int size) { - unsigned long v, cnt, end; + reg_size_t aligned_start, v, cnt, end; - v = (unsigned long)start & ~(L1_CACHE_BYTES-1); - end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + aligned_start = register_align(start); + v = aligned_start & ~(L1_CACHE_BYTES-1); + end = (aligned_start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); cnt = (end - v) / L1_CACHE_BYTES; @@ -52,10 +53,11 @@ void __weak __flush_wback_region(void *start, int size) */ void __weak __flush_purge_region(void *start, int size) { - unsigned long v, cnt, end; + reg_size_t aligned_start, v, cnt, end; - v = (unsigned long)start & ~(L1_CACHE_BYTES-1); - end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + aligned_start = register_align(start); + v = aligned_start & ~(L1_CACHE_BYTES-1); + end = (aligned_start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); cnt = (end - v) / L1_CACHE_BYTES; @@ -90,10 +92,11 @@ void __weak __flush_purge_region(void *start, int size) */ void __weak __flush_invalidate_region(void *start, int size) { - unsigned long v, cnt, end; + reg_size_t aligned_start, v, cnt, end; - v = (unsigned long)start & ~(L1_CACHE_BYTES-1); - end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + aligned_start = register_align(start); + v = aligned_start & ~(L1_CACHE_BYTES-1); + end = (aligned_start + size + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); cnt = (end - v) / L1_CACHE_BYTES; -- 2.7.4