[SPARC64]: Preload TSB entries from update_mmu_cache().
authorDavid S. Miller <davem@davemloft.net>
Wed, 1 Feb 2006 02:32:04 +0000 (18:32 -0800)
committerDavid S. Miller <davem@sunset.davemloft.net>
Mon, 20 Mar 2006 09:11:19 +0000 (01:11 -0800)
Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc64/kernel/tsb.S
arch/sparc64/mm/init.c
include/asm-sparc64/mmu.h

index fe266ba..08405ed 100644 (file)
@@ -126,6 +126,23 @@ winfix_trampoline:
        wrpr    %g3, %tnpc                      ! Write it into TNPC
        done                                    ! Trap return
 
+       /* Insert an entry into the TSB.
+        *
+        * %o0: TSB entry pointer
+        * %o1: tag
+        * %o2: pte
+        */
+       .align  32
+       .globl  tsb_insert
+tsb_insert:
+       rdpr    %pstate, %o5
+       wrpr    %o5, PSTATE_IE, %pstate
+       TSB_LOCK_TAG(%o0, %g2, %g3)
+       TSB_WRITE(%o0, %o2, %o1)
+       wrpr    %o5, %pstate
+       retl
+        nop
+
        /* Reload MMU related context switch state at
         * schedule() time.
         *
index a8119cb..1e8a5a3 100644 (file)
@@ -277,6 +277,16 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p
        mm_rss = get_mm_rss(mm);
        if (mm_rss >= mm->context.tsb_rss_limit)
                tsb_grow(mm, mm_rss, GFP_ATOMIC);
+
+       if ((pte_val(pte) & _PAGE_ALL_SZ_BITS) == _PAGE_SZBITS) {
+               struct tsb *tsb;
+               unsigned long tag;
+
+               tsb = &mm->context.tsb[(address >> PAGE_SHIFT) &
+                                      (mm->context.tsb_nentries - 1UL)];
+               tag = (address >> 22UL) | CTX_HWBITS(mm->context) << 48UL;
+               tsb_insert(tsb, tag, pte_val(pte));
+       }
 }
 
 void flush_dcache_page(struct page *page)
index 76008ff..18f98ed 100644 (file)
@@ -97,6 +97,8 @@ struct tsb {
        unsigned long pte;
 } __attribute__((aligned(TSB_ENTRY_ALIGNMENT)));
 
+extern void tsb_insert(struct tsb *ent, unsigned long tag, unsigned long pte);
+
 typedef struct {
        unsigned long   sparc64_ctx_val;
        struct tsb      *tsb;