]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/asm-sparc64/tsb.h
Merge branch 'for_paulus' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc
[linux-2.6-omap-h63xx.git] / include / asm-sparc64 / tsb.h
index 44709cde56171570a6ddc3b7d2b1b608fa1e5cd6..e82612cd9f33635f7d198838c44f88f213e0cd2d 100644 (file)
@@ -12,6 +12,8 @@
  *
  *     ldxa            [%g0] ASI_{D,I}MMU_TSB_8KB_PTR, %g1
  *     ldxa            [%g0] ASI_{D,I}MMU, %g6
+ *     sllx            %g6, 22, %g6
+ *     srlx            %g6, 22, %g6
  *     ldda            [%g1] ASI_NUCLEUS_QUAD_LDD, %g4
  *     cmp             %g4, %g6
  *     bne,pn  %xcc, tsb_miss_{d,i}tlb
@@ -29,6 +31,9 @@
  * -------------------------------------------------
  *  63 61 60      48 47 42 41                     0
  *
+ * But actually, since we use per-mm TSB's, we zero out the CONTEXT
+ * field.
+ *
  * Like the powerpc hashtables we need to use locking in order to
  * synchronize while we update the entries.  PTE updates need locking
  * as well.
@@ -42,6 +47,9 @@
 #define TSB_TAG_LOCK_BIT       47
 #define TSB_TAG_LOCK_HIGH      (1 << (TSB_TAG_LOCK_BIT - 32))
 
+#define TSB_TAG_INVALID_BIT    46
+#define TSB_TAG_INVALID_HIGH   (1 << (TSB_TAG_INVALID_BIT - 32))
+
 #define TSB_MEMBAR     membar  #StoreStore
 
 /* Some cpus support physical address quad loads.  We want to use
  * kernel image, so we don't play these games for swapper_tsb access.
  */
 #ifndef __ASSEMBLY__
+struct tsb_ldquad_phys_patch_entry {
+       unsigned int    addr;
+       unsigned int    sun4u_insn;
+       unsigned int    sun4v_insn;
+};
+extern struct tsb_ldquad_phys_patch_entry __tsb_ldquad_phys_patch,
+       __tsb_ldquad_phys_patch_end;
+
 struct tsb_phys_patch_entry {
        unsigned int    addr;
        unsigned int    insn;
@@ -61,9 +77,10 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
 #endif
 #define TSB_LOAD_QUAD(TSB, REG)        \
 661:   ldda            [TSB] ASI_NUCLEUS_QUAD_LDD, REG; \
-       .section        .tsb_phys_patch, "ax"; \
+       .section        .tsb_ldquad_phys_patch, "ax"; \
        .word           661b; \
        ldda            [TSB] ASI_QUAD_LDD_PHYS, REG; \
+       ldda            [TSB] ASI_QUAD_LDD_PHYS_4V, REG; \
        .previous
 
 #define TSB_LOAD_TAG_HIGH(TSB, REG) \
@@ -226,6 +243,7 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
 #define KERNEL_TSB_SIZE_BYTES  (32 * 1024)
 #define KERNEL_TSB_NENTRIES    \
        (KERNEL_TSB_SIZE_BYTES / 16)
+#define KERNEL_TSB4M_NENTRIES  4096
 
        /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL
         * on TSB hit.  REG1, REG2, REG3, and REG4 are used as temporaries
@@ -246,4 +264,18 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
        be,a,pt         %xcc, OK_LABEL; \
         mov            REG4, REG1;
 
+       /* This version uses a trick, the TAG is already (VADDR >> 22) so
+        * we can make use of that for the index computation.
+        */
+#define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
+       sethi           %hi(swapper_4m_tsb), REG1; \
+       or              REG1, %lo(swapper_4m_tsb), REG1; \
+       and             TAG, (KERNEL_TSB_NENTRIES - 1), REG2; \
+       sllx            REG2, 4, REG2; \
+       add             REG1, REG2, REG2; \
+       KTSB_LOAD_QUAD(REG2, REG3); \
+       cmp             REG3, TAG; \
+       be,a,pt         %xcc, OK_LABEL; \
+        mov            REG4, REG1;
+
 #endif /* !(_SPARC64_TSB_H) */