Commit 43bc61d8 authored by Paul Mundt's avatar Paul Mundt

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: default avatarPaul Mundt <lethal@linux-sh.org>
parent 0837f524
...@@ -198,6 +198,11 @@ do { \ ...@@ -198,6 +198,11 @@ do { \
}) })
#endif #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, int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
struct mem_access *ma); struct mem_access *ma);
......
...@@ -37,4 +37,9 @@ do { \ ...@@ -37,4 +37,9 @@ do { \
#define jump_to_uncached() do { } while (0) #define jump_to_uncached() do { } while (0)
#define back_to_cached() 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 */ #endif /* __ASM_SH_SYSTEM_64_H */
...@@ -11,8 +11,10 @@ ...@@ -11,8 +11,10 @@
#ifdef CONFIG_SUPERH32 #ifdef CONFIG_SUPERH32
typedef u16 insn_size_t; typedef u16 insn_size_t;
typedef u32 reg_size_t;
#else #else
typedef u32 insn_size_t; typedef u32 insn_size_t;
typedef u64 reg_size_t;
#endif #endif
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
......
...@@ -10,10 +10,11 @@ ...@@ -10,10 +10,11 @@
*/ */
void __weak __flush_wback_region(void *start, int size) 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); aligned_start = register_align(start);
end = ((unsigned long)start + size + L1_CACHE_BYTES-1) v = aligned_start & ~(L1_CACHE_BYTES-1);
end = (aligned_start + size + L1_CACHE_BYTES-1)
& ~(L1_CACHE_BYTES-1); & ~(L1_CACHE_BYTES-1);
cnt = (end - v) / L1_CACHE_BYTES; cnt = (end - v) / L1_CACHE_BYTES;
...@@ -52,10 +53,11 @@ void __weak __flush_wback_region(void *start, int size) ...@@ -52,10 +53,11 @@ void __weak __flush_wback_region(void *start, int size)
*/ */
void __weak __flush_purge_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); aligned_start = register_align(start);
end = ((unsigned long)start + size + L1_CACHE_BYTES-1) v = aligned_start & ~(L1_CACHE_BYTES-1);
end = (aligned_start + size + L1_CACHE_BYTES-1)
& ~(L1_CACHE_BYTES-1); & ~(L1_CACHE_BYTES-1);
cnt = (end - v) / L1_CACHE_BYTES; cnt = (end - v) / L1_CACHE_BYTES;
...@@ -90,10 +92,11 @@ void __weak __flush_purge_region(void *start, int size) ...@@ -90,10 +92,11 @@ void __weak __flush_purge_region(void *start, int size)
*/ */
void __weak __flush_invalidate_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); aligned_start = register_align(start);
end = ((unsigned long)start + size + L1_CACHE_BYTES-1) v = aligned_start & ~(L1_CACHE_BYTES-1);
end = (aligned_start + size + L1_CACHE_BYTES-1)
& ~(L1_CACHE_BYTES-1); & ~(L1_CACHE_BYTES-1);
cnt = (end - v) / L1_CACHE_BYTES; cnt = (end - v) / L1_CACHE_BYTES;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment