diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-04-06 09:55:50 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-04-06 09:55:50 -0700 |
commit | f183d269cc6c64481b47ecbf9d3aff128dc0978c (patch) | |
tree | 3897411e0d277ac966c996c9acaf17f8252df027 /arch/csky/mm/cachev2.c | |
parent | b6ff10700d1bf33c4323d34eca1e80bc8a69f9f5 (diff) | |
parent | aefd9461d34a1b0a2acad0750c43216c1c27b9d4 (diff) |
Merge tag 'csky-for-linus-5.7-rc1' of git://github.com/c-sky/csky-linux
Pull csky updates from Guo Ren:
- Add kproobes/uprobes support
- Add lockdep, rseq, gcov support
- Fixup init_fpu
- Fixup ftrace_modify deadlock
- Fixup speculative execution on IO area
* tag 'csky-for-linus-5.7-rc1' of git://github.com/c-sky/csky-linux:
csky: Fixup cpu speculative execution to IO area
csky: Add uprobes support
csky: Add kprobes supported
csky: Enable LOCKDEP_SUPPORT
csky: Enable the gcov function
csky: Fixup get wrong psr value from phyical reg
csky/ftrace: Fixup ftrace_modify_code deadlock without CPU_HAS_ICACHE_INS
csky: Implement ftrace with regs
csky: Add support for restartable sequence
csky: Implement ptrace regs and stack API
csky: Fixup init_fpu compile warning with __init
Diffstat (limited to 'arch/csky/mm/cachev2.c')
-rw-r--r-- | arch/csky/mm/cachev2.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/arch/csky/mm/cachev2.c b/arch/csky/mm/cachev2.c index bc419f8039d3..7a9664adce43 100644 --- a/arch/csky/mm/cachev2.c +++ b/arch/csky/mm/cachev2.c @@ -7,8 +7,12 @@ #include <asm/cache.h> #include <asm/barrier.h> +/* for L1-cache */ #define INS_CACHE (1 << 0) +#define DATA_CACHE (1 << 1) #define CACHE_INV (1 << 4) +#define CACHE_CLR (1 << 5) +#define CACHE_OMS (1 << 6) void local_icache_inv_all(void *priv) { @@ -16,11 +20,6 @@ void local_icache_inv_all(void *priv) sync_is(); } -void icache_inv_all(void) -{ - on_each_cpu(local_icache_inv_all, NULL, 1); -} - #ifdef CONFIG_CPU_HAS_ICACHE_INS void icache_inv_range(unsigned long start, unsigned long end) { @@ -31,9 +30,43 @@ void icache_inv_range(unsigned long start, unsigned long end) sync_is(); } #else +struct cache_range { + unsigned long start; + unsigned long end; +}; + +static DEFINE_SPINLOCK(cache_lock); + +static inline void cache_op_line(unsigned long i, unsigned int val) +{ + mtcr("cr22", i); + mtcr("cr17", val); +} + +void local_icache_inv_range(void *priv) +{ + struct cache_range *param = priv; + unsigned long i = param->start & ~(L1_CACHE_BYTES - 1); + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); + + for (; i < param->end; i += L1_CACHE_BYTES) + cache_op_line(i, INS_CACHE | CACHE_INV | CACHE_OMS); + + spin_unlock_irqrestore(&cache_lock, flags); + + sync_is(); +} + void icache_inv_range(unsigned long start, unsigned long end) { - icache_inv_all(); + struct cache_range param = { start, end }; + + if (irqs_disabled()) + local_icache_inv_range(¶m); + else + on_each_cpu(local_icache_inv_range, ¶m, 1); } #endif |