diff options
Diffstat (limited to 'arch/sh/mm/tlb-sh3.c')
| -rw-r--r-- | arch/sh/mm/tlb-sh3.c | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c index e5e76eb7ee0..6554fb439f0 100644 --- a/arch/sh/mm/tlb-sh3.c +++ b/arch/sh/mm/tlb-sh3.c @@ -8,9 +8,51 @@ * * Released under the terms of the GNU GPL v2.0. */ -#include <linux/io.h> -#include <asm/system.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/types.h> +#include <linux/ptrace.h> +#include <linux/mman.h> +#include <linux/mm.h> +#include <linux/smp.h> +#include <linux/interrupt.h> + +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/pgalloc.h> #include <asm/mmu_context.h> +#include <asm/cacheflush.h> + +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) +{ + unsigned long flags, pteval, vpn; + + /* + * Handle debugger faulting in for debugee. + */ + if (vma && current->active_mm != vma->vm_mm) + return; + + local_irq_save(flags); + + /* Set PTEH register */ + vpn = (address & MMU_VPN_MASK) | get_asid(); + __raw_writel(vpn, MMU_PTEH); + + pteval = pte_val(pte); + + /* Set PTEL register */ + pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */ + /* conveniently, we want all the software flags to be 0 anyway */ + __raw_writel(pteval, MMU_PTEL); + + /* Load the TLB */ + asm volatile("ldtlb": /* no output */ : /* no input */ : "memory"); + local_irq_restore(flags); +} void local_flush_tlb_one(unsigned long asid, unsigned long page) { @@ -32,5 +74,24 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page) } for (i = 0; i < ways; i++) - ctrl_outl(data, addr + (i << 8)); + __raw_writel(data, addr + (i << 8)); +} + +void local_flush_tlb_all(void) +{ + unsigned long flags, status; + + /* + * Flush all the TLB. + * + * Write to the MMU control register's bit: + * TF-bit for SH-3, TI-bit for SH-4. + * It's same position, bit #2. + */ + local_irq_save(flags); + status = __raw_readl(MMUCR); + status |= 0x04; + __raw_writel(status, MMUCR); + ctrl_barrier(); + local_irq_restore(flags); } |
