aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/tlb-r4k.c
diff options
context:
space:
mode:
authorHuacai Chen <chenhc@lemote.com>2016-03-03 09:45:11 +0800
committerRalf Baechle <ralf@linux-mips.org>2016-05-13 14:02:14 +0200
commit06e4814eec988f7ee01c29762f945b3ff59355fb (patch)
treed23c5f9cf1b096b3bc67f458a6b0984b664d7cbf /arch/mips/mm/tlb-r4k.c
parentMIPS: Loongson-3: Set cache flush handlers to cache_noop (diff)
downloadlinux-dev-06e4814eec988f7ee01c29762f945b3ff59355fb.tar.xz
linux-dev-06e4814eec988f7ee01c29762f945b3ff59355fb.zip
MIPS: Loongson: Invalidate special TLBs when needed
Loongson-2 has a 4 entry itlb which is a subset of jtlb, Loongson-3 has a 4 entry itlb and a 4 entry dtlb which are subsets of jtlb. We should write diag register to invalidate itlb/dtlb when flushing jtlb because itlb/dtlb are not totally transparent to software. For Loongson-3A R2 (and newer), we should invalidate ITLB, DTLB, VTLB and FTLB before we enable/disable FTLB. Signed-off-by: Huacai Chen <chenhc@lemote.com> Cc: Aurelien Jarno <aurelien@aurel32.net> Cc: Steven J . Hill <sjhill@realitydiluted.com> Cc: Fuxin Zhang <zhangfx@lemote.com> Cc: Zhangjin Wu <wuzhangjin@gmail.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/12753/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mm/tlb-r4k.c')
-rw-r--r--arch/mips/mm/tlb-r4k.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index c17d7627f872..4c3362b46066 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -28,25 +28,28 @@
extern void build_tlb_refill_handler(void);
/*
- * LOONGSON2/3 has a 4 entry itlb which is a subset of dtlb,
- * unfortunately, itlb is not totally transparent to software.
+ * LOONGSON-2 has a 4 entry itlb which is a subset of jtlb, LOONGSON-3 has
+ * a 4 entry itlb and a 4 entry dtlb which are subsets of jtlb. Unfortunately,
+ * itlb/dtlb are not totally transparent to software.
*/
-static inline void flush_itlb(void)
+static inline void flush_micro_tlb(void)
{
switch (current_cpu_type()) {
case CPU_LOONGSON2:
+ write_c0_diag(LOONGSON_DIAG_ITLB);
+ break;
case CPU_LOONGSON3:
- write_c0_diag(4);
+ write_c0_diag(LOONGSON_DIAG_ITLB | LOONGSON_DIAG_DTLB);
break;
default:
break;
}
}
-static inline void flush_itlb_vm(struct vm_area_struct *vma)
+static inline void flush_micro_tlb_vm(struct vm_area_struct *vma)
{
if (vma->vm_flags & VM_EXEC)
- flush_itlb();
+ flush_micro_tlb();
}
void local_flush_tlb_all(void)
@@ -93,7 +96,7 @@ void local_flush_tlb_all(void)
tlbw_use_hazard();
write_c0_entryhi(old_ctx);
htw_start();
- flush_itlb();
+ flush_micro_tlb();
local_irq_restore(flags);
}
EXPORT_SYMBOL(local_flush_tlb_all);
@@ -159,7 +162,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
} else {
drop_mmu_context(mm, cpu);
}
- flush_itlb();
+ flush_micro_tlb();
local_irq_restore(flags);
}
}
@@ -205,7 +208,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
} else {
local_flush_tlb_all();
}
- flush_itlb();
+ flush_micro_tlb();
local_irq_restore(flags);
}
@@ -240,7 +243,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
finish:
write_c0_entryhi(oldpid);
htw_start();
- flush_itlb_vm(vma);
+ flush_micro_tlb_vm(vma);
local_irq_restore(flags);
}
}
@@ -274,7 +277,7 @@ void local_flush_tlb_one(unsigned long page)
}
write_c0_entryhi(oldpid);
htw_start();
- flush_itlb();
+ flush_micro_tlb();
local_irq_restore(flags);
}
@@ -357,7 +360,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
}
tlbw_use_hazard();
htw_start();
- flush_itlb_vm(vma);
+ flush_micro_tlb_vm(vma);
local_irq_restore(flags);
}