aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2006-03-13 04:23:03 -0500
committerRalf Baechle <ralf@linux-mips.org>2006-03-18 11:59:27 -0500
commitde62893bc0725f8b5f0445250577cd7a10b2d8f8 (patch)
tree3a5d77b8e8aa66113431ebe287c552749c2e8fee
parenta3c4946db4fe64cb21b66a09e89890678aac6d65 (diff)
[MIPS] local_r4k_flush_cache_page fix
If dcache_size != icache_size or dcache_size != scache_size, or set-associative cache, icache/scache does not flushed properly. Make blast_?cache_page_indexed() masks its index value correctly. Also, use physical address for physically indexed pcache/scache. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/mm/c-r4k.c13
-rw-r--r--arch/mips/mm/c-tx39.c1
-rw-r--r--include/asm-mips/cpu-features.h3
-rw-r--r--include/asm-mips/cpu-info.h1
-rw-r--r--include/asm-mips/r4kcache.h3
5 files changed, 15 insertions, 6 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 0668e9bfce41..9572ed44f0d5 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -375,6 +375,7 @@ static void r4k_flush_cache_mm(struct mm_struct *mm)
375struct flush_cache_page_args { 375struct flush_cache_page_args {
376 struct vm_area_struct *vma; 376 struct vm_area_struct *vma;
377 unsigned long addr; 377 unsigned long addr;
378 unsigned long pfn;
378}; 379};
379 380
380static inline void local_r4k_flush_cache_page(void *args) 381static inline void local_r4k_flush_cache_page(void *args)
@@ -382,6 +383,7 @@ static inline void local_r4k_flush_cache_page(void *args)
382 struct flush_cache_page_args *fcp_args = args; 383 struct flush_cache_page_args *fcp_args = args;
383 struct vm_area_struct *vma = fcp_args->vma; 384 struct vm_area_struct *vma = fcp_args->vma;
384 unsigned long addr = fcp_args->addr; 385 unsigned long addr = fcp_args->addr;
386 unsigned long paddr = fcp_args->pfn << PAGE_SHIFT;
385 int exec = vma->vm_flags & VM_EXEC; 387 int exec = vma->vm_flags & VM_EXEC;
386 struct mm_struct *mm = vma->vm_mm; 388 struct mm_struct *mm = vma->vm_mm;
387 pgd_t *pgdp; 389 pgd_t *pgdp;
@@ -431,11 +433,12 @@ static inline void local_r4k_flush_cache_page(void *args)
431 * Do indexed flush, too much work to get the (possible) TLB refills 433 * Do indexed flush, too much work to get the (possible) TLB refills
432 * to work correctly. 434 * to work correctly.
433 */ 435 */
434 addr = INDEX_BASE + (addr & (dcache_size - 1));
435 if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { 436 if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
436 r4k_blast_dcache_page_indexed(addr); 437 r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ?
437 if (exec && !cpu_icache_snoops_remote_store) 438 paddr : addr);
438 r4k_blast_scache_page_indexed(addr); 439 if (exec && !cpu_icache_snoops_remote_store) {
440 r4k_blast_scache_page_indexed(paddr);
441 }
439 } 442 }
440 if (exec) { 443 if (exec) {
441 if (cpu_has_vtag_icache) { 444 if (cpu_has_vtag_icache) {
@@ -455,6 +458,7 @@ static void r4k_flush_cache_page(struct vm_area_struct *vma,
455 458
456 args.vma = vma; 459 args.vma = vma;
457 args.addr = addr; 460 args.addr = addr;
461 args.pfn = pfn;
458 462
459 on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1); 463 on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
460} 464}
@@ -956,6 +960,7 @@ static void __init probe_pcache(void)
956 switch (c->cputype) { 960 switch (c->cputype) {
957 case CPU_20KC: 961 case CPU_20KC:
958 case CPU_25KF: 962 case CPU_25KF:
963 c->dcache.flags |= MIPS_CACHE_PINDEX;
959 case CPU_R10000: 964 case CPU_R10000:
960 case CPU_R12000: 965 case CPU_R12000:
961 case CPU_SB1: 966 case CPU_SB1:
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index 7c572bea4a98..fe232e3988e3 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -210,7 +210,6 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
210 * Do indexed flush, too much work to get the (possible) TLB refills 210 * Do indexed flush, too much work to get the (possible) TLB refills
211 * to work correctly. 211 * to work correctly.
212 */ 212 */
213 page = (KSEG0 + (page & (dcache_size - 1)));
214 if (cpu_has_dc_aliases || exec) 213 if (cpu_has_dc_aliases || exec)
215 tx39_blast_dcache_page_indexed(page); 214 tx39_blast_dcache_page_indexed(page);
216 if (exec) 215 if (exec)
diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
index 78c9cc2735d5..3f2b6d9ac45e 100644
--- a/include/asm-mips/cpu-features.h
+++ b/include/asm-mips/cpu-features.h
@@ -96,6 +96,9 @@
96#ifndef cpu_has_ic_fills_f_dc 96#ifndef cpu_has_ic_fills_f_dc
97#define cpu_has_ic_fills_f_dc (cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC) 97#define cpu_has_ic_fills_f_dc (cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC)
98#endif 98#endif
99#ifndef cpu_has_pindexed_dcache
100#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
101#endif
99 102
100/* 103/*
101 * I-Cache snoops remote store. This only matters on SMP. Some multiprocessors 104 * I-Cache snoops remote store. This only matters on SMP. Some multiprocessors
diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h
index d5cf519f8fcc..140be1c67da7 100644
--- a/include/asm-mips/cpu-info.h
+++ b/include/asm-mips/cpu-info.h
@@ -39,6 +39,7 @@ struct cache_desc {
39#define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */ 39#define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */
40#define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */ 40#define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */
41#define MIPS_IC_SNOOPS_REMOTE 0x00000010 /* Ic snoops remote stores */ 41#define MIPS_IC_SNOOPS_REMOTE 0x00000010 /* Ic snoops remote stores */
42#define MIPS_CACHE_PINDEX 0x00000020 /* Physically indexed cache */
42 43
43struct cpuinfo_mips { 44struct cpuinfo_mips {
44 unsigned long udelay_val; 45 unsigned long udelay_val;
diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h
index 9632c27dad15..0bcb79a58ee9 100644
--- a/include/asm-mips/r4kcache.h
+++ b/include/asm-mips/r4kcache.h
@@ -257,7 +257,8 @@ static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \
257 \ 257 \
258static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \ 258static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
259{ \ 259{ \
260 unsigned long start = page; \ 260 unsigned long indexmask = current_cpu_data.desc.waysize - 1; \
261 unsigned long start = INDEX_BASE + (page & indexmask); \
261 unsigned long end = start + PAGE_SIZE; \ 262 unsigned long end = start + PAGE_SIZE; \
262 unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit; \ 263 unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit; \
263 unsigned long ws_end = current_cpu_data.desc.ways << \ 264 unsigned long ws_end = current_cpu_data.desc.ways << \