mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 20:24:12 +08:00
csky: Support icache flush without specific instructions
Some CPUs don't support icache specific instructions to flush icache lines in broadcast way. We use cpu control registers to flush local icache and use IPI to notify other cores. Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
This commit is contained in:
parent
a736fa1ed7
commit
761b4f694c
@ -231,6 +231,10 @@ config CPU_HAS_FPU
|
||||
bool "CPU has FPU coprocessor"
|
||||
depends on CPU_CK807 || CPU_CK810 || CPU_CK860
|
||||
|
||||
config CPU_HAS_ICACHE_INS
|
||||
bool "CPU has Icache invalidate instructions"
|
||||
depends on CPU_HAS_CACHEV2
|
||||
|
||||
config CPU_HAS_TEE
|
||||
bool "CPU has Trusted Execution Environment"
|
||||
depends on CPU_CK810
|
||||
|
@ -16,6 +16,7 @@ void dcache_wb_line(unsigned long start);
|
||||
|
||||
void icache_inv_range(unsigned long start, unsigned long end);
|
||||
void icache_inv_all(void);
|
||||
void local_icache_inv_all(void *priv);
|
||||
|
||||
void dcache_wb_range(unsigned long start, unsigned long end);
|
||||
void dcache_wbinv_all(void);
|
||||
|
@ -94,6 +94,11 @@ void icache_inv_all(void)
|
||||
cache_op_all(INS_CACHE|CACHE_INV, 0);
|
||||
}
|
||||
|
||||
void local_icache_inv_all(void *priv)
|
||||
{
|
||||
cache_op_all(INS_CACHE|CACHE_INV, 0);
|
||||
}
|
||||
|
||||
void dcache_wb_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
cache_op_range(start, end, DATA_CACHE|CACHE_CLR, 0);
|
||||
|
@ -3,15 +3,25 @@
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/barrier.h>
|
||||
|
||||
inline void dcache_wb_line(unsigned long start)
|
||||
#define INS_CACHE (1 << 0)
|
||||
#define CACHE_INV (1 << 4)
|
||||
|
||||
void local_icache_inv_all(void *priv)
|
||||
{
|
||||
asm volatile("dcache.cval1 %0\n"::"r"(start):"memory");
|
||||
mtcr("cr17", INS_CACHE|CACHE_INV);
|
||||
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)
|
||||
{
|
||||
unsigned long i = start & ~(L1_CACHE_BYTES - 1);
|
||||
@ -20,10 +30,16 @@ void icache_inv_range(unsigned long start, unsigned long end)
|
||||
asm volatile("icache.iva %0\n"::"r"(i):"memory");
|
||||
sync_is();
|
||||
}
|
||||
|
||||
void icache_inv_all(void)
|
||||
#else
|
||||
void icache_inv_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
asm volatile("icache.ialls\n":::"memory");
|
||||
icache_inv_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void dcache_wb_line(unsigned long start)
|
||||
{
|
||||
asm volatile("dcache.cval1 %0\n"::"r"(start):"memory");
|
||||
sync_is();
|
||||
}
|
||||
|
||||
@ -53,10 +69,7 @@ void cache_wbinv_range(unsigned long start, unsigned long end)
|
||||
asm volatile("dcache.cval1 %0\n"::"r"(i):"memory");
|
||||
sync_is();
|
||||
|
||||
i = start & ~(L1_CACHE_BYTES - 1);
|
||||
for (; i < end; i += L1_CACHE_BYTES)
|
||||
asm volatile("icache.iva %0\n"::"r"(i):"memory");
|
||||
sync_is();
|
||||
icache_inv_range(start, end);
|
||||
}
|
||||
EXPORT_SYMBOL(cache_wbinv_range);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user