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>
Šī revīzija ir iekļauta:
@@ -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);
|
||||
|
||||
|
Atsaukties uz šo jaunā problēmā
Block a user