sh: update the TLB replacement counter for entry wiring.
authorMatt Fleming <matt@console-pimps.org>
Fri, 26 Mar 2010 02:37:16 +0000 (11:37 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Fri, 26 Mar 2010 02:37:16 +0000 (11:37 +0900)
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>
arch/sh/include/cpu-sh4/cpu/mmu_context.h
arch/sh/mm/tlb-urb.c

index 310ec92f27591645749b7df8cdf19e5f81d05de6..5963124c1d4ad0f105605e139ea6f1e7d55cc845 100644 (file)
@@ -30,6 +30,8 @@
 #define MMUCR_URB              0x00FC0000
 #define MMUCR_URB_SHIFT                18
 #define MMUCR_URB_NENTRIES     64
+#define MMUCR_URC              0x0000FC00
+#define MMUCR_URC_SHIFT                10
 
 #if defined(CONFIG_32BIT) && defined(CONFIG_CPU_SUBTYPE_ST40)
 #define MMUCR_SE               (1 << 4)
index bb5b9098956d9157c2d1bf7c4166b20990bd99a0..c92ce20db39bf478dd6db83a0c3ed6dc430ca027 100644 (file)
@@ -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();