sh: Add register alignment helpers for shared flushers.
authorPaul Mundt <lethal@linux-sh.org>
Fri, 14 Aug 2009 16:57:36 +0000 (01:57 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Fri, 14 Aug 2009 16:57:36 +0000 (01:57 +0900)
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 <lethal@linux-sh.org>
arch/sh/include/asm/system_32.h
arch/sh/include/asm/system_64.h
arch/sh/include/asm/types.h
arch/sh/mm/flush-sh4.c

index 6c68a51..d7299d6 100644 (file)
@@ -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);
 
index 943acf5..218b54d 100644 (file)
@@ -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 */
index c7f3c94..f8421f7 100644 (file)
 
 #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__ */
index edefc53..1b6b6a1 100644 (file)
  */
 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;