summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2015-05-27 14:15:08 +0100
committerRalf Baechle <ralf@linux-mips.org>2015-06-21 21:52:39 +0200
commitdbfbf60f4a6b058b873b0d37e272fc3bd2f1356d (patch)
treee869b4b640ffbd026fe29c1be421d9cd83891d39
parent24ca1d9896bb9bbd7625e3596bac4ea2fe74c725 (diff)
MIPS: tlb-r3k: Also invalidate wired TLB entries on boot
Most R3k processor implementations have their 8 first TLB entries fixed as wired, so we always skip them in TLB invalidation. That however means any leftover entries present there at boot will stay throughout the life of the kernel, unless replaced with new ones. So rename `local_flush_tlb_all' to `local_flush_tlb_from' and make it accept the TLB entry to start from. Then use 0 initially at bootstrap, and the first regular entry later on, bypassing any wired entries. Wrap the latter arrangement into a new `local_flush_tlb_all' entry point. There is no need to disable interrupts in the call made from `tlb_init' because it's made before the interrupt subsystem has been initialised; this is also true for secondary processors, should we ever support R3k SMP. So move this piece of code to new `local_flush_tlb_all'. Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Cc: James Hogan <james.hogan@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/10194/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/mm/tlb-r3k.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c
index 4094bbd42adf..b34b75d62a73 100644
--- a/arch/mips/mm/tlb-r3k.c
+++ b/arch/mips/mm/tlb-r3k.c
@@ -39,20 +39,12 @@ extern void build_tlb_refill_handler(void);
int r3k_have_wired_reg; /* should be in cpu_data? */
/* TLB operations. */
-void local_flush_tlb_all(void)
+static void local_flush_tlb_from(int entry)
{
- unsigned long flags;
unsigned long old_ctx;
- int entry;
-#ifdef DEBUG_TLB
- printk("[tlball]");
-#endif
-
- local_irq_save(flags);
old_ctx = read_c0_entryhi() & ASID_MASK;
write_c0_entrylo0(0);
- entry = r3k_have_wired_reg ? read_c0_wired() : 8;
for (; entry < current_cpu_data.tlbsize; entry++) {
write_c0_index(entry << 8);
write_c0_entryhi((entry | 0x80000) << 12);
@@ -60,6 +52,17 @@ void local_flush_tlb_all(void)
tlb_write_indexed();
}
write_c0_entryhi(old_ctx);
+}
+
+void local_flush_tlb_all(void)
+{
+ unsigned long flags;
+
+#ifdef DEBUG_TLB
+ printk("[tlball]");
+#endif
+ local_irq_save(flags);
+ local_flush_tlb_from(r3k_have_wired_reg ? read_c0_wired() : 8);
local_irq_restore(flags);
}
@@ -277,7 +280,6 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
void tlb_init(void)
{
- local_flush_tlb_all();
-
+ local_flush_tlb_from(0);
build_tlb_refill_handler();
}