sh: Provide a global TLB flush for U/I-TLB clear.
authorPaul Mundt <lethal@linux-sh.org>
Fri, 2 Jul 2010 06:44:09 +0000 (15:44 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Fri, 2 Jul 2010 06:44:09 +0000 (15:44 +0900)
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>
arch/sh/include/asm/tlbflush.h
arch/sh/kernel/reboot.c
arch/sh/mm/tlbflush_32.c
arch/sh/mm/tlbflush_64.c

index e0ac97221ae6bb6a6351331ce72b884fc229ecd1..0df66f0c72847c37a9598f33126237a442ec4366 100644 (file)
@@ -21,6 +21,8 @@ extern void local_flush_tlb_kernel_range(unsigned long start,
                                         unsigned long end);
 extern void local_flush_tlb_one(unsigned long asid, unsigned long page);
 
+extern void __flush_tlb_global(void);
+
 #ifdef CONFIG_SMP
 
 extern void flush_tlb_all(void);
index b1fca66bb92eca13b57e2ed6f94cc4ae383cbebd..ca6a5ca64015bf223e64e1303e07bdfa17fd03e8 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/addrspace.h>
 #include <asm/reboot.h>
 #include <asm/system.h>
+#include <asm/tlbflush.h>
 
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
@@ -25,6 +26,9 @@ static void native_machine_restart(char * __unused)
 {
        local_irq_disable();
 
+       /* Destroy all of the TLBs in preparation for reset by MMU */
+       __flush_tlb_global();
+
        /* Address error with SR.BL=1 first. */
        trigger_address_error();
 
index 3fbe03ce8fe3a665768516dd4e341e783e164e69..a6a20d6de4c0b9535679a85ebbcc8522810b86cc 100644 (file)
@@ -119,3 +119,19 @@ void local_flush_tlb_mm(struct mm_struct *mm)
                local_irq_restore(flags);
        }
 }
+
+void __flush_tlb_global(void)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+
+       /*
+        * This is the most destructive of the TLB flushing options,
+        * and will tear down all of the UTLB/ITLB mappings, including
+        * wired entries.
+        */
+       __raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR);
+
+       local_irq_restore(flags);
+}
index 03db41cc126854bdf5b8e61ef7e918d6558e7db3..7f5810f5dfdc4b5141aabcacf7ca6b61f1b5bba5 100644 (file)
@@ -455,6 +455,11 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
         flush_tlb_all();
 }
 
+void __flush_tlb_global(void)
+{
+       flush_tlb_all();
+}
+
 void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
 }