aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/sun4v_tlb_miss.S
diff options
context:
space:
mode:
authorSam Ravnborg <sam@ravnborg.org>2008-12-03 06:11:52 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-04 12:17:21 -0500
commita88b5ba8bd8ac18aad65ee6c6a254e2e74876db3 (patch)
treeeb3d0ffaf53c3f7ec6083752c2097cecd1cb892a /arch/sparc/kernel/sun4v_tlb_miss.S
parentd670bd4f803c8b646acd20f3ba21e65458293faf (diff)
sparc,sparc64: unify kernel/
o Move all files from sparc64/kernel/ to sparc/kernel - rename as appropriate o Update sparc/Makefile to the changes o Update sparc/kernel/Makefile to include the sparc64 files NOTE: This commit changes link order on sparc64! Link order had to change for either of sparc32 and sparc64. And assuming sparc64 see more testing than sparc32 change link order on sparc64 where issues will be caught faster. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/sun4v_tlb_miss.S')
-rw-r--r--arch/sparc/kernel/sun4v_tlb_miss.S428
1 files changed, 428 insertions, 0 deletions
diff --git a/arch/sparc/kernel/sun4v_tlb_miss.S b/arch/sparc/kernel/sun4v_tlb_miss.S
new file mode 100644
index 000000000000..e1fbf8c75787
--- /dev/null
+++ b/arch/sparc/kernel/sun4v_tlb_miss.S
@@ -0,0 +1,428 @@
1/* sun4v_tlb_miss.S: Sun4v TLB miss handlers.
2 *
3 * Copyright (C) 2006 <davem@davemloft.net>
4 */
5
6 .text
7 .align 32
8
9 /* Load ITLB fault information into VADDR and CTX, using BASE. */
10#define LOAD_ITLB_INFO(BASE, VADDR, CTX) \
11 ldx [BASE + HV_FAULT_I_ADDR_OFFSET], VADDR; \
12 ldx [BASE + HV_FAULT_I_CTX_OFFSET], CTX;
13
14 /* Load DTLB fault information into VADDR and CTX, using BASE. */
15#define LOAD_DTLB_INFO(BASE, VADDR, CTX) \
16 ldx [BASE + HV_FAULT_D_ADDR_OFFSET], VADDR; \
17 ldx [BASE + HV_FAULT_D_CTX_OFFSET], CTX;
18
19 /* DEST = (VADDR >> 22)
20 *
21 * Branch to ZERO_CTX_LABEL if context is zero.
22 */
23#define COMPUTE_TAG_TARGET(DEST, VADDR, CTX, ZERO_CTX_LABEL) \
24 srlx VADDR, 22, DEST; \
25 brz,pn CTX, ZERO_CTX_LABEL; \
26 nop;
27
28 /* Create TSB pointer. This is something like:
29 *
30 * index_mask = (512 << (tsb_reg & 0x7UL)) - 1UL;
31 * tsb_base = tsb_reg & ~0x7UL;
32 * tsb_index = ((vaddr >> HASH_SHIFT) & tsb_mask);
33 * tsb_ptr = tsb_base + (tsb_index * 16);
34 */
35#define COMPUTE_TSB_PTR(TSB_PTR, VADDR, HASH_SHIFT, TMP1, TMP2) \
36 and TSB_PTR, 0x7, TMP1; \
37 mov 512, TMP2; \
38 andn TSB_PTR, 0x7, TSB_PTR; \
39 sllx TMP2, TMP1, TMP2; \
40 srlx VADDR, HASH_SHIFT, TMP1; \
41 sub TMP2, 1, TMP2; \
42 and TMP1, TMP2, TMP1; \
43 sllx TMP1, 4, TMP1; \
44 add TSB_PTR, TMP1, TSB_PTR;
45
46sun4v_itlb_miss:
47 /* Load MMU Miss base into %g2. */
48 ldxa [%g0] ASI_SCRATCHPAD, %g2
49
50 /* Load UTSB reg into %g1. */
51 mov SCRATCHPAD_UTSBREG1, %g1
52 ldxa [%g1] ASI_SCRATCHPAD, %g1
53
54 LOAD_ITLB_INFO(%g2, %g4, %g5)
55 COMPUTE_TAG_TARGET(%g6, %g4, %g5, kvmap_itlb_4v)
56 COMPUTE_TSB_PTR(%g1, %g4, PAGE_SHIFT, %g3, %g7)
57
58 /* Load TSB tag/pte into %g2/%g3 and compare the tag. */
59 ldda [%g1] ASI_QUAD_LDD_PHYS_4V, %g2
60 cmp %g2, %g6
61 bne,a,pn %xcc, tsb_miss_page_table_walk
62 mov FAULT_CODE_ITLB, %g3
63 andcc %g3, _PAGE_EXEC_4V, %g0
64 be,a,pn %xcc, tsb_do_fault
65 mov FAULT_CODE_ITLB, %g3
66
67 /* We have a valid entry, make hypervisor call to load
68 * I-TLB and return from trap.
69 *
70 * %g3: PTE
71 * %g4: vaddr
72 */
73sun4v_itlb_load:
74 ldxa [%g0] ASI_SCRATCHPAD, %g6
75 mov %o0, %g1 ! save %o0
76 mov %o1, %g2 ! save %o1
77 mov %o2, %g5 ! save %o2
78 mov %o3, %g7 ! save %o3
79 mov %g4, %o0 ! vaddr
80 ldx [%g6 + HV_FAULT_I_CTX_OFFSET], %o1 ! ctx
81 mov %g3, %o2 ! PTE
82 mov HV_MMU_IMMU, %o3 ! flags
83 ta HV_MMU_MAP_ADDR_TRAP
84 brnz,pn %o0, sun4v_itlb_error
85 mov %g2, %o1 ! restore %o1
86 mov %g1, %o0 ! restore %o0
87 mov %g5, %o2 ! restore %o2
88 mov %g7, %o3 ! restore %o3
89
90 retry
91
92sun4v_dtlb_miss:
93 /* Load MMU Miss base into %g2. */
94 ldxa [%g0] ASI_SCRATCHPAD, %g2
95
96 /* Load UTSB reg into %g1. */
97 mov SCRATCHPAD_UTSBREG1, %g1
98 ldxa [%g1] ASI_SCRATCHPAD, %g1
99
100 LOAD_DTLB_INFO(%g2, %g4, %g5)
101 COMPUTE_TAG_TARGET(%g6, %g4, %g5, kvmap_dtlb_4v)
102 COMPUTE_TSB_PTR(%g1, %g4, PAGE_SHIFT, %g3, %g7)
103
104 /* Load TSB tag/pte into %g2/%g3 and compare the tag. */
105 ldda [%g1] ASI_QUAD_LDD_PHYS_4V, %g2
106 cmp %g2, %g6
107 bne,a,pn %xcc, tsb_miss_page_table_walk
108 mov FAULT_CODE_DTLB, %g3
109
110 /* We have a valid entry, make hypervisor call to load
111 * D-TLB and return from trap.
112 *
113 * %g3: PTE
114 * %g4: vaddr
115 */
116sun4v_dtlb_load:
117 ldxa [%g0] ASI_SCRATCHPAD, %g6
118 mov %o0, %g1 ! save %o0
119 mov %o1, %g2 ! save %o1
120 mov %o2, %g5 ! save %o2
121 mov %o3, %g7 ! save %o3
122 mov %g4, %o0 ! vaddr
123 ldx [%g6 + HV_FAULT_D_CTX_OFFSET], %o1 ! ctx
124 mov %g3, %o2 ! PTE
125 mov HV_MMU_DMMU, %o3 ! flags
126 ta HV_MMU_MAP_ADDR_TRAP
127 brnz,pn %o0, sun4v_dtlb_error
128 mov %g2, %o1 ! restore %o1
129 mov %g1, %o0 ! restore %o0
130 mov %g5, %o2 ! restore %o2
131 mov %g7, %o3 ! restore %o3
132
133 retry
134
135sun4v_dtlb_prot:
136 SET_GL(1)
137
138 /* Load MMU Miss base into %g5. */
139 ldxa [%g0] ASI_SCRATCHPAD, %g5
140
141 ldx [%g5 + HV_FAULT_D_ADDR_OFFSET], %g5
142 rdpr %tl, %g1
143 cmp %g1, 1
144 bgu,pn %xcc, winfix_trampoline
145 mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4
146 ba,pt %xcc, sparc64_realfault_common
147 nop
148
149 /* Called from trap table:
150 * %g4: vaddr
151 * %g5: context
152 * %g6: TAG TARGET
153 */
154sun4v_itsb_miss:
155 mov SCRATCHPAD_UTSBREG1, %g1
156 ldxa [%g1] ASI_SCRATCHPAD, %g1
157 brz,pn %g5, kvmap_itlb_4v
158 mov FAULT_CODE_ITLB, %g3
159 ba,a,pt %xcc, sun4v_tsb_miss_common
160
161 /* Called from trap table:
162 * %g4: vaddr
163 * %g5: context
164 * %g6: TAG TARGET
165 */
166sun4v_dtsb_miss:
167 mov SCRATCHPAD_UTSBREG1, %g1
168 ldxa [%g1] ASI_SCRATCHPAD, %g1
169 brz,pn %g5, kvmap_dtlb_4v
170 mov FAULT_CODE_DTLB, %g3
171
172 /* fallthrough */
173
174sun4v_tsb_miss_common:
175 COMPUTE_TSB_PTR(%g1, %g4, PAGE_SHIFT, %g5, %g7)
176
177 sub %g2, TRAP_PER_CPU_FAULT_INFO, %g2
178
179#ifdef CONFIG_HUGETLB_PAGE
180 mov SCRATCHPAD_UTSBREG2, %g5
181 ldxa [%g5] ASI_SCRATCHPAD, %g5
182 cmp %g5, -1
183 be,pt %xcc, 80f
184 nop
185 COMPUTE_TSB_PTR(%g5, %g4, HPAGE_SHIFT, %g2, %g7)
186
187 /* That clobbered %g2, reload it. */
188 ldxa [%g0] ASI_SCRATCHPAD, %g2
189 sub %g2, TRAP_PER_CPU_FAULT_INFO, %g2
190
19180: stx %g5, [%g2 + TRAP_PER_CPU_TSB_HUGE_TEMP]
192#endif
193
194 ba,pt %xcc, tsb_miss_page_table_walk_sun4v_fastpath
195 ldx [%g2 + TRAP_PER_CPU_PGD_PADDR], %g7
196
197sun4v_itlb_error:
198 sethi %hi(sun4v_err_itlb_vaddr), %g1
199 stx %g4, [%g1 + %lo(sun4v_err_itlb_vaddr)]
200 sethi %hi(sun4v_err_itlb_ctx), %g1
201 ldxa [%g0] ASI_SCRATCHPAD, %g6
202 ldx [%g6 + HV_FAULT_I_CTX_OFFSET], %o1
203 stx %o1, [%g1 + %lo(sun4v_err_itlb_ctx)]
204 sethi %hi(sun4v_err_itlb_pte), %g1
205 stx %g3, [%g1 + %lo(sun4v_err_itlb_pte)]
206 sethi %hi(sun4v_err_itlb_error), %g1
207 stx %o0, [%g1 + %lo(sun4v_err_itlb_error)]
208
209 rdpr %tl, %g4
210 cmp %g4, 1
211 ble,pt %icc, 1f
212 sethi %hi(2f), %g7
213 ba,pt %xcc, etraptl1
214 or %g7, %lo(2f), %g7
215
2161: ba,pt %xcc, etrap
2172: or %g7, %lo(2b), %g7
218 mov %l4, %o1
219 call sun4v_itlb_error_report
220 add %sp, PTREGS_OFF, %o0
221
222 /* NOTREACHED */
223
224sun4v_dtlb_error:
225 sethi %hi(sun4v_err_dtlb_vaddr), %g1
226 stx %g4, [%g1 + %lo(sun4v_err_dtlb_vaddr)]
227 sethi %hi(sun4v_err_dtlb_ctx), %g1
228 ldxa [%g0] ASI_SCRATCHPAD, %g6
229 ldx [%g6 + HV_FAULT_D_CTX_OFFSET], %o1
230 stx %o1, [%g1 + %lo(sun4v_err_dtlb_ctx)]
231 sethi %hi(sun4v_err_dtlb_pte), %g1
232 stx %g3, [%g1 + %lo(sun4v_err_dtlb_pte)]
233 sethi %hi(sun4v_err_dtlb_error), %g1
234 stx %o0, [%g1 + %lo(sun4v_err_dtlb_error)]
235
236 rdpr %tl, %g4
237 cmp %g4, 1
238 ble,pt %icc, 1f
239 sethi %hi(2f), %g7
240 ba,pt %xcc, etraptl1
241 or %g7, %lo(2f), %g7
242
2431: ba,pt %xcc, etrap
2442: or %g7, %lo(2b), %g7
245 mov %l4, %o1
246 call sun4v_dtlb_error_report
247 add %sp, PTREGS_OFF, %o0
248
249 /* NOTREACHED */
250
251 /* Instruction Access Exception, tl0. */
252sun4v_iacc:
253 ldxa [%g0] ASI_SCRATCHPAD, %g2
254 ldx [%g2 + HV_FAULT_I_TYPE_OFFSET], %g3
255 ldx [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4
256 ldx [%g2 + HV_FAULT_I_CTX_OFFSET], %g5
257 sllx %g3, 16, %g3
258 or %g5, %g3, %g5
259 ba,pt %xcc, etrap
260 rd %pc, %g7
261 mov %l4, %o1
262 mov %l5, %o2
263 call sun4v_insn_access_exception
264 add %sp, PTREGS_OFF, %o0
265 ba,a,pt %xcc, rtrap
266
267 /* Instruction Access Exception, tl1. */
268sun4v_iacc_tl1:
269 ldxa [%g0] ASI_SCRATCHPAD, %g2
270 ldx [%g2 + HV_FAULT_I_TYPE_OFFSET], %g3
271 ldx [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4
272 ldx [%g2 + HV_FAULT_I_CTX_OFFSET], %g5
273 sllx %g3, 16, %g3
274 or %g5, %g3, %g5
275 ba,pt %xcc, etraptl1
276 rd %pc, %g7
277 mov %l4, %o1
278 mov %l5, %o2
279 call sun4v_insn_access_exception_tl1
280 add %sp, PTREGS_OFF, %o0
281 ba,a,pt %xcc, rtrap
282
283 /* Data Access Exception, tl0. */
284sun4v_dacc:
285 ldxa [%g0] ASI_SCRATCHPAD, %g2
286 ldx [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3
287 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
288 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
289 sllx %g3, 16, %g3
290 or %g5, %g3, %g5
291 ba,pt %xcc, etrap
292 rd %pc, %g7
293 mov %l4, %o1
294 mov %l5, %o2
295 call sun4v_data_access_exception
296 add %sp, PTREGS_OFF, %o0
297 ba,a,pt %xcc, rtrap
298
299 /* Data Access Exception, tl1. */
300sun4v_dacc_tl1:
301 ldxa [%g0] ASI_SCRATCHPAD, %g2
302 ldx [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3
303 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
304 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
305 sllx %g3, 16, %g3
306 or %g5, %g3, %g5
307 ba,pt %xcc, etraptl1
308 rd %pc, %g7
309 mov %l4, %o1
310 mov %l5, %o2
311 call sun4v_data_access_exception_tl1
312 add %sp, PTREGS_OFF, %o0
313 ba,a,pt %xcc, rtrap
314
315 /* Memory Address Unaligned. */
316sun4v_mna:
317 /* Window fixup? */
318 rdpr %tl, %g2
319 cmp %g2, 1
320 ble,pt %icc, 1f
321 nop
322
323 SET_GL(1)
324 ldxa [%g0] ASI_SCRATCHPAD, %g2
325 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g5
326 mov HV_FAULT_TYPE_UNALIGNED, %g3
327 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g4
328 sllx %g3, 16, %g3
329 or %g4, %g3, %g4
330 ba,pt %xcc, winfix_mna
331 rdpr %tpc, %g3
332 /* not reached */
333
3341: ldxa [%g0] ASI_SCRATCHPAD, %g2
335 mov HV_FAULT_TYPE_UNALIGNED, %g3
336 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
337 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
338 sllx %g3, 16, %g3
339 or %g5, %g3, %g5
340
341 ba,pt %xcc, etrap
342 rd %pc, %g7
343 mov %l4, %o1
344 mov %l5, %o2
345 call sun4v_do_mna
346 add %sp, PTREGS_OFF, %o0
347 ba,a,pt %xcc, rtrap
348
349 /* Privileged Action. */
350sun4v_privact:
351 ba,pt %xcc, etrap
352 rd %pc, %g7
353 call do_privact
354 add %sp, PTREGS_OFF, %o0
355 ba,a,pt %xcc, rtrap
356
357 /* Unaligned ldd float, tl0. */
358sun4v_lddfmna:
359 ldxa [%g0] ASI_SCRATCHPAD, %g2
360 ldx [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3
361 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
362 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
363 sllx %g3, 16, %g3
364 or %g5, %g3, %g5
365 ba,pt %xcc, etrap
366 rd %pc, %g7
367 mov %l4, %o1
368 mov %l5, %o2
369 call handle_lddfmna
370 add %sp, PTREGS_OFF, %o0
371 ba,a,pt %xcc, rtrap
372
373 /* Unaligned std float, tl0. */
374sun4v_stdfmna:
375 ldxa [%g0] ASI_SCRATCHPAD, %g2
376 ldx [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3
377 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
378 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
379 sllx %g3, 16, %g3
380 or %g5, %g3, %g5
381 ba,pt %xcc, etrap
382 rd %pc, %g7
383 mov %l4, %o1
384 mov %l5, %o2
385 call handle_stdfmna
386 add %sp, PTREGS_OFF, %o0
387 ba,a,pt %xcc, rtrap
388
389#define BRANCH_ALWAYS 0x10680000
390#define NOP 0x01000000
391#define SUN4V_DO_PATCH(OLD, NEW) \
392 sethi %hi(NEW), %g1; \
393 or %g1, %lo(NEW), %g1; \
394 sethi %hi(OLD), %g2; \
395 or %g2, %lo(OLD), %g2; \
396 sub %g1, %g2, %g1; \
397 sethi %hi(BRANCH_ALWAYS), %g3; \
398 sll %g1, 11, %g1; \
399 srl %g1, 11 + 2, %g1; \
400 or %g3, %lo(BRANCH_ALWAYS), %g3; \
401 or %g3, %g1, %g3; \
402 stw %g3, [%g2]; \
403 sethi %hi(NOP), %g3; \
404 or %g3, %lo(NOP), %g3; \
405 stw %g3, [%g2 + 0x4]; \
406 flush %g2;
407
408 .globl sun4v_patch_tlb_handlers
409 .type sun4v_patch_tlb_handlers,#function
410sun4v_patch_tlb_handlers:
411 SUN4V_DO_PATCH(tl0_iamiss, sun4v_itlb_miss)
412 SUN4V_DO_PATCH(tl1_iamiss, sun4v_itlb_miss)
413 SUN4V_DO_PATCH(tl0_damiss, sun4v_dtlb_miss)
414 SUN4V_DO_PATCH(tl1_damiss, sun4v_dtlb_miss)
415 SUN4V_DO_PATCH(tl0_daprot, sun4v_dtlb_prot)
416 SUN4V_DO_PATCH(tl1_daprot, sun4v_dtlb_prot)
417 SUN4V_DO_PATCH(tl0_iax, sun4v_iacc)
418 SUN4V_DO_PATCH(tl1_iax, sun4v_iacc_tl1)
419 SUN4V_DO_PATCH(tl0_dax, sun4v_dacc)
420 SUN4V_DO_PATCH(tl1_dax, sun4v_dacc_tl1)
421 SUN4V_DO_PATCH(tl0_mna, sun4v_mna)
422 SUN4V_DO_PATCH(tl1_mna, sun4v_mna)
423 SUN4V_DO_PATCH(tl0_lddfmna, sun4v_lddfmna)
424 SUN4V_DO_PATCH(tl0_stdfmna, sun4v_stdfmna)
425 SUN4V_DO_PATCH(tl0_privact, sun4v_privact)
426 retl
427 nop
428 .size sun4v_patch_tlb_handlers,.-sun4v_patch_tlb_handlers