aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-07-02 02:44:09 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-07-02 02:44:09 -0400
commit59615ecdb516cf218c3699b02d87d9827dc3e0c7 (patch)
tree120c63e846caad2ba0f469cd608015e9a776193f
parentae9b12c72f831a2f956a5b30fd999f3018c43a89 (diff)
sh: Provide a global TLB flush for U/I-TLB clear.
This provides a sledgehammer approach for clearing the TLBs, only to be used in cases where we know we will never want to use the mappings again and have no interest in preserving state. This also destroys wired entries. The primary use for this is when we are either entering or exiting the kernel completely, in the latter case as a precursor for CPU reset by MMU. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/include/asm/tlbflush.h2
-rw-r--r--arch/sh/kernel/reboot.c4
-rw-r--r--arch/sh/mm/tlbflush_32.c16
-rw-r--r--arch/sh/mm/tlbflush_64.c5
4 files changed, 27 insertions, 0 deletions
diff --git a/arch/sh/include/asm/tlbflush.h b/arch/sh/include/asm/tlbflush.h
index e0ac97221ae6..0df66f0c7284 100644
--- a/arch/sh/include/asm/tlbflush.h
+++ b/arch/sh/include/asm/tlbflush.h
@@ -21,6 +21,8 @@ extern void local_flush_tlb_kernel_range(unsigned long start,
21 unsigned long end); 21 unsigned long end);
22extern void local_flush_tlb_one(unsigned long asid, unsigned long page); 22extern void local_flush_tlb_one(unsigned long asid, unsigned long page);
23 23
24extern void __flush_tlb_global(void);
25
24#ifdef CONFIG_SMP 26#ifdef CONFIG_SMP
25 27
26extern void flush_tlb_all(void); 28extern void flush_tlb_all(void);
diff --git a/arch/sh/kernel/reboot.c b/arch/sh/kernel/reboot.c
index b1fca66bb92e..ca6a5ca64015 100644
--- a/arch/sh/kernel/reboot.c
+++ b/arch/sh/kernel/reboot.c
@@ -9,6 +9,7 @@
9#include <asm/addrspace.h> 9#include <asm/addrspace.h>
10#include <asm/reboot.h> 10#include <asm/reboot.h>
11#include <asm/system.h> 11#include <asm/system.h>
12#include <asm/tlbflush.h>
12 13
13void (*pm_power_off)(void); 14void (*pm_power_off)(void);
14EXPORT_SYMBOL(pm_power_off); 15EXPORT_SYMBOL(pm_power_off);
@@ -25,6 +26,9 @@ static void native_machine_restart(char * __unused)
25{ 26{
26 local_irq_disable(); 27 local_irq_disable();
27 28
29 /* Destroy all of the TLBs in preparation for reset by MMU */
30 __flush_tlb_global();
31
28 /* Address error with SR.BL=1 first. */ 32 /* Address error with SR.BL=1 first. */
29 trigger_address_error(); 33 trigger_address_error();
30 34
diff --git a/arch/sh/mm/tlbflush_32.c b/arch/sh/mm/tlbflush_32.c
index 3fbe03ce8fe3..a6a20d6de4c0 100644
--- a/arch/sh/mm/tlbflush_32.c
+++ b/arch/sh/mm/tlbflush_32.c
@@ -119,3 +119,19 @@ void local_flush_tlb_mm(struct mm_struct *mm)
119 local_irq_restore(flags); 119 local_irq_restore(flags);
120 } 120 }
121} 121}
122
123void __flush_tlb_global(void)
124{
125 unsigned long flags;
126
127 local_irq_save(flags);
128
129 /*
130 * This is the most destructive of the TLB flushing options,
131 * and will tear down all of the UTLB/ITLB mappings, including
132 * wired entries.
133 */
134 __raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR);
135
136 local_irq_restore(flags);
137}
diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c
index 03db41cc1268..7f5810f5dfdc 100644
--- a/arch/sh/mm/tlbflush_64.c
+++ b/arch/sh/mm/tlbflush_64.c
@@ -455,6 +455,11 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
455 flush_tlb_all(); 455 flush_tlb_all();
456} 456}
457 457
458void __flush_tlb_global(void)
459{
460 flush_tlb_all();
461}
462
458void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) 463void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
459{ 464{
460} 465}