Skip to content

Commit

Permalink
[MIPS] local_r4k_flush_cache_page fix
Browse files Browse the repository at this point in the history
    
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>
  • Loading branch information
Atsushi Nemoto authored and Ralf Baechle committed Mar 18, 2006
1 parent a3c4946 commit de62893
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 6 deletions.
13 changes: 9 additions & 4 deletions arch/mips/mm/c-r4k.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,13 +375,15 @@ static void r4k_flush_cache_mm(struct mm_struct *mm)
struct flush_cache_page_args {
struct vm_area_struct *vma;
unsigned long addr;
unsigned long pfn;
};

static inline void local_r4k_flush_cache_page(void *args)
{
struct flush_cache_page_args *fcp_args = args;
struct vm_area_struct *vma = fcp_args->vma;
unsigned long addr = fcp_args->addr;
unsigned long paddr = fcp_args->pfn << PAGE_SHIFT;
int exec = vma->vm_flags & VM_EXEC;
struct mm_struct *mm = vma->vm_mm;
pgd_t *pgdp;
Expand Down Expand Up @@ -431,11 +433,12 @@ static inline void local_r4k_flush_cache_page(void *args)
* Do indexed flush, too much work to get the (possible) TLB refills
* to work correctly.
*/
addr = INDEX_BASE + (addr & (dcache_size - 1));
if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
r4k_blast_dcache_page_indexed(addr);
if (exec && !cpu_icache_snoops_remote_store)
r4k_blast_scache_page_indexed(addr);
r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ?
paddr : addr);
if (exec && !cpu_icache_snoops_remote_store) {
r4k_blast_scache_page_indexed(paddr);
}
}
if (exec) {
if (cpu_has_vtag_icache) {
Expand All @@ -455,6 +458,7 @@ static void r4k_flush_cache_page(struct vm_area_struct *vma,

args.vma = vma;
args.addr = addr;
args.pfn = pfn;

on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
}
Expand Down Expand Up @@ -956,6 +960,7 @@ static void __init probe_pcache(void)
switch (c->cputype) {
case CPU_20KC:
case CPU_25KF:
c->dcache.flags |= MIPS_CACHE_PINDEX;
case CPU_R10000:
case CPU_R12000:
case CPU_SB1:
Expand Down
1 change: 0 additions & 1 deletion arch/mips/mm/c-tx39.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
* Do indexed flush, too much work to get the (possible) TLB refills
* to work correctly.
*/
page = (KSEG0 + (page & (dcache_size - 1)));
if (cpu_has_dc_aliases || exec)
tx39_blast_dcache_page_indexed(page);
if (exec)
Expand Down
3 changes: 3 additions & 0 deletions include/asm-mips/cpu-features.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@
#ifndef cpu_has_ic_fills_f_dc
#define cpu_has_ic_fills_f_dc (cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC)
#endif
#ifndef cpu_has_pindexed_dcache
#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
#endif

/*
* I-Cache snoops remote store. This only matters on SMP. Some multiprocessors
Expand Down
1 change: 1 addition & 0 deletions include/asm-mips/cpu-info.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct cache_desc {
#define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */
#define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */
#define MIPS_IC_SNOOPS_REMOTE 0x00000010 /* Ic snoops remote stores */
#define MIPS_CACHE_PINDEX 0x00000020 /* Physically indexed cache */

struct cpuinfo_mips {
unsigned long udelay_val;
Expand Down
3 changes: 2 additions & 1 deletion include/asm-mips/r4kcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,8 @@ static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \
\
static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
{ \
unsigned long start = page; \
unsigned long indexmask = current_cpu_data.desc.waysize - 1; \
unsigned long start = INDEX_BASE + (page & indexmask); \
unsigned long end = start + PAGE_SIZE; \
unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit; \
unsigned long ws_end = current_cpu_data.desc.ways << \
Expand Down

0 comments on commit de62893

Please sign in to comment.