aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSonic Zhang <sonic.zhang@analog.com>2009-06-10 04:57:08 -0400
committerMike Frysinger <vapier@gentoo.org>2009-06-13 07:20:07 -0400
commit47e9dedb720364e0adff0e99960fa294c6161f71 (patch)
treefa5bcb532023a89fa11995e5ceca5ed5dfeabbba /arch
parent2466ac65560ee8b7506eea3987aba9519355fd02 (diff)
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/blackfin/include/asm/cache.h11
-rw-r--r--arch/blackfin/include/asm/cacheflush.h1
-rw-r--r--arch/blackfin/include/asm/cpu.h1
-rw-r--r--arch/blackfin/kernel/setup.c3
-rw-r--r--arch/blackfin/mach-common/cache-c.c14
-rw-r--r--arch/blackfin/mach-common/smp.c11
6 files changed, 37 insertions, 4 deletions
diff --git a/arch/blackfin/include/asm/cache.h b/arch/blackfin/include/asm/cache.h
index 86637814cf25..2ef669ed9222 100644
--- a/arch/blackfin/include/asm/cache.h
+++ b/arch/blackfin/include/asm/cache.h
@@ -34,9 +34,13 @@
34#define L1_CACHE_SHIFT_MAX 5 34#define L1_CACHE_SHIFT_MAX 5
35 35
36#if defined(CONFIG_SMP) && \ 36#if defined(CONFIG_SMP) && \
37 !defined(CONFIG_BFIN_CACHE_COHERENT) && \ 37 !defined(CONFIG_BFIN_CACHE_COHERENT)
38 defined(CONFIG_BFIN_DCACHE) 38# if defined(CONFIG_BFIN_ICACHE)
39#define __ARCH_SYNC_CORE_DCACHE 39# define __ARCH_SYNC_CORE_ICACHE
40# endif
41# if defined(CONFIG_BFIN_DCACHE)
42# define __ARCH_SYNC_CORE_DCACHE
43# endif
40#ifndef __ASSEMBLY__ 44#ifndef __ASSEMBLY__
41asmlinkage void __raw_smp_mark_barrier_asm(void); 45asmlinkage void __raw_smp_mark_barrier_asm(void);
42asmlinkage void __raw_smp_check_barrier_asm(void); 46asmlinkage void __raw_smp_check_barrier_asm(void);
@@ -51,6 +55,7 @@ static inline void smp_check_barrier(void)
51} 55}
52 56
53void resync_core_dcache(void); 57void resync_core_dcache(void);
58void resync_core_icache(void);
54#endif 59#endif
55#endif 60#endif
56 61
diff --git a/arch/blackfin/include/asm/cacheflush.h b/arch/blackfin/include/asm/cacheflush.h
index 18bc4f71fe2c..5c17dee53b5d 100644
--- a/arch/blackfin/include/asm/cacheflush.h
+++ b/arch/blackfin/include/asm/cacheflush.h
@@ -37,6 +37,7 @@ extern void blackfin_dcache_flush_range(unsigned long start_address, unsigned lo
37extern void blackfin_dcache_invalidate_range(unsigned long start_address, unsigned long end_address); 37extern void blackfin_dcache_invalidate_range(unsigned long start_address, unsigned long end_address);
38extern void blackfin_dflush_page(void *page); 38extern void blackfin_dflush_page(void *page);
39extern void blackfin_invalidate_entire_dcache(void); 39extern void blackfin_invalidate_entire_dcache(void);
40extern void blackfin_invalidate_entire_icache(void);
40 41
41#define flush_dcache_mmap_lock(mapping) do { } while (0) 42#define flush_dcache_mmap_lock(mapping) do { } while (0)
42#define flush_dcache_mmap_unlock(mapping) do { } while (0) 43#define flush_dcache_mmap_unlock(mapping) do { } while (0)
diff --git a/arch/blackfin/include/asm/cpu.h b/arch/blackfin/include/asm/cpu.h
index c2594ef877f6..565b8136855e 100644
--- a/arch/blackfin/include/asm/cpu.h
+++ b/arch/blackfin/include/asm/cpu.h
@@ -34,6 +34,7 @@ struct blackfin_cpudata {
34 unsigned int dmemctl; 34 unsigned int dmemctl;
35 unsigned long loops_per_jiffy; 35 unsigned long loops_per_jiffy;
36 unsigned long dcache_invld_count; 36 unsigned long dcache_invld_count;
37 unsigned long icache_invld_count;
37}; 38};
38 39
39DECLARE_PER_CPU(struct blackfin_cpudata, cpu_data); 40DECLARE_PER_CPU(struct blackfin_cpudata, cpu_data);
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index f5f516e817f4..6454babdfaff 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -1181,6 +1181,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
1181#ifdef __ARCH_SYNC_CORE_DCACHE 1181#ifdef __ARCH_SYNC_CORE_DCACHE
1182 seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", cpudata->dcache_invld_count); 1182 seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", cpudata->dcache_invld_count);
1183#endif 1183#endif
1184#ifdef __ARCH_SYNC_CORE_ICACHE
1185 seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", cpudata->icache_invld_count);
1186#endif
1184#ifdef CONFIG_BFIN_ICACHE_LOCK 1187#ifdef CONFIG_BFIN_ICACHE_LOCK
1185 switch ((cpudata->imemctl >> 3) & WAYALL_L) { 1188 switch ((cpudata->imemctl >> 3) & WAYALL_L) {
1186 case WAY0_L: 1189 case WAY0_L:
diff --git a/arch/blackfin/mach-common/cache-c.c b/arch/blackfin/mach-common/cache-c.c
index e6ab1f815123..b59ce3cb3807 100644
--- a/arch/blackfin/mach-common/cache-c.c
+++ b/arch/blackfin/mach-common/cache-c.c
@@ -16,9 +16,21 @@
16void blackfin_invalidate_entire_dcache(void) 16void blackfin_invalidate_entire_dcache(void)
17{ 17{
18 u32 dmem = bfin_read_DMEM_CONTROL(); 18 u32 dmem = bfin_read_DMEM_CONTROL();
19 SSYNC();
20 bfin_write_DMEM_CONTROL(dmem & ~0xc); 19 bfin_write_DMEM_CONTROL(dmem & ~0xc);
21 SSYNC(); 20 SSYNC();
22 bfin_write_DMEM_CONTROL(dmem); 21 bfin_write_DMEM_CONTROL(dmem);
23 SSYNC(); 22 SSYNC();
24} 23}
24
25/* Invalidate the Entire Instruction cache by
26 * clearing IMC bit
27 */
28void blackfin_invalidate_entire_icache(void)
29{
30 u32 imem = bfin_read_IMEM_CONTROL();
31 bfin_write_IMEM_CONTROL(imem & ~0x4);
32 SSYNC();
33 bfin_write_IMEM_CONTROL(imem);
34 SSYNC();
35}
36
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index 3b8ebaee77f2..c187da2448bf 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -468,6 +468,17 @@ void smp_icache_flush_range_others(unsigned long start, unsigned long end)
468} 468}
469EXPORT_SYMBOL_GPL(smp_icache_flush_range_others); 469EXPORT_SYMBOL_GPL(smp_icache_flush_range_others);
470 470
471#ifdef __ARCH_SYNC_CORE_ICACHE
472void resync_core_icache(void)
473{
474 unsigned int cpu = get_cpu();
475 blackfin_invalidate_entire_icache();
476 ++per_cpu(cpu_data, cpu).icache_invld_count;
477 put_cpu();
478}
479EXPORT_SYMBOL(resync_core_icache);
480#endif
481
471#ifdef __ARCH_SYNC_CORE_DCACHE 482#ifdef __ARCH_SYNC_CORE_DCACHE
472unsigned long barrier_mask __attribute__ ((__section__(".l2.bss"))); 483unsigned long barrier_mask __attribute__ ((__section__(".l2.bss")));
473 484