diff options
author | Matt Fleming <matt@console-pimps.org> | 2010-03-26 11:37:16 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-03-26 11:37:16 +0900 |
commit | 4539282dbc20fe612113c8f267d51a90d46a7f50 (patch) | |
tree | 579f4785bd2e06339291df2c1d17c0b7be93df0c /arch/sh/mm | |
parent | 01e77706cdde7c0b47e5ca1f4284a795504c7c40 (diff) |
sh: update the TLB replacement counter for entry wiring.
Presently the TLB wiring code depends on MMUCR.URB for working out where
to place the wired entry, but fails to take the replacment counter in to
consideration. This fixes up the wiring logic and ensures that wired
entries remain so.
Signed-off-by: Matt Fleming <matt@console-pimps.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/mm')
-rw-r--r-- | arch/sh/mm/tlb-urb.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/arch/sh/mm/tlb-urb.c b/arch/sh/mm/tlb-urb.c index bb5b9098956d..c92ce20db39b 100644 --- a/arch/sh/mm/tlb-urb.c +++ b/arch/sh/mm/tlb-urb.c @@ -24,13 +24,9 @@ void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte) local_irq_save(flags); - /* Load the entry into the TLB */ - __update_tlb(vma, addr, pte); - - /* ... and wire it up. */ status = __raw_readl(MMUCR); urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT; - status &= ~MMUCR_URB; + status &= ~MMUCR_URC; /* * Make sure we're not trying to wire the last TLB entry slot. @@ -39,7 +35,23 @@ void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte) urb = urb % MMUCR_URB_NENTRIES; + /* + * Insert this entry into the highest non-wired TLB slot (via + * the URC field). + */ + status |= (urb << MMUCR_URC_SHIFT); + __raw_writel(status, MMUCR); + ctrl_barrier(); + + /* Load the entry into the TLB */ + __update_tlb(vma, addr, pte); + + /* ... and wire it up. */ + status = __raw_readl(MMUCR); + + status &= ~MMUCR_URB; status |= (urb << MMUCR_URB_SHIFT); + __raw_writel(status, MMUCR); ctrl_barrier(); |