aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-18 19:39:39 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:13:39 -0500
commit24c523ecc667dfeb28ef969cfabc531709bfffb8 (patch)
tree67760d3bb5c5c9f950e61b263fff836e677957ee
parent6cc200db9500f53c6b884ea5d5bc7eabae7f5d5c (diff)
[SPARC64]: Fix unaligned access winfxup handling on SUN4V.
Another case where we have to force ourselves into global register level one. Also make sure the arguments passed to sun4v_do_mna() are correct. This area actually needs some more work, for example spill fixup is not necessarily going to do the right thing for this case. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc64/kernel/sun4v_tlb_miss.S42
-rw-r--r--arch/sparc64/kernel/winfixup.S9
2 files changed, 34 insertions, 17 deletions
diff --git a/arch/sparc64/kernel/sun4v_tlb_miss.S b/arch/sparc64/kernel/sun4v_tlb_miss.S
index 57ccdaec7ccb..654244a3b048 100644
--- a/arch/sparc64/kernel/sun4v_tlb_miss.S
+++ b/arch/sparc64/kernel/sun4v_tlb_miss.S
@@ -137,7 +137,7 @@ sun4v_dtlb_load:
137sun4v_dtlb_prot: 137sun4v_dtlb_prot:
138 SET_GL(1) 138 SET_GL(1)
139 139
140 /* Load MMU Miss base into %g2. */ 140 /* Load MMU Miss base into %g5. */
141 ldxa [%g0] ASI_SCRATCHPAD, %g5 141 ldxa [%g0] ASI_SCRATCHPAD, %g5
142 142
143 ldx [%g5 + HV_FAULT_D_ADDR_OFFSET], %g5 143 ldx [%g5 + HV_FAULT_D_ADDR_OFFSET], %g5
@@ -148,9 +148,10 @@ sun4v_dtlb_prot:
148 ba,pt %xcc, sparc64_realfault_common 148 ba,pt %xcc, sparc64_realfault_common
149 mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4 149 mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4
150 150
151 /* Called from trap table with TAG TARGET placed into 151 /* Called from trap table:
152 * %g6, SCRATCHPAD_UTSBREG1 contents in %g1, and 152 * %g4: vaddr
153 * SCRATCHPAD_MMU_MISS contents in %g2. 153 * %g5: context
154 * %g6: TAG TARGET
154 */ 155 */
155sun4v_itsb_miss: 156sun4v_itsb_miss:
156 mov SCRATCHPAD_UTSBREG1, %g1 157 mov SCRATCHPAD_UTSBREG1, %g1
@@ -159,8 +160,10 @@ sun4v_itsb_miss:
159 mov FAULT_CODE_ITLB, %g3 160 mov FAULT_CODE_ITLB, %g3
160 ba,a,pt %xcc, sun4v_tsb_miss_common 161 ba,a,pt %xcc, sun4v_tsb_miss_common
161 162
162 /* Called from trap table with TAG TARGET placed into 163 /* Called from trap table:
163 * %g6 and SCRATCHPAD_UTSBREG1 contents in %g1. 164 * %g4: vaddr
165 * %g5: context
166 * %g6: TAG TARGET
164 */ 167 */
165sun4v_dtsb_miss: 168sun4v_dtsb_miss:
166 mov SCRATCHPAD_UTSBREG1, %g1 169 mov SCRATCHPAD_UTSBREG1, %g1
@@ -168,6 +171,8 @@ sun4v_dtsb_miss:
168 brz,pn %g5, kvmap_dtlb_4v 171 brz,pn %g5, kvmap_dtlb_4v
169 mov FAULT_CODE_DTLB, %g3 172 mov FAULT_CODE_DTLB, %g3
170 173
174 /* fallthrough */
175
171 /* Create TSB pointer into %g1. This is something like: 176 /* Create TSB pointer into %g1. This is something like:
172 * 177 *
173 * index_mask = (512 << (tsb_reg & 0x7UL)) - 1UL; 178 * index_mask = (512 << (tsb_reg & 0x7UL)) - 1UL;
@@ -304,19 +309,30 @@ sun4v_dacc_tl1:
304 309
305 /* Memory Address Unaligned. */ 310 /* Memory Address Unaligned. */
306sun4v_mna: 311sun4v_mna:
307 ldxa [%g0] ASI_SCRATCHPAD, %g2 312 /* Window fixup? */
313 rdpr %tl, %g2
314 cmp %g2, 1
315 ble,pt %icc, 1f
316 nop
317
318 SET_GL(1)
319 ldxa [%g0] ASI_SCRATCHPAD, %g5
320 ldx [%g5 + HV_FAULT_D_ADDR_OFFSET], %g5
321 mov HV_FAULT_TYPE_UNALIGNED, %g3
322 ldx [%g5 + HV_FAULT_D_CTX_OFFSET], %g4
323 sllx %g3, 16, %g3
324 or %g4, %g3, %g4
325 ba,pt %xcc, winfix_mna
326 rdpr %tpc, %g3
327 /* not reached */
328
3291: ldxa [%g0] ASI_SCRATCHPAD, %g2
308 mov HV_FAULT_TYPE_UNALIGNED, %g3 330 mov HV_FAULT_TYPE_UNALIGNED, %g3
309 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4 331 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
310 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5 332 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
311 sllx %g3, 16, %g3 333 sllx %g3, 16, %g3
312 or %g5, %g3, %g5 334 or %g5, %g3, %g5
313 335
314 /* Window fixup? */
315 rdpr %tl, %g2
316 cmp %g2, 1
317 bgu,pn %icc, winfix_mna
318 rdpr %tpc, %g3
319
320 ba,pt %xcc, etrap 336 ba,pt %xcc, etrap
321 rd %pc, %g7 337 rd %pc, %g7
322 mov %l4, %o1 338 mov %l4, %o1
diff --git a/arch/sparc64/kernel/winfixup.S b/arch/sparc64/kernel/winfixup.S
index 161371370e9d..c4aa110a10e5 100644
--- a/arch/sparc64/kernel/winfixup.S
+++ b/arch/sparc64/kernel/winfixup.S
@@ -115,16 +115,17 @@ fill_fixup_mna:
115 ba,pt %xcc, etrap 115 ba,pt %xcc, etrap
116 rd %pc, %g7 116 rd %pc, %g7
117 sethi %hi(tlb_type), %g1 117 sethi %hi(tlb_type), %g1
118 mov %l4, %o1
119 lduw [%g1 + %lo(tlb_type)], %g1 118 lduw [%g1 + %lo(tlb_type)], %g1
120 mov %l5, %o2
121 cmp %g1, 3 119 cmp %g1, 3
122 bne,pt %icc, 1f 120 bne,pt %icc, 1f
123 add %sp, PTREGS_OFF, %o0 121 add %sp, PTREGS_OFF, %o0
122 mov %l4, %o2
124 call sun4v_do_mna 123 call sun4v_do_mna
125 nop 124 mov %l5, %o1
126 ba,a,pt %xcc, rtrap_clr_l6 125 ba,a,pt %xcc, rtrap_clr_l6
1271: call mem_address_unaligned 1261: mov %l4, %o1
127 mov %l5, %o2
128 call mem_address_unaligned
128 nop 129 nop
129 ba,a,pt %xcc, rtrap_clr_l6 130 ba,a,pt %xcc, rtrap_clr_l6
130 131