aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/tsb.S
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-17 21:01:02 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:13:34 -0500
commit8b234274418d6d79527c4ac3a72da446ca4cb35f (patch)
treeab4ab14fa7f1cab7889ecc2339f0261253a5d0e1 /arch/sparc64/kernel/tsb.S
parent7adb37fe80d06cbd40de9b225b12a3a9ec40b6bb (diff)
[SPARC64]: More TLB/TSB handling fixes.
The SUN4V convention with non-shared TSBs is that the context bit of the TAG is clear. So we have to choose an "invalid" bit and initialize new TSBs appropriately. Otherwise a zero TAG looks "valid". Make sure, for the window fixup cases, that we use the right global registers and that we don't potentially trample on the live global registers in etrap/rtrap handling (%g2 and %g6) and that we put the missing virtual address properly in %g5. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/tsb.S')
-rw-r--r--arch/sparc64/kernel/tsb.S17
1 files changed, 11 insertions, 6 deletions
diff --git a/arch/sparc64/kernel/tsb.S b/arch/sparc64/kernel/tsb.S
index a17259cf34b8..cc225c0563c3 100644
--- a/arch/sparc64/kernel/tsb.S
+++ b/arch/sparc64/kernel/tsb.S
@@ -36,7 +36,7 @@ tsb_miss_itlb:
36 /* At this point we have: 36 /* At this point we have:
37 * %g4 -- missing virtual address 37 * %g4 -- missing virtual address
38 * %g1 -- TSB entry address 38 * %g1 -- TSB entry address
39 * %g6 -- TAG TARGET ((vaddr >> 22) | (ctx << 48)) 39 * %g6 -- TAG TARGET (vaddr >> 22)
40 */ 40 */
41tsb_miss_page_table_walk: 41tsb_miss_page_table_walk:
42 TRAP_LOAD_PGD_PHYS(%g7, %g5) 42 TRAP_LOAD_PGD_PHYS(%g7, %g5)
@@ -50,8 +50,10 @@ tsb_reload:
50 50
51 /* Load and check PTE. */ 51 /* Load and check PTE. */
52 ldxa [%g5] ASI_PHYS_USE_EC, %g5 52 ldxa [%g5] ASI_PHYS_USE_EC, %g5
53 mov 1, %g7
54 sllx %g7, TSB_TAG_INVALID_BIT, %g7
53 brgez,a,pn %g5, tsb_do_fault 55 brgez,a,pn %g5, tsb_do_fault
54 TSB_STORE(%g1, %g0) 56 TSB_STORE(%g1, %g7)
55 57
56 /* If it is larger than the base page size, don't 58 /* If it is larger than the base page size, don't
57 * bother putting it into the TSB. 59 * bother putting it into the TSB.
@@ -62,8 +64,10 @@ tsb_reload:
62 sethi %hi(_PAGE_SZBITS), %g7 64 sethi %hi(_PAGE_SZBITS), %g7
63 ldx [%g7 + %lo(_PAGE_SZBITS)], %g7 65 ldx [%g7 + %lo(_PAGE_SZBITS)], %g7
64 cmp %g2, %g7 66 cmp %g2, %g7
67 mov 1, %g7
68 sllx %g7, TSB_TAG_INVALID_BIT, %g7
65 bne,a,pn %xcc, tsb_tlb_reload 69 bne,a,pn %xcc, tsb_tlb_reload
66 TSB_STORE(%g1, %g0) 70 TSB_STORE(%g1, %g7)
67 71
68 TSB_WRITE(%g1, %g5, %g6) 72 TSB_WRITE(%g1, %g5, %g6)
69 73
@@ -136,7 +140,7 @@ tsb_do_fault:
136 .section .sun4v_2insn_patch, "ax" 140 .section .sun4v_2insn_patch, "ax"
137 .word 661b 141 .word 661b
138 SET_GL(1) 142 SET_GL(1)
139 ldxa [%g0] ASI_SCRATCHPAD, %g2 143 ldxa [%g0] ASI_SCRATCHPAD, %g4
140 .previous 144 .previous
141 145
142 bne,pn %xcc, tsb_do_itlb_fault 146 bne,pn %xcc, tsb_do_itlb_fault
@@ -150,7 +154,7 @@ tsb_do_dtlb_fault:
150 ldxa [%g4] ASI_DMMU, %g5 154 ldxa [%g4] ASI_DMMU, %g5
151 .section .sun4v_2insn_patch, "ax" 155 .section .sun4v_2insn_patch, "ax"
152 .word 661b 156 .word 661b
153 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g5 157 ldx [%g4 + HV_FAULT_D_ADDR_OFFSET], %g5
154 nop 158 nop
155 .previous 159 .previous
156 160
@@ -217,8 +221,9 @@ tsb_flush:
217 bne,pn %icc, 1b 221 bne,pn %icc, 1b
218 membar #LoadLoad 222 membar #LoadLoad
219 cmp %g1, %o1 223 cmp %g1, %o1
224 mov 1, %o3
220 bne,pt %xcc, 2f 225 bne,pt %xcc, 2f
221 clr %o3 226 sllx %o3, TSB_TAG_INVALID_BIT, %o3
222 TSB_CAS_TAG(%o0, %g1, %o3) 227 TSB_CAS_TAG(%o0, %g1, %o3)
223 cmp %g1, %o3 228 cmp %g1, %o3
224 bne,pn %xcc, 1b 229 bne,pn %xcc, 1b