Blackfin: add blackfin_invalidate_entire_icache for SMP systems
The KGDB code uses this when switching processors to make sure the icache is in a valid state. Signed-off-by: Sonic Zhang <sonic.zhang@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
This commit is contained in:
parent
2466ac6556
commit
47e9dedb72
|
@ -34,9 +34,13 @@
|
||||||
#define L1_CACHE_SHIFT_MAX 5
|
#define L1_CACHE_SHIFT_MAX 5
|
||||||
|
|
||||||
#if defined(CONFIG_SMP) && \
|
#if defined(CONFIG_SMP) && \
|
||||||
!defined(CONFIG_BFIN_CACHE_COHERENT) && \
|
!defined(CONFIG_BFIN_CACHE_COHERENT)
|
||||||
defined(CONFIG_BFIN_DCACHE)
|
# if defined(CONFIG_BFIN_ICACHE)
|
||||||
#define __ARCH_SYNC_CORE_DCACHE
|
# define __ARCH_SYNC_CORE_ICACHE
|
||||||
|
# endif
|
||||||
|
# if defined(CONFIG_BFIN_DCACHE)
|
||||||
|
# define __ARCH_SYNC_CORE_DCACHE
|
||||||
|
# endif
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
asmlinkage void __raw_smp_mark_barrier_asm(void);
|
asmlinkage void __raw_smp_mark_barrier_asm(void);
|
||||||
asmlinkage void __raw_smp_check_barrier_asm(void);
|
asmlinkage void __raw_smp_check_barrier_asm(void);
|
||||||
|
@ -51,6 +55,7 @@ static inline void smp_check_barrier(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void resync_core_dcache(void);
|
void resync_core_dcache(void);
|
||||||
|
void resync_core_icache(void);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ extern void blackfin_dcache_flush_range(unsigned long start_address, unsigned lo
|
||||||
extern void blackfin_dcache_invalidate_range(unsigned long start_address, unsigned long end_address);
|
extern void blackfin_dcache_invalidate_range(unsigned long start_address, unsigned long end_address);
|
||||||
extern void blackfin_dflush_page(void *page);
|
extern void blackfin_dflush_page(void *page);
|
||||||
extern void blackfin_invalidate_entire_dcache(void);
|
extern void blackfin_invalidate_entire_dcache(void);
|
||||||
|
extern void blackfin_invalidate_entire_icache(void);
|
||||||
|
|
||||||
#define flush_dcache_mmap_lock(mapping) do { } while (0)
|
#define flush_dcache_mmap_lock(mapping) do { } while (0)
|
||||||
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
|
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
|
||||||
|
|
|
@ -34,6 +34,7 @@ struct blackfin_cpudata {
|
||||||
unsigned int dmemctl;
|
unsigned int dmemctl;
|
||||||
unsigned long loops_per_jiffy;
|
unsigned long loops_per_jiffy;
|
||||||
unsigned long dcache_invld_count;
|
unsigned long dcache_invld_count;
|
||||||
|
unsigned long icache_invld_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_PER_CPU(struct blackfin_cpudata, cpu_data);
|
DECLARE_PER_CPU(struct blackfin_cpudata, cpu_data);
|
||||||
|
|
|
@ -1181,6 +1181,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||||
#ifdef __ARCH_SYNC_CORE_DCACHE
|
#ifdef __ARCH_SYNC_CORE_DCACHE
|
||||||
seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", cpudata->dcache_invld_count);
|
seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", cpudata->dcache_invld_count);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __ARCH_SYNC_CORE_ICACHE
|
||||||
|
seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", cpudata->icache_invld_count);
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_BFIN_ICACHE_LOCK
|
#ifdef CONFIG_BFIN_ICACHE_LOCK
|
||||||
switch ((cpudata->imemctl >> 3) & WAYALL_L) {
|
switch ((cpudata->imemctl >> 3) & WAYALL_L) {
|
||||||
case WAY0_L:
|
case WAY0_L:
|
||||||
|
|
|
@ -16,9 +16,21 @@
|
||||||
void blackfin_invalidate_entire_dcache(void)
|
void blackfin_invalidate_entire_dcache(void)
|
||||||
{
|
{
|
||||||
u32 dmem = bfin_read_DMEM_CONTROL();
|
u32 dmem = bfin_read_DMEM_CONTROL();
|
||||||
SSYNC();
|
|
||||||
bfin_write_DMEM_CONTROL(dmem & ~0xc);
|
bfin_write_DMEM_CONTROL(dmem & ~0xc);
|
||||||
SSYNC();
|
SSYNC();
|
||||||
bfin_write_DMEM_CONTROL(dmem);
|
bfin_write_DMEM_CONTROL(dmem);
|
||||||
SSYNC();
|
SSYNC();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Invalidate the Entire Instruction cache by
|
||||||
|
* clearing IMC bit
|
||||||
|
*/
|
||||||
|
void blackfin_invalidate_entire_icache(void)
|
||||||
|
{
|
||||||
|
u32 imem = bfin_read_IMEM_CONTROL();
|
||||||
|
bfin_write_IMEM_CONTROL(imem & ~0x4);
|
||||||
|
SSYNC();
|
||||||
|
bfin_write_IMEM_CONTROL(imem);
|
||||||
|
SSYNC();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -468,6 +468,17 @@ void smp_icache_flush_range_others(unsigned long start, unsigned long end)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(smp_icache_flush_range_others);
|
EXPORT_SYMBOL_GPL(smp_icache_flush_range_others);
|
||||||
|
|
||||||
|
#ifdef __ARCH_SYNC_CORE_ICACHE
|
||||||
|
void resync_core_icache(void)
|
||||||
|
{
|
||||||
|
unsigned int cpu = get_cpu();
|
||||||
|
blackfin_invalidate_entire_icache();
|
||||||
|
++per_cpu(cpu_data, cpu).icache_invld_count;
|
||||||
|
put_cpu();
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(resync_core_icache);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __ARCH_SYNC_CORE_DCACHE
|
#ifdef __ARCH_SYNC_CORE_DCACHE
|
||||||
unsigned long barrier_mask __attribute__ ((__section__(".l2.bss")));
|
unsigned long barrier_mask __attribute__ ((__section__(".l2.bss")));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue