/*1* arch/sh/mm/tlb-urb.c2*3* TLB entry wiring helpers for URB-equipped parts.4*5* Copyright (C) 2010 Matt Fleming6*7* This file is subject to the terms and conditions of the GNU General Public8* License. See the file "COPYING" in the main directory of this archive9* for more details.10*/11#include <linux/mm.h>12#include <linux/io.h>13#include <asm/tlb.h>14#include <asm/mmu_context.h>1516/*17* Load the entry for 'addr' into the TLB and wire the entry.18*/19void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte)20{21unsigned long status, flags;22int urb;2324local_irq_save(flags);2526status = __raw_readl(MMUCR);27urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT;28status &= ~MMUCR_URC;2930/*31* Make sure we're not trying to wire the last TLB entry slot.32*/33BUG_ON(!--urb);3435urb = urb % MMUCR_URB_NENTRIES;3637/*38* Insert this entry into the highest non-wired TLB slot (via39* the URC field).40*/41status |= (urb << MMUCR_URC_SHIFT);42__raw_writel(status, MMUCR);43ctrl_barrier();4445/* Load the entry into the TLB */46__update_tlb(vma, addr, pte);4748/* ... and wire it up. */49status = __raw_readl(MMUCR);5051status &= ~MMUCR_URB;52status |= (urb << MMUCR_URB_SHIFT);5354__raw_writel(status, MMUCR);55ctrl_barrier();5657local_irq_restore(flags);58}5960/*61* Unwire the last wired TLB entry.62*63* It should also be noted that it is not possible to wire and unwire64* TLB entries in an arbitrary order. If you wire TLB entry N, followed65* by entry N+1, you must unwire entry N+1 first, then entry N. In this66* respect, it works like a stack or LIFO queue.67*/68void tlb_unwire_entry(void)69{70unsigned long status, flags;71int urb;7273local_irq_save(flags);7475status = __raw_readl(MMUCR);76urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT;77status &= ~MMUCR_URB;7879/*80* Make sure we're not trying to unwire a TLB entry when none81* have been wired.82*/83BUG_ON(urb++ == MMUCR_URB_NENTRIES);8485urb = urb % MMUCR_URB_NENTRIES;8687status |= (urb << MMUCR_URB_SHIFT);88__raw_writel(status, MMUCR);89ctrl_barrier();9091local_irq_restore(flags);92}939495