blob: fa185f22705586252c32d5c6b4165ad80d94d3a7 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* $Id: entry.S,v 1.144 2002/02/09 19:49:30 davem Exp $
2 * arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points.
3 *
4 * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
6 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
7 * Copyright (C) 1996,98,99 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
8 */
9
10#include <linux/config.h>
11#include <linux/errno.h>
12
13#include <asm/head.h>
14#include <asm/asi.h>
15#include <asm/smp.h>
16#include <asm/ptrace.h>
17#include <asm/page.h>
18#include <asm/signal.h>
19#include <asm/pgtable.h>
20#include <asm/processor.h>
21#include <asm/visasm.h>
22#include <asm/estate.h>
23#include <asm/auxio.h>
David S. Miller6c52a962005-08-29 12:45:11 -070024#include <asm/sfafsr.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070025
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#define curptr g6
27
David S. Miller1b9a4282006-02-07 18:11:24 -080028#define NR_SYSCALLS 300 /* Each OS is different... */
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
30 .text
31 .align 32
32
Linus Torvalds1da177e2005-04-16 15:20:36 -070033 /* This is trivial with the new code... */
34 .globl do_fpdis
35do_fpdis:
David S. Millerba6399332005-10-07 13:30:49 -070036 sethi %hi(TSTATE_PEF), %g4
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 rdpr %tstate, %g5
38 andcc %g5, %g4, %g0
39 be,pt %xcc, 1f
40 nop
41 rd %fprs, %g5
42 andcc %g5, FPRS_FEF, %g0
43 be,pt %xcc, 1f
44 nop
45
46 /* Legal state when DCR_IFPOE is set in Cheetah %dcr. */
47 sethi %hi(109f), %g7
48 ba,pt %xcc, etrap
49109: or %g7, %lo(109b), %g7
50 add %g0, %g0, %g0
51 ba,a,pt %xcc, rtrap_clr_l6
52
David S. Millerffe483d2006-02-02 21:55:10 -0800531: TRAP_LOAD_THREAD_REG(%g6, %g1)
David S. Miller56fb4df2006-02-26 23:24:22 -080054 ldub [%g6 + TI_FPSAVED], %g5
David S. Millerba6399332005-10-07 13:30:49 -070055 wr %g0, FPRS_FEF, %fprs
56 andcc %g5, FPRS_FEF, %g0
57 be,a,pt %icc, 1f
58 clr %g7
59 ldx [%g6 + TI_GSR], %g7
601: andcc %g5, FPRS_DL, %g0
61 bne,pn %icc, 2f
62 fzero %f0
63 andcc %g5, FPRS_DU, %g0
64 bne,pn %icc, 1f
65 fzero %f2
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 faddd %f0, %f2, %f4
67 fmuld %f0, %f2, %f6
68 faddd %f0, %f2, %f8
69 fmuld %f0, %f2, %f10
70 faddd %f0, %f2, %f12
71 fmuld %f0, %f2, %f14
72 faddd %f0, %f2, %f16
73 fmuld %f0, %f2, %f18
74 faddd %f0, %f2, %f20
75 fmuld %f0, %f2, %f22
76 faddd %f0, %f2, %f24
77 fmuld %f0, %f2, %f26
78 faddd %f0, %f2, %f28
79 fmuld %f0, %f2, %f30
80 faddd %f0, %f2, %f32
81 fmuld %f0, %f2, %f34
82 faddd %f0, %f2, %f36
83 fmuld %f0, %f2, %f38
84 faddd %f0, %f2, %f40
85 fmuld %f0, %f2, %f42
86 faddd %f0, %f2, %f44
87 fmuld %f0, %f2, %f46
88 faddd %f0, %f2, %f48
89 fmuld %f0, %f2, %f50
90 faddd %f0, %f2, %f52
91 fmuld %f0, %f2, %f54
92 faddd %f0, %f2, %f56
93 fmuld %f0, %f2, %f58
94 b,pt %xcc, fpdis_exit2
95 faddd %f0, %f2, %f60
961: mov SECONDARY_CONTEXT, %g3
97 add %g6, TI_FPREGS + 0x80, %g1
98 faddd %f0, %f2, %f4
99 fmuld %f0, %f2, %f6
David S. Miller8b11bd12006-02-07 22:13:05 -0800100
101661: ldxa [%g3] ASI_DMMU, %g5
102 .section .sun4v_1insn_patch, "ax"
103 .word 661b
104 ldxa [%g3] ASI_MMU, %g5
105 .previous
106
David S. Miller0835ae02005-10-04 15:23:20 -0700107 sethi %hi(sparc64_kern_sec_context), %g2
108 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
David S. Miller8b11bd12006-02-07 22:13:05 -0800109
110661: stxa %g2, [%g3] ASI_DMMU
111 .section .sun4v_1insn_patch, "ax"
112 .word 661b
113 stxa %g2, [%g3] ASI_MMU
114 .previous
115
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 membar #Sync
117 add %g6, TI_FPREGS + 0xc0, %g2
118 faddd %f0, %f2, %f8
119 fmuld %f0, %f2, %f10
David S. Millerba6399332005-10-07 13:30:49 -0700120 membar #Sync
121 ldda [%g1] ASI_BLK_S, %f32
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 ldda [%g2] ASI_BLK_S, %f48
David S. Millerba6399332005-10-07 13:30:49 -0700123 membar #Sync
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 faddd %f0, %f2, %f12
125 fmuld %f0, %f2, %f14
126 faddd %f0, %f2, %f16
127 fmuld %f0, %f2, %f18
128 faddd %f0, %f2, %f20
129 fmuld %f0, %f2, %f22
130 faddd %f0, %f2, %f24
131 fmuld %f0, %f2, %f26
132 faddd %f0, %f2, %f28
133 fmuld %f0, %f2, %f30
134 b,pt %xcc, fpdis_exit
David S. Millerb445e262005-06-27 15:42:04 -0700135 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362: andcc %g5, FPRS_DU, %g0
137 bne,pt %icc, 3f
138 fzero %f32
139 mov SECONDARY_CONTEXT, %g3
140 fzero %f34
David S. Miller8b11bd12006-02-07 22:13:05 -0800141
142661: ldxa [%g3] ASI_DMMU, %g5
143 .section .sun4v_1insn_patch, "ax"
144 .word 661b
145 ldxa [%g3] ASI_MMU, %g5
146 .previous
147
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 add %g6, TI_FPREGS, %g1
David S. Miller0835ae02005-10-04 15:23:20 -0700149 sethi %hi(sparc64_kern_sec_context), %g2
150 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
David S. Miller8b11bd12006-02-07 22:13:05 -0800151
152661: stxa %g2, [%g3] ASI_DMMU
153 .section .sun4v_1insn_patch, "ax"
154 .word 661b
155 stxa %g2, [%g3] ASI_MMU
156 .previous
157
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 membar #Sync
159 add %g6, TI_FPREGS + 0x40, %g2
160 faddd %f32, %f34, %f36
161 fmuld %f32, %f34, %f38
David S. Millerba6399332005-10-07 13:30:49 -0700162 membar #Sync
163 ldda [%g1] ASI_BLK_S, %f0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 ldda [%g2] ASI_BLK_S, %f16
David S. Millerba6399332005-10-07 13:30:49 -0700165 membar #Sync
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 faddd %f32, %f34, %f40
167 fmuld %f32, %f34, %f42
168 faddd %f32, %f34, %f44
169 fmuld %f32, %f34, %f46
170 faddd %f32, %f34, %f48
171 fmuld %f32, %f34, %f50
172 faddd %f32, %f34, %f52
173 fmuld %f32, %f34, %f54
174 faddd %f32, %f34, %f56
175 fmuld %f32, %f34, %f58
176 faddd %f32, %f34, %f60
177 fmuld %f32, %f34, %f62
178 ba,pt %xcc, fpdis_exit
David S. Millerb445e262005-06-27 15:42:04 -0700179 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803: mov SECONDARY_CONTEXT, %g3
181 add %g6, TI_FPREGS, %g1
David S. Miller8b11bd12006-02-07 22:13:05 -0800182
183661: ldxa [%g3] ASI_DMMU, %g5
184 .section .sun4v_1insn_patch, "ax"
185 .word 661b
186 ldxa [%g3] ASI_MMU, %g5
187 .previous
188
David S. Miller0835ae02005-10-04 15:23:20 -0700189 sethi %hi(sparc64_kern_sec_context), %g2
190 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
David S. Miller8b11bd12006-02-07 22:13:05 -0800191
192661: stxa %g2, [%g3] ASI_DMMU
193 .section .sun4v_1insn_patch, "ax"
194 .word 661b
195 stxa %g2, [%g3] ASI_MMU
196 .previous
197
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 membar #Sync
199 mov 0x40, %g2
David S. Millerba6399332005-10-07 13:30:49 -0700200 membar #Sync
201 ldda [%g1] ASI_BLK_S, %f0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 ldda [%g1 + %g2] ASI_BLK_S, %f16
203 add %g1, 0x80, %g1
204 ldda [%g1] ASI_BLK_S, %f32
205 ldda [%g1 + %g2] ASI_BLK_S, %f48
206 membar #Sync
207fpdis_exit:
David S. Miller8b11bd12006-02-07 22:13:05 -0800208
209661: stxa %g5, [%g3] ASI_DMMU
210 .section .sun4v_1insn_patch, "ax"
211 .word 661b
212 stxa %g5, [%g3] ASI_MMU
213 .previous
214
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 membar #Sync
216fpdis_exit2:
217 wr %g7, 0, %gsr
218 ldx [%g6 + TI_XFSR], %fsr
219 rdpr %tstate, %g3
220 or %g3, %g4, %g3 ! anal...
221 wrpr %g3, %tstate
222 wr %g0, FPRS_FEF, %fprs ! clean DU/DL bits
223 retry
224
225 .align 32
226fp_other_bounce:
227 call do_fpother
228 add %sp, PTREGS_OFF, %o0
229 ba,pt %xcc, rtrap
230 clr %l6
231
232 .globl do_fpother_check_fitos
233 .align 32
234do_fpother_check_fitos:
David S. Millerffe483d2006-02-02 21:55:10 -0800235 TRAP_LOAD_THREAD_REG(%g6, %g1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236 sethi %hi(fp_other_bounce - 4), %g7
237 or %g7, %lo(fp_other_bounce - 4), %g7
238
239 /* NOTE: Need to preserve %g7 until we fully commit
240 * to the fitos fixup.
241 */
242 stx %fsr, [%g6 + TI_XFSR]
243 rdpr %tstate, %g3
244 andcc %g3, TSTATE_PRIV, %g0
245 bne,pn %xcc, do_fptrap_after_fsr
246 nop
247 ldx [%g6 + TI_XFSR], %g3
248 srlx %g3, 14, %g1
249 and %g1, 7, %g1
250 cmp %g1, 2 ! Unfinished FP-OP
251 bne,pn %xcc, do_fptrap_after_fsr
252 sethi %hi(1 << 23), %g1 ! Inexact
253 andcc %g3, %g1, %g0
254 bne,pn %xcc, do_fptrap_after_fsr
255 rdpr %tpc, %g1
256 lduwa [%g1] ASI_AIUP, %g3 ! This cannot ever fail
257#define FITOS_MASK 0xc1f83fe0
258#define FITOS_COMPARE 0x81a01880
259 sethi %hi(FITOS_MASK), %g1
260 or %g1, %lo(FITOS_MASK), %g1
261 and %g3, %g1, %g1
262 sethi %hi(FITOS_COMPARE), %g2
263 or %g2, %lo(FITOS_COMPARE), %g2
264 cmp %g1, %g2
265 bne,pn %xcc, do_fptrap_after_fsr
266 nop
267 std %f62, [%g6 + TI_FPREGS + (62 * 4)]
268 sethi %hi(fitos_table_1), %g1
269 and %g3, 0x1f, %g2
270 or %g1, %lo(fitos_table_1), %g1
271 sllx %g2, 2, %g2
272 jmpl %g1 + %g2, %g0
273 ba,pt %xcc, fitos_emul_continue
274
275fitos_table_1:
276 fitod %f0, %f62
277 fitod %f1, %f62
278 fitod %f2, %f62
279 fitod %f3, %f62
280 fitod %f4, %f62
281 fitod %f5, %f62
282 fitod %f6, %f62
283 fitod %f7, %f62
284 fitod %f8, %f62
285 fitod %f9, %f62
286 fitod %f10, %f62
287 fitod %f11, %f62
288 fitod %f12, %f62
289 fitod %f13, %f62
290 fitod %f14, %f62
291 fitod %f15, %f62
292 fitod %f16, %f62
293 fitod %f17, %f62
294 fitod %f18, %f62
295 fitod %f19, %f62
296 fitod %f20, %f62
297 fitod %f21, %f62
298 fitod %f22, %f62
299 fitod %f23, %f62
300 fitod %f24, %f62
301 fitod %f25, %f62
302 fitod %f26, %f62
303 fitod %f27, %f62
304 fitod %f28, %f62
305 fitod %f29, %f62
306 fitod %f30, %f62
307 fitod %f31, %f62
308
309fitos_emul_continue:
310 sethi %hi(fitos_table_2), %g1
311 srl %g3, 25, %g2
312 or %g1, %lo(fitos_table_2), %g1
313 and %g2, 0x1f, %g2
314 sllx %g2, 2, %g2
315 jmpl %g1 + %g2, %g0
316 ba,pt %xcc, fitos_emul_fini
317
318fitos_table_2:
319 fdtos %f62, %f0
320 fdtos %f62, %f1
321 fdtos %f62, %f2
322 fdtos %f62, %f3
323 fdtos %f62, %f4
324 fdtos %f62, %f5
325 fdtos %f62, %f6
326 fdtos %f62, %f7
327 fdtos %f62, %f8
328 fdtos %f62, %f9
329 fdtos %f62, %f10
330 fdtos %f62, %f11
331 fdtos %f62, %f12
332 fdtos %f62, %f13
333 fdtos %f62, %f14
334 fdtos %f62, %f15
335 fdtos %f62, %f16
336 fdtos %f62, %f17
337 fdtos %f62, %f18
338 fdtos %f62, %f19
339 fdtos %f62, %f20
340 fdtos %f62, %f21
341 fdtos %f62, %f22
342 fdtos %f62, %f23
343 fdtos %f62, %f24
344 fdtos %f62, %f25
345 fdtos %f62, %f26
346 fdtos %f62, %f27
347 fdtos %f62, %f28
348 fdtos %f62, %f29
349 fdtos %f62, %f30
350 fdtos %f62, %f31
351
352fitos_emul_fini:
353 ldd [%g6 + TI_FPREGS + (62 * 4)], %f62
354 done
355
356 .globl do_fptrap
357 .align 32
358do_fptrap:
359 stx %fsr, [%g6 + TI_XFSR]
360do_fptrap_after_fsr:
361 ldub [%g6 + TI_FPSAVED], %g3
362 rd %fprs, %g1
363 or %g3, %g1, %g3
364 stb %g3, [%g6 + TI_FPSAVED]
365 rd %gsr, %g3
366 stx %g3, [%g6 + TI_GSR]
367 mov SECONDARY_CONTEXT, %g3
David S. Miller8b11bd12006-02-07 22:13:05 -0800368
369661: ldxa [%g3] ASI_DMMU, %g5
370 .section .sun4v_1insn_patch, "ax"
371 .word 661b
372 ldxa [%g3] ASI_MMU, %g5
373 .previous
374
David S. Miller0835ae02005-10-04 15:23:20 -0700375 sethi %hi(sparc64_kern_sec_context), %g2
376 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
David S. Miller8b11bd12006-02-07 22:13:05 -0800377
378661: stxa %g2, [%g3] ASI_DMMU
379 .section .sun4v_1insn_patch, "ax"
380 .word 661b
381 stxa %g2, [%g3] ASI_MMU
382 .previous
383
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 membar #Sync
385 add %g6, TI_FPREGS, %g2
386 andcc %g1, FPRS_DL, %g0
387 be,pn %icc, 4f
388 mov 0x40, %g3
389 stda %f0, [%g2] ASI_BLK_S
390 stda %f16, [%g2 + %g3] ASI_BLK_S
391 andcc %g1, FPRS_DU, %g0
392 be,pn %icc, 5f
3934: add %g2, 128, %g2
394 stda %f32, [%g2] ASI_BLK_S
395 stda %f48, [%g2 + %g3] ASI_BLK_S
3965: mov SECONDARY_CONTEXT, %g1
397 membar #Sync
David S. Miller8b11bd12006-02-07 22:13:05 -0800398
399661: stxa %g5, [%g1] ASI_DMMU
400 .section .sun4v_1insn_patch, "ax"
401 .word 661b
402 stxa %g5, [%g1] ASI_MMU
403 .previous
404
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 membar #Sync
406 ba,pt %xcc, etrap
407 wr %g0, 0, %fprs
408
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 /* The registers for cross calls will be:
410 *
411 * DATA 0: [low 32-bits] Address of function to call, jmp to this
412 * [high 32-bits] MMU Context Argument 0, place in %g5
David S. Miller80dc0d62005-09-26 00:32:17 -0700413 * DATA 1: Address Argument 1, place in %g1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 * DATA 2: Address Argument 2, place in %g7
415 *
416 * With this method we can do most of the cross-call tlb/cache
417 * flushing very quickly.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 */
419 .text
420 .align 32
421 .globl do_ivec
422do_ivec:
423 mov 0x40, %g3
424 ldxa [%g3 + %g0] ASI_INTR_R, %g3
425 sethi %hi(KERNBASE), %g4
426 cmp %g3, %g4
427 bgeu,pn %xcc, do_ivec_xcall
428 srlx %g3, 32, %g5
429 stxa %g0, [%g0] ASI_INTR_RECEIVE
430 membar #Sync
431
432 sethi %hi(ivector_table), %g2
433 sllx %g3, 5, %g3
434 or %g2, %lo(ivector_table), %g2
435 add %g2, %g3, %g3
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436 ldub [%g3 + 0x04], %g4 /* pil */
David S. Miller088dd1f2005-07-04 13:24:38 -0700437 mov 1, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 sllx %g2, %g4, %g2
439 sllx %g4, 2, %g4
David S. Miller088dd1f2005-07-04 13:24:38 -0700440
David S. Millerffe483d2006-02-02 21:55:10 -0800441 TRAP_LOAD_IRQ_WORK(%g6, %g1)
David S. Miller56fb4df2006-02-26 23:24:22 -0800442
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 lduw [%g6 + %g4], %g5 /* g5 = irq_work(cpu, pil) */
444 stw %g5, [%g3 + 0x00] /* bucket->irq_chain = g5 */
445 stw %g3, [%g6 + %g4] /* irq_work(cpu, pil) = bucket */
446 wr %g2, 0x0, %set_softint
447 retry
448do_ivec_xcall:
449 mov 0x50, %g1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 ldxa [%g1 + %g0] ASI_INTR_R, %g1
451 srl %g3, 0, %g3
David S. Miller088dd1f2005-07-04 13:24:38 -0700452
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 mov 0x60, %g7
454 ldxa [%g7 + %g0] ASI_INTR_R, %g7
455 stxa %g0, [%g0] ASI_INTR_RECEIVE
456 membar #Sync
457 ba,pt %xcc, 1f
458 nop
459
460 .align 32
4611: jmpl %g3, %g0
462 nop
463
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 .globl getcc, setcc
465getcc:
466 ldx [%o0 + PT_V9_TSTATE], %o1
467 srlx %o1, 32, %o1
468 and %o1, 0xf, %o1
469 retl
470 stx %o1, [%o0 + PT_V9_G1]
471setcc:
472 ldx [%o0 + PT_V9_TSTATE], %o1
473 ldx [%o0 + PT_V9_G1], %o2
474 or %g0, %ulo(TSTATE_ICC), %o3
475 sllx %o3, 32, %o3
476 andn %o1, %o3, %o1
477 sllx %o2, 32, %o2
478 and %o2, %o3, %o2
479 or %o1, %o2, %o1
480 retl
481 stx %o1, [%o0 + PT_V9_TSTATE]
482
David S. Miller56fb4df2006-02-26 23:24:22 -0800483 .globl utrap_trap
484utrap_trap: /* %g3=handler,%g4=level */
David S. Millerffe483d2006-02-02 21:55:10 -0800485 TRAP_LOAD_THREAD_REG(%g6, %g1)
David S. Miller56fb4df2006-02-26 23:24:22 -0800486 ldx [%g6 + TI_UTRAPS], %g1
487 brnz,pt %g1, invoke_utrap
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 nop
David S. Miller56fb4df2006-02-26 23:24:22 -0800489
490 ba,pt %xcc, etrap
491 rd %pc, %g7
492 mov %l4, %o1
493 call bad_trap
494 add %sp, PTREGS_OFF, %o0
495 ba,pt %xcc, rtrap
496 clr %l6
497
498invoke_utrap:
499 sllx %g3, 3, %g3
500 ldx [%g1 + %g3], %g1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 save %sp, -128, %sp
502 rdpr %tstate, %l6
503 rdpr %cwp, %l7
504 andn %l6, TSTATE_CWP, %l6
505 wrpr %l6, %l7, %tstate
506 rdpr %tpc, %l6
507 rdpr %tnpc, %l7
508 wrpr %g1, 0, %tnpc
509 done
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510
David S. Miller6c52a962005-08-29 12:45:11 -0700511 /* We need to carefully read the error status, ACK
512 * the errors, prevent recursive traps, and pass the
513 * information on to C code for logging.
514 *
515 * We pass the AFAR in as-is, and we encode the status
516 * information as described in asm-sparc64/sfafsr.h
517 */
518 .globl __spitfire_access_error
519__spitfire_access_error:
520 /* Disable ESTATE error reporting so that we do not
521 * take recursive traps and RED state the processor.
522 */
523 stxa %g0, [%g0] ASI_ESTATE_ERROR_EN
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 membar #Sync
David S. Miller6c52a962005-08-29 12:45:11 -0700525
526 mov UDBE_UE, %g1
527 ldxa [%g0] ASI_AFSR, %g4 ! Get AFSR
528
529 /* __spitfire_cee_trap branches here with AFSR in %g4 and
530 * UDBE_CE in %g1. It only clears ESTATE_ERR_CE in the
531 * ESTATE Error Enable register.
532 */
533__spitfire_cee_trap_continue:
534 ldxa [%g0] ASI_AFAR, %g5 ! Get AFAR
535
David S. Millerbde4e4e2005-08-29 12:44:57 -0700536 rdpr %tt, %g3
David S. Miller6c52a962005-08-29 12:45:11 -0700537 and %g3, 0x1ff, %g3 ! Paranoia
538 sllx %g3, SFSTAT_TRAP_TYPE_SHIFT, %g3
539 or %g4, %g3, %g4
540 rdpr %tl, %g3
541 cmp %g3, 1
542 mov 1, %g3
543 bleu %xcc, 1f
544 sllx %g3, SFSTAT_TL_GT_ONE_SHIFT, %g3
545
546 or %g4, %g3, %g4
547
548 /* Read in the UDB error register state, clearing the
549 * sticky error bits as-needed. We only clear them if
550 * the UE bit is set. Likewise, __spitfire_cee_trap
551 * below will only do so if the CE bit is set.
552 *
553 * NOTE: UltraSparc-I/II have high and low UDB error
554 * registers, corresponding to the two UDB units
555 * present on those chips. UltraSparc-IIi only
556 * has a single UDB, called "SDB" in the manual.
557 * For IIi the upper UDB register always reads
558 * as zero so for our purposes things will just
559 * work with the checks below.
560 */
5611: ldxa [%g0] ASI_UDBH_ERROR_R, %g3
562 and %g3, 0x3ff, %g7 ! Paranoia
563 sllx %g7, SFSTAT_UDBH_SHIFT, %g7
564 or %g4, %g7, %g4
565 andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE
566 be,pn %xcc, 1f
David S. Millerbde4e4e2005-08-29 12:44:57 -0700567 nop
David S. Miller6c52a962005-08-29 12:45:11 -0700568 stxa %g3, [%g0] ASI_UDB_ERROR_W
569 membar #Sync
570
5711: mov 0x18, %g3
572 ldxa [%g3] ASI_UDBL_ERROR_R, %g3
573 and %g3, 0x3ff, %g7 ! Paranoia
574 sllx %g7, SFSTAT_UDBL_SHIFT, %g7
575 or %g4, %g7, %g4
576 andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE
577 be,pn %xcc, 1f
578 nop
579 mov 0x18, %g7
580 stxa %g3, [%g7] ASI_UDB_ERROR_W
581 membar #Sync
582
5831: /* Ok, now that we've latched the error state,
584 * clear the sticky bits in the AFSR.
585 */
586 stxa %g4, [%g0] ASI_AFSR
587 membar #Sync
588
589 rdpr %tl, %g2
590 cmp %g2, 1
591 rdpr %pil, %g2
592 bleu,pt %xcc, 1f
593 wrpr %g0, 15, %pil
594
David S. Millerbde4e4e2005-08-29 12:44:57 -0700595 ba,pt %xcc, etraptl1
David S. Miller6c52a962005-08-29 12:45:11 -0700596 rd %pc, %g7
David S. Millerbde4e4e2005-08-29 12:44:57 -0700597
David S. Miller6c52a962005-08-29 12:45:11 -0700598 ba,pt %xcc, 2f
599 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
David S. Miller6c52a962005-08-29 12:45:11 -07006011: ba,pt %xcc, etrap_irq
602 rd %pc, %g7
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603
David S. Miller6c52a962005-08-29 12:45:11 -07006042: mov %l4, %o1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 mov %l5, %o2
David S. Miller6c52a962005-08-29 12:45:11 -0700606 call spitfire_access_error
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 add %sp, PTREGS_OFF, %o0
608 ba,pt %xcc, rtrap
609 clr %l6
610
611 /* This is the trap handler entry point for ECC correctable
612 * errors. They are corrected, but we listen for the trap
613 * so that the event can be logged.
614 *
615 * Disrupting errors are either:
616 * 1) single-bit ECC errors during UDB reads to system
617 * memory
618 * 2) data parity errors during write-back events
619 *
620 * As far as I can make out from the manual, the CEE trap
621 * is only for correctable errors during memory read
622 * accesses by the front-end of the processor.
623 *
624 * The code below is only for trap level 1 CEE events,
625 * as it is the only situation where we can safely record
626 * and log. For trap level >1 we just clear the CE bit
627 * in the AFSR and return.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 *
David S. Miller6c52a962005-08-29 12:45:11 -0700629 * This is just like __spiftire_access_error above, but it
630 * specifically handles correctable errors. If an
631 * uncorrectable error is indicated in the AFSR we
632 * will branch directly above to __spitfire_access_error
633 * to handle it instead. Uncorrectable therefore takes
634 * priority over correctable, and the error logging
635 * C code will notice this case by inspecting the
636 * trap type.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 */
David S. Miller6c52a962005-08-29 12:45:11 -0700638 .globl __spitfire_cee_trap
639__spitfire_cee_trap:
640 ldxa [%g0] ASI_AFSR, %g4 ! Get AFSR
641 mov 1, %g3
642 sllx %g3, SFAFSR_UE_SHIFT, %g3
643 andcc %g4, %g3, %g0 ! Check for UE
644 bne,pn %xcc, __spitfire_access_error
645 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646
David S. Miller6c52a962005-08-29 12:45:11 -0700647 /* Ok, in this case we only have a correctable error.
648 * Indicate we only wish to capture that state in register
649 * %g1, and we only disable CE error reporting unlike UE
650 * handling which disables all errors.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 */
David S. Miller6c52a962005-08-29 12:45:11 -0700652 ldxa [%g0] ASI_ESTATE_ERROR_EN, %g3
653 andn %g3, ESTATE_ERR_CE, %g3
654 stxa %g3, [%g0] ASI_ESTATE_ERROR_EN
655 membar #Sync
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656
David S. Miller6c52a962005-08-29 12:45:11 -0700657 /* Preserve AFSR in %g4, indicate UDB state to capture in %g1 */
658 ba,pt %xcc, __spitfire_cee_trap_continue
659 mov UDBE_CE, %g1
660
661 .globl __spitfire_data_access_exception
662 .globl __spitfire_data_access_exception_tl1
663__spitfire_data_access_exception_tl1:
664 rdpr %pstate, %g4
665 wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
666 mov TLB_SFSR, %g3
667 mov DMMU_SFAR, %g5
668 ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR
669 ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR
670 stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit
671 membar #Sync
672 rdpr %tt, %g3
673 cmp %g3, 0x80 ! first win spill/fill trap
674 blu,pn %xcc, 1f
675 cmp %g3, 0xff ! last win spill/fill trap
676 bgu,pn %xcc, 1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 nop
David S. Miller6c52a962005-08-29 12:45:11 -0700678 ba,pt %xcc, winfix_dax
679 rdpr %tpc, %g3
6801: sethi %hi(109f), %g7
681 ba,pt %xcc, etraptl1
682109: or %g7, %lo(109b), %g7
683 mov %l4, %o1
684 mov %l5, %o2
685 call spitfire_data_access_exception_tl1
686 add %sp, PTREGS_OFF, %o0
687 ba,pt %xcc, rtrap
688 clr %l6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689
David S. Miller6c52a962005-08-29 12:45:11 -0700690__spitfire_data_access_exception:
691 rdpr %pstate, %g4
692 wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
693 mov TLB_SFSR, %g3
694 mov DMMU_SFAR, %g5
695 ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR
696 ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR
697 stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit
698 membar #Sync
699 sethi %hi(109f), %g7
700 ba,pt %xcc, etrap
701109: or %g7, %lo(109b), %g7
702 mov %l4, %o1
703 mov %l5, %o2
704 call spitfire_data_access_exception
705 add %sp, PTREGS_OFF, %o0
706 ba,pt %xcc, rtrap
707 clr %l6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708
David S. Miller6c52a962005-08-29 12:45:11 -0700709 .globl __spitfire_insn_access_exception
710 .globl __spitfire_insn_access_exception_tl1
711__spitfire_insn_access_exception_tl1:
712 rdpr %pstate, %g4
713 wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
714 mov TLB_SFSR, %g3
715 ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR
716 rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC
717 stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit
718 membar #Sync
719 sethi %hi(109f), %g7
720 ba,pt %xcc, etraptl1
721109: or %g7, %lo(109b), %g7
722 mov %l4, %o1
723 mov %l5, %o2
724 call spitfire_insn_access_exception_tl1
725 add %sp, PTREGS_OFF, %o0
726 ba,pt %xcc, rtrap
727 clr %l6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728
David S. Miller6c52a962005-08-29 12:45:11 -0700729__spitfire_insn_access_exception:
730 rdpr %pstate, %g4
731 wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
732 mov TLB_SFSR, %g3
733 ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR
734 rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC
735 stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit
736 membar #Sync
737 sethi %hi(109f), %g7
738 ba,pt %xcc, etrap
739109: or %g7, %lo(109b), %g7
740 mov %l4, %o1
741 mov %l5, %o2
742 call spitfire_insn_access_exception
743 add %sp, PTREGS_OFF, %o0
744 ba,pt %xcc, rtrap
745 clr %l6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 /* These get patched into the trap table at boot time
748 * once we know we have a cheetah processor.
749 */
750 .globl cheetah_fecc_trap_vector, cheetah_fecc_trap_vector_tl1
751cheetah_fecc_trap_vector:
752 membar #Sync
753 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1
754 andn %g1, DCU_DC | DCU_IC, %g1
755 stxa %g1, [%g0] ASI_DCU_CONTROL_REG
756 membar #Sync
757 sethi %hi(cheetah_fast_ecc), %g2
758 jmpl %g2 + %lo(cheetah_fast_ecc), %g0
759 mov 0, %g1
760cheetah_fecc_trap_vector_tl1:
761 membar #Sync
762 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1
763 andn %g1, DCU_DC | DCU_IC, %g1
764 stxa %g1, [%g0] ASI_DCU_CONTROL_REG
765 membar #Sync
766 sethi %hi(cheetah_fast_ecc), %g2
767 jmpl %g2 + %lo(cheetah_fast_ecc), %g0
768 mov 1, %g1
769 .globl cheetah_cee_trap_vector, cheetah_cee_trap_vector_tl1
770cheetah_cee_trap_vector:
771 membar #Sync
772 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1
773 andn %g1, DCU_IC, %g1
774 stxa %g1, [%g0] ASI_DCU_CONTROL_REG
775 membar #Sync
776 sethi %hi(cheetah_cee), %g2
777 jmpl %g2 + %lo(cheetah_cee), %g0
778 mov 0, %g1
779cheetah_cee_trap_vector_tl1:
780 membar #Sync
781 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1
782 andn %g1, DCU_IC, %g1
783 stxa %g1, [%g0] ASI_DCU_CONTROL_REG
784 membar #Sync
785 sethi %hi(cheetah_cee), %g2
786 jmpl %g2 + %lo(cheetah_cee), %g0
787 mov 1, %g1
788 .globl cheetah_deferred_trap_vector, cheetah_deferred_trap_vector_tl1
789cheetah_deferred_trap_vector:
790 membar #Sync
791 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1;
792 andn %g1, DCU_DC | DCU_IC, %g1;
793 stxa %g1, [%g0] ASI_DCU_CONTROL_REG;
794 membar #Sync;
795 sethi %hi(cheetah_deferred_trap), %g2
796 jmpl %g2 + %lo(cheetah_deferred_trap), %g0
797 mov 0, %g1
798cheetah_deferred_trap_vector_tl1:
799 membar #Sync;
800 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1;
801 andn %g1, DCU_DC | DCU_IC, %g1;
802 stxa %g1, [%g0] ASI_DCU_CONTROL_REG;
803 membar #Sync;
804 sethi %hi(cheetah_deferred_trap), %g2
805 jmpl %g2 + %lo(cheetah_deferred_trap), %g0
806 mov 1, %g1
807
808 /* Cheetah+ specific traps. These are for the new I/D cache parity
809 * error traps. The first argument to cheetah_plus_parity_handler
810 * is encoded as follows:
811 *
812 * Bit0: 0=dcache,1=icache
813 * Bit1: 0=recoverable,1=unrecoverable
814 */
815 .globl cheetah_plus_dcpe_trap_vector, cheetah_plus_dcpe_trap_vector_tl1
816cheetah_plus_dcpe_trap_vector:
817 membar #Sync
818 sethi %hi(do_cheetah_plus_data_parity), %g7
819 jmpl %g7 + %lo(do_cheetah_plus_data_parity), %g0
820 nop
821 nop
822 nop
823 nop
824 nop
825
826do_cheetah_plus_data_parity:
David S. Miller80dc0d62005-09-26 00:32:17 -0700827 rdpr %pil, %g2
828 wrpr %g0, 15, %pil
829 ba,pt %xcc, etrap_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 rd %pc, %g7
831 mov 0x0, %o0
832 call cheetah_plus_parity_error
833 add %sp, PTREGS_OFF, %o1
David S. Miller80dc0d62005-09-26 00:32:17 -0700834 ba,a,pt %xcc, rtrap_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835
836cheetah_plus_dcpe_trap_vector_tl1:
837 membar #Sync
838 wrpr PSTATE_IG | PSTATE_PEF | PSTATE_PRIV, %pstate
839 sethi %hi(do_dcpe_tl1), %g3
840 jmpl %g3 + %lo(do_dcpe_tl1), %g0
841 nop
842 nop
843 nop
844 nop
845
846 .globl cheetah_plus_icpe_trap_vector, cheetah_plus_icpe_trap_vector_tl1
847cheetah_plus_icpe_trap_vector:
848 membar #Sync
849 sethi %hi(do_cheetah_plus_insn_parity), %g7
850 jmpl %g7 + %lo(do_cheetah_plus_insn_parity), %g0
851 nop
852 nop
853 nop
854 nop
855 nop
856
857do_cheetah_plus_insn_parity:
David S. Miller80dc0d62005-09-26 00:32:17 -0700858 rdpr %pil, %g2
859 wrpr %g0, 15, %pil
860 ba,pt %xcc, etrap_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 rd %pc, %g7
862 mov 0x1, %o0
863 call cheetah_plus_parity_error
864 add %sp, PTREGS_OFF, %o1
David S. Miller80dc0d62005-09-26 00:32:17 -0700865 ba,a,pt %xcc, rtrap_irq
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866
867cheetah_plus_icpe_trap_vector_tl1:
868 membar #Sync
869 wrpr PSTATE_IG | PSTATE_PEF | PSTATE_PRIV, %pstate
870 sethi %hi(do_icpe_tl1), %g3
871 jmpl %g3 + %lo(do_icpe_tl1), %g0
872 nop
873 nop
874 nop
875 nop
876
877 /* If we take one of these traps when tl >= 1, then we
878 * jump to interrupt globals. If some trap level above us
879 * was also using interrupt globals, we cannot recover.
880 * We may use all interrupt global registers except %g6.
881 */
882 .globl do_dcpe_tl1, do_icpe_tl1
883do_dcpe_tl1:
884 rdpr %tl, %g1 ! Save original trap level
885 mov 1, %g2 ! Setup TSTATE checking loop
886 sethi %hi(TSTATE_IG), %g3 ! TSTATE mask bit
8871: wrpr %g2, %tl ! Set trap level to check
888 rdpr %tstate, %g4 ! Read TSTATE for this level
889 andcc %g4, %g3, %g0 ! Interrupt globals in use?
890 bne,a,pn %xcc, do_dcpe_tl1_fatal ! Yep, irrecoverable
891 wrpr %g1, %tl ! Restore original trap level
892 add %g2, 1, %g2 ! Next trap level
893 cmp %g2, %g1 ! Hit them all yet?
894 ble,pt %icc, 1b ! Not yet
895 nop
896 wrpr %g1, %tl ! Restore original trap level
897do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
David S. Miller80dc0d62005-09-26 00:32:17 -0700898 sethi %hi(dcache_parity_tl1_occurred), %g2
899 lduw [%g2 + %lo(dcache_parity_tl1_occurred)], %g1
900 add %g1, 1, %g1
901 stw %g1, [%g2 + %lo(dcache_parity_tl1_occurred)]
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 /* Reset D-cache parity */
903 sethi %hi(1 << 16), %g1 ! D-cache size
904 mov (1 << 5), %g2 ! D-cache line size
905 sub %g1, %g2, %g1 ! Move down 1 cacheline
9061: srl %g1, 14, %g3 ! Compute UTAG
907 membar #Sync
908 stxa %g3, [%g1] ASI_DCACHE_UTAG
909 membar #Sync
910 sub %g2, 8, %g3 ! 64-bit data word within line
9112: membar #Sync
912 stxa %g0, [%g1 + %g3] ASI_DCACHE_DATA
913 membar #Sync
914 subcc %g3, 8, %g3 ! Next 64-bit data word
915 bge,pt %icc, 2b
916 nop
917 subcc %g1, %g2, %g1 ! Next cacheline
918 bge,pt %icc, 1b
919 nop
920 ba,pt %xcc, dcpe_icpe_tl1_common
921 nop
922
923do_dcpe_tl1_fatal:
924 sethi %hi(1f), %g7
925 ba,pt %xcc, etraptl1
9261: or %g7, %lo(1b), %g7
927 mov 0x2, %o0
928 call cheetah_plus_parity_error
929 add %sp, PTREGS_OFF, %o1
930 ba,pt %xcc, rtrap
931 clr %l6
932
933do_icpe_tl1:
934 rdpr %tl, %g1 ! Save original trap level
935 mov 1, %g2 ! Setup TSTATE checking loop
936 sethi %hi(TSTATE_IG), %g3 ! TSTATE mask bit
9371: wrpr %g2, %tl ! Set trap level to check
938 rdpr %tstate, %g4 ! Read TSTATE for this level
939 andcc %g4, %g3, %g0 ! Interrupt globals in use?
940 bne,a,pn %xcc, do_icpe_tl1_fatal ! Yep, irrecoverable
941 wrpr %g1, %tl ! Restore original trap level
942 add %g2, 1, %g2 ! Next trap level
943 cmp %g2, %g1 ! Hit them all yet?
944 ble,pt %icc, 1b ! Not yet
945 nop
946 wrpr %g1, %tl ! Restore original trap level
947do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
David S. Miller80dc0d62005-09-26 00:32:17 -0700948 sethi %hi(icache_parity_tl1_occurred), %g2
949 lduw [%g2 + %lo(icache_parity_tl1_occurred)], %g1
950 add %g1, 1, %g1
951 stw %g1, [%g2 + %lo(icache_parity_tl1_occurred)]
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 /* Flush I-cache */
953 sethi %hi(1 << 15), %g1 ! I-cache size
954 mov (1 << 5), %g2 ! I-cache line size
955 sub %g1, %g2, %g1
9561: or %g1, (2 << 3), %g3
957 stxa %g0, [%g3] ASI_IC_TAG
958 membar #Sync
959 subcc %g1, %g2, %g1
960 bge,pt %icc, 1b
961 nop
962 ba,pt %xcc, dcpe_icpe_tl1_common
963 nop
964
965do_icpe_tl1_fatal:
966 sethi %hi(1f), %g7
967 ba,pt %xcc, etraptl1
9681: or %g7, %lo(1b), %g7
969 mov 0x3, %o0
970 call cheetah_plus_parity_error
971 add %sp, PTREGS_OFF, %o1
972 ba,pt %xcc, rtrap
973 clr %l6
974
975dcpe_icpe_tl1_common:
976 /* Flush D-cache, re-enable D/I caches in DCU and finally
977 * retry the trapping instruction.
978 */
979 sethi %hi(1 << 16), %g1 ! D-cache size
980 mov (1 << 5), %g2 ! D-cache line size
981 sub %g1, %g2, %g1
9821: stxa %g0, [%g1] ASI_DCACHE_TAG
983 membar #Sync
984 subcc %g1, %g2, %g1
985 bge,pt %icc, 1b
986 nop
987 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1
988 or %g1, (DCU_DC | DCU_IC), %g1
989 stxa %g1, [%g0] ASI_DCU_CONTROL_REG
990 membar #Sync
991 retry
992
David S. Miller3c2cafa2005-08-30 15:11:52 -0700993 /* Capture I/D/E-cache state into per-cpu error scoreboard.
994 *
995 * %g1: (TL>=0) ? 1 : 0
996 * %g2: scratch
997 * %g3: scratch
998 * %g4: AFSR
999 * %g5: AFAR
David S. Miller56fb4df2006-02-26 23:24:22 -08001000 * %g6: unused, will have current thread ptr after etrap
David S. Miller3c2cafa2005-08-30 15:11:52 -07001001 * %g7: scratch
1002 */
1003__cheetah_log_error:
1004 /* Put "TL1" software bit into AFSR. */
1005 and %g1, 0x1, %g1
1006 sllx %g1, 63, %g2
1007 or %g4, %g2, %g4
1008
1009 /* Get log entry pointer for this cpu at this trap level. */
1010 BRANCH_IF_JALAPENO(g2,g3,50f)
1011 ldxa [%g0] ASI_SAFARI_CONFIG, %g2
1012 srlx %g2, 17, %g2
1013 ba,pt %xcc, 60f
1014 and %g2, 0x3ff, %g2
1015
101650: ldxa [%g0] ASI_JBUS_CONFIG, %g2
1017 srlx %g2, 17, %g2
1018 and %g2, 0x1f, %g2
1019
102060: sllx %g2, 9, %g2
1021 sethi %hi(cheetah_error_log), %g3
1022 ldx [%g3 + %lo(cheetah_error_log)], %g3
1023 brz,pn %g3, 80f
1024 nop
1025
1026 add %g3, %g2, %g3
1027 sllx %g1, 8, %g1
1028 add %g3, %g1, %g1
1029
1030 /* %g1 holds pointer to the top of the logging scoreboard */
1031 ldx [%g1 + 0x0], %g7
1032 cmp %g7, -1
1033 bne,pn %xcc, 80f
1034 nop
1035
1036 stx %g4, [%g1 + 0x0]
1037 stx %g5, [%g1 + 0x8]
1038 add %g1, 0x10, %g1
1039
1040 /* %g1 now points to D-cache logging area */
1041 set 0x3ff8, %g2 /* DC_addr mask */
1042 and %g5, %g2, %g2 /* DC_addr bits of AFAR */
1043 srlx %g5, 12, %g3
1044 or %g3, 1, %g3 /* PHYS tag + valid */
1045
104610: ldxa [%g2] ASI_DCACHE_TAG, %g7
1047 cmp %g3, %g7 /* TAG match? */
1048 bne,pt %xcc, 13f
1049 nop
1050
1051 /* Yep, what we want, capture state. */
1052 stx %g2, [%g1 + 0x20]
1053 stx %g7, [%g1 + 0x28]
1054
1055 /* A membar Sync is required before and after utag access. */
1056 membar #Sync
1057 ldxa [%g2] ASI_DCACHE_UTAG, %g7
1058 membar #Sync
1059 stx %g7, [%g1 + 0x30]
1060 ldxa [%g2] ASI_DCACHE_SNOOP_TAG, %g7
1061 stx %g7, [%g1 + 0x38]
1062 clr %g3
1063
106412: ldxa [%g2 + %g3] ASI_DCACHE_DATA, %g7
1065 stx %g7, [%g1]
1066 add %g3, (1 << 5), %g3
1067 cmp %g3, (4 << 5)
1068 bl,pt %xcc, 12b
1069 add %g1, 0x8, %g1
1070
1071 ba,pt %xcc, 20f
1072 add %g1, 0x20, %g1
1073
107413: sethi %hi(1 << 14), %g7
1075 add %g2, %g7, %g2
1076 srlx %g2, 14, %g7
1077 cmp %g7, 4
1078 bl,pt %xcc, 10b
1079 nop
1080
1081 add %g1, 0x40, %g1
1082
1083 /* %g1 now points to I-cache logging area */
108420: set 0x1fe0, %g2 /* IC_addr mask */
1085 and %g5, %g2, %g2 /* IC_addr bits of AFAR */
1086 sllx %g2, 1, %g2 /* IC_addr[13:6]==VA[12:5] */
1087 srlx %g5, (13 - 8), %g3 /* Make PTAG */
1088 andn %g3, 0xff, %g3 /* Mask off undefined bits */
1089
109021: ldxa [%g2] ASI_IC_TAG, %g7
1091 andn %g7, 0xff, %g7
1092 cmp %g3, %g7
1093 bne,pt %xcc, 23f
1094 nop
1095
1096 /* Yep, what we want, capture state. */
1097 stx %g2, [%g1 + 0x40]
1098 stx %g7, [%g1 + 0x48]
1099 add %g2, (1 << 3), %g2
1100 ldxa [%g2] ASI_IC_TAG, %g7
1101 add %g2, (1 << 3), %g2
1102 stx %g7, [%g1 + 0x50]
1103 ldxa [%g2] ASI_IC_TAG, %g7
1104 add %g2, (1 << 3), %g2
1105 stx %g7, [%g1 + 0x60]
1106 ldxa [%g2] ASI_IC_TAG, %g7
1107 stx %g7, [%g1 + 0x68]
1108 sub %g2, (3 << 3), %g2
1109 ldxa [%g2] ASI_IC_STAG, %g7
1110 stx %g7, [%g1 + 0x58]
1111 clr %g3
1112 srlx %g2, 2, %g2
1113
111422: ldxa [%g2 + %g3] ASI_IC_INSTR, %g7
1115 stx %g7, [%g1]
1116 add %g3, (1 << 3), %g3
1117 cmp %g3, (8 << 3)
1118 bl,pt %xcc, 22b
1119 add %g1, 0x8, %g1
1120
1121 ba,pt %xcc, 30f
1122 add %g1, 0x30, %g1
1123
112423: sethi %hi(1 << 14), %g7
1125 add %g2, %g7, %g2
1126 srlx %g2, 14, %g7
1127 cmp %g7, 4
1128 bl,pt %xcc, 21b
1129 nop
1130
1131 add %g1, 0x70, %g1
1132
1133 /* %g1 now points to E-cache logging area */
113430: andn %g5, (32 - 1), %g2
1135 stx %g2, [%g1 + 0x20]
1136 ldxa [%g2] ASI_EC_TAG_DATA, %g7
1137 stx %g7, [%g1 + 0x28]
1138 ldxa [%g2] ASI_EC_R, %g0
1139 clr %g3
1140
114131: ldxa [%g3] ASI_EC_DATA, %g7
1142 stx %g7, [%g1 + %g3]
1143 add %g3, 0x8, %g3
1144 cmp %g3, 0x20
1145
1146 bl,pt %xcc, 31b
1147 nop
114880:
1149 rdpr %tt, %g2
1150 cmp %g2, 0x70
1151 be c_fast_ecc
1152 cmp %g2, 0x63
1153 be c_cee
1154 nop
1155 ba,pt %xcc, c_deferred
1156
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 /* Cheetah FECC trap handling, we get here from tl{0,1}_fecc
1158 * in the trap table. That code has done a memory barrier
1159 * and has disabled both the I-cache and D-cache in the DCU
1160 * control register. The I-cache is disabled so that we may
1161 * capture the corrupted cache line, and the D-cache is disabled
1162 * because corrupt data may have been placed there and we don't
1163 * want to reference it.
1164 *
1165 * %g1 is one if this trap occurred at %tl >= 1.
1166 *
1167 * Next, we turn off error reporting so that we don't recurse.
1168 */
1169 .globl cheetah_fast_ecc
1170cheetah_fast_ecc:
1171 ldxa [%g0] ASI_ESTATE_ERROR_EN, %g2
1172 andn %g2, ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN, %g2
1173 stxa %g2, [%g0] ASI_ESTATE_ERROR_EN
1174 membar #Sync
1175
1176 /* Fetch and clear AFSR/AFAR */
1177 ldxa [%g0] ASI_AFSR, %g4
1178 ldxa [%g0] ASI_AFAR, %g5
1179 stxa %g4, [%g0] ASI_AFSR
1180 membar #Sync
1181
David S. Miller3c2cafa2005-08-30 15:11:52 -07001182 ba,pt %xcc, __cheetah_log_error
1183 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184
David S. Miller3c2cafa2005-08-30 15:11:52 -07001185c_fast_ecc:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186 rdpr %pil, %g2
1187 wrpr %g0, 15, %pil
1188 ba,pt %xcc, etrap_irq
1189 rd %pc, %g7
1190 mov %l4, %o1
1191 mov %l5, %o2
1192 call cheetah_fecc_handler
1193 add %sp, PTREGS_OFF, %o0
1194 ba,a,pt %xcc, rtrap_irq
1195
1196 /* Our caller has disabled I-cache and performed membar Sync. */
1197 .globl cheetah_cee
1198cheetah_cee:
1199 ldxa [%g0] ASI_ESTATE_ERROR_EN, %g2
1200 andn %g2, ESTATE_ERROR_CEEN, %g2
1201 stxa %g2, [%g0] ASI_ESTATE_ERROR_EN
1202 membar #Sync
1203
1204 /* Fetch and clear AFSR/AFAR */
1205 ldxa [%g0] ASI_AFSR, %g4
1206 ldxa [%g0] ASI_AFAR, %g5
1207 stxa %g4, [%g0] ASI_AFSR
1208 membar #Sync
1209
David S. Miller3c2cafa2005-08-30 15:11:52 -07001210 ba,pt %xcc, __cheetah_log_error
1211 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212
David S. Miller3c2cafa2005-08-30 15:11:52 -07001213c_cee:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 rdpr %pil, %g2
1215 wrpr %g0, 15, %pil
1216 ba,pt %xcc, etrap_irq
1217 rd %pc, %g7
1218 mov %l4, %o1
1219 mov %l5, %o2
1220 call cheetah_cee_handler
1221 add %sp, PTREGS_OFF, %o0
1222 ba,a,pt %xcc, rtrap_irq
1223
1224 /* Our caller has disabled I-cache+D-cache and performed membar Sync. */
1225 .globl cheetah_deferred_trap
1226cheetah_deferred_trap:
1227 ldxa [%g0] ASI_ESTATE_ERROR_EN, %g2
1228 andn %g2, ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN, %g2
1229 stxa %g2, [%g0] ASI_ESTATE_ERROR_EN
1230 membar #Sync
1231
1232 /* Fetch and clear AFSR/AFAR */
1233 ldxa [%g0] ASI_AFSR, %g4
1234 ldxa [%g0] ASI_AFAR, %g5
1235 stxa %g4, [%g0] ASI_AFSR
1236 membar #Sync
1237
David S. Miller3c2cafa2005-08-30 15:11:52 -07001238 ba,pt %xcc, __cheetah_log_error
1239 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240
David S. Miller3c2cafa2005-08-30 15:11:52 -07001241c_deferred:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 rdpr %pil, %g2
1243 wrpr %g0, 15, %pil
1244 ba,pt %xcc, etrap_irq
1245 rd %pc, %g7
1246 mov %l4, %o1
1247 mov %l5, %o2
1248 call cheetah_deferred_handler
1249 add %sp, PTREGS_OFF, %o0
1250 ba,a,pt %xcc, rtrap_irq
1251
1252 .globl __do_privact
1253__do_privact:
1254 mov TLB_SFSR, %g3
1255 stxa %g0, [%g3] ASI_DMMU ! Clear FaultValid bit
1256 membar #Sync
1257 sethi %hi(109f), %g7
1258 ba,pt %xcc, etrap
1259109: or %g7, %lo(109b), %g7
1260 call do_privact
1261 add %sp, PTREGS_OFF, %o0
1262 ba,pt %xcc, rtrap
1263 clr %l6
1264
1265 .globl do_mna
1266do_mna:
1267 rdpr %tl, %g3
1268 cmp %g3, 1
1269
1270 /* Setup %g4/%g5 now as they are used in the
1271 * winfixup code.
1272 */
1273 mov TLB_SFSR, %g3
1274 mov DMMU_SFAR, %g4
1275 ldxa [%g4] ASI_DMMU, %g4
1276 ldxa [%g3] ASI_DMMU, %g5
1277 stxa %g0, [%g3] ASI_DMMU ! Clear FaultValid bit
1278 membar #Sync
1279 bgu,pn %icc, winfix_mna
1280 rdpr %tpc, %g3
1281
12821: sethi %hi(109f), %g7
1283 ba,pt %xcc, etrap
1284109: or %g7, %lo(109b), %g7
1285 mov %l4, %o1
1286 mov %l5, %o2
1287 call mem_address_unaligned
1288 add %sp, PTREGS_OFF, %o0
1289 ba,pt %xcc, rtrap
1290 clr %l6
1291
1292 .globl do_lddfmna
1293do_lddfmna:
1294 sethi %hi(109f), %g7
1295 mov TLB_SFSR, %g4
1296 ldxa [%g4] ASI_DMMU, %g5
1297 stxa %g0, [%g4] ASI_DMMU ! Clear FaultValid bit
1298 membar #Sync
1299 mov DMMU_SFAR, %g4
1300 ldxa [%g4] ASI_DMMU, %g4
1301 ba,pt %xcc, etrap
1302109: or %g7, %lo(109b), %g7
1303 mov %l4, %o1
1304 mov %l5, %o2
1305 call handle_lddfmna
1306 add %sp, PTREGS_OFF, %o0
1307 ba,pt %xcc, rtrap
1308 clr %l6
1309
1310 .globl do_stdfmna
1311do_stdfmna:
1312 sethi %hi(109f), %g7
1313 mov TLB_SFSR, %g4
1314 ldxa [%g4] ASI_DMMU, %g5
1315 stxa %g0, [%g4] ASI_DMMU ! Clear FaultValid bit
1316 membar #Sync
1317 mov DMMU_SFAR, %g4
1318 ldxa [%g4] ASI_DMMU, %g4
1319 ba,pt %xcc, etrap
1320109: or %g7, %lo(109b), %g7
1321 mov %l4, %o1
1322 mov %l5, %o2
1323 call handle_stdfmna
1324 add %sp, PTREGS_OFF, %o0
1325 ba,pt %xcc, rtrap
1326 clr %l6
1327
1328 .globl breakpoint_trap
1329breakpoint_trap:
1330 call sparc_breakpoint
1331 add %sp, PTREGS_OFF, %o0
1332 ba,pt %xcc, rtrap
1333 nop
1334
1335#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
1336 defined(CONFIG_SOLARIS_EMUL_MODULE)
1337 /* SunOS uses syscall zero as the 'indirect syscall' it looks
1338 * like indir_syscall(scall_num, arg0, arg1, arg2...); etc.
1339 * This is complete brain damage.
1340 */
1341 .globl sunos_indir
1342sunos_indir:
1343 srl %o0, 0, %o0
1344 mov %o7, %l4
1345 cmp %o0, NR_SYSCALLS
1346 blu,a,pt %icc, 1f
1347 sll %o0, 0x2, %o0
1348 sethi %hi(sunos_nosys), %l6
1349 b,pt %xcc, 2f
1350 or %l6, %lo(sunos_nosys), %l6
13511: sethi %hi(sunos_sys_table), %l7
1352 or %l7, %lo(sunos_sys_table), %l7
1353 lduw [%l7 + %o0], %l6
13542: mov %o1, %o0
1355 mov %o2, %o1
1356 mov %o3, %o2
1357 mov %o4, %o3
1358 mov %o5, %o4
1359 call %l6
1360 mov %l4, %o7
1361
1362 .globl sunos_getpid
1363sunos_getpid:
1364 call sys_getppid
1365 nop
1366 call sys_getpid
1367 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
1368 b,pt %xcc, ret_sys_call
1369 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1370
1371 /* SunOS getuid() returns uid in %o0 and euid in %o1 */
1372 .globl sunos_getuid
1373sunos_getuid:
1374 call sys32_geteuid16
1375 nop
1376 call sys32_getuid16
1377 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
1378 b,pt %xcc, ret_sys_call
1379 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1380
1381 /* SunOS getgid() returns gid in %o0 and egid in %o1 */
1382 .globl sunos_getgid
1383sunos_getgid:
1384 call sys32_getegid16
1385 nop
1386 call sys32_getgid16
1387 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
1388 b,pt %xcc, ret_sys_call
1389 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1390#endif
1391
1392 /* SunOS's execv() call only specifies the argv argument, the
1393 * environment settings are the same as the calling processes.
1394 */
1395 .globl sunos_execv
1396sys_execve:
1397 sethi %hi(sparc_execve), %g1
1398 ba,pt %xcc, execve_merge
1399 or %g1, %lo(sparc_execve), %g1
1400#ifdef CONFIG_COMPAT
1401 .globl sys_execve
1402sunos_execv:
1403 stx %g0, [%sp + PTREGS_OFF + PT_V9_I2]
1404 .globl sys32_execve
1405sys32_execve:
1406 sethi %hi(sparc32_execve), %g1
1407 or %g1, %lo(sparc32_execve), %g1
1408#endif
1409execve_merge:
1410 flushw
1411 jmpl %g1, %g0
1412 add %sp, PTREGS_OFF, %o0
1413
1414 .globl sys_pipe, sys_sigpause, sys_nis_syscall
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 .globl sys_rt_sigreturn
1416 .globl sys_ptrace
1417 .globl sys_sigaltstack
1418 .align 32
1419sys_pipe: ba,pt %xcc, sparc_pipe
1420 add %sp, PTREGS_OFF, %o0
1421sys_nis_syscall:ba,pt %xcc, c_sys_nis_syscall
1422 add %sp, PTREGS_OFF, %o0
1423sys_memory_ordering:
1424 ba,pt %xcc, sparc_memory_ordering
1425 add %sp, PTREGS_OFF, %o1
1426sys_sigaltstack:ba,pt %xcc, do_sigaltstack
1427 add %i6, STACK_BIAS, %o2
1428#ifdef CONFIG_COMPAT
1429 .globl sys32_sigstack
1430sys32_sigstack: ba,pt %xcc, do_sys32_sigstack
1431 mov %i6, %o2
1432 .globl sys32_sigaltstack
1433sys32_sigaltstack:
1434 ba,pt %xcc, do_sys32_sigaltstack
1435 mov %i6, %o2
1436#endif
1437 .align 32
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438#ifdef CONFIG_COMPAT
1439 .globl sys32_sigreturn
1440sys32_sigreturn:
1441 add %sp, PTREGS_OFF, %o0
1442 call do_sigreturn32
1443 add %o7, 1f-.-4, %o7
1444 nop
1445#endif
1446sys_rt_sigreturn:
1447 add %sp, PTREGS_OFF, %o0
1448 call do_rt_sigreturn
1449 add %o7, 1f-.-4, %o7
1450 nop
1451#ifdef CONFIG_COMPAT
1452 .globl sys32_rt_sigreturn
1453sys32_rt_sigreturn:
1454 add %sp, PTREGS_OFF, %o0
1455 call do_rt_sigreturn32
1456 add %o7, 1f-.-4, %o7
1457 nop
1458#endif
1459sys_ptrace: add %sp, PTREGS_OFF, %o0
1460 call do_ptrace
1461 add %o7, 1f-.-4, %o7
1462 nop
1463 .align 32
14641: ldx [%curptr + TI_FLAGS], %l5
David S. Millerf7ceba32005-07-10 19:29:45 -07001465 andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 be,pt %icc, rtrap
1467 clr %l6
David S. Miller8d8a6472005-07-10 16:55:48 -07001468 add %sp, PTREGS_OFF, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 call syscall_trace
David S. Miller8d8a6472005-07-10 16:55:48 -07001470 mov 1, %o1
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471
1472 ba,pt %xcc, rtrap
1473 clr %l6
1474
1475 /* This is how fork() was meant to be done, 8 instruction entry.
1476 *
1477 * I questioned the following code briefly, let me clear things
1478 * up so you must not reason on it like I did.
1479 *
1480 * Know the fork_kpsr etc. we use in the sparc32 port? We don't
1481 * need it here because the only piece of window state we copy to
1482 * the child is the CWP register. Even if the parent sleeps,
1483 * we are safe because we stuck it into pt_regs of the parent
1484 * so it will not change.
1485 *
1486 * XXX This raises the question, whether we can do the same on
1487 * XXX sparc32 to get rid of fork_kpsr _and_ fork_kwim. The
1488 * XXX answer is yes. We stick fork_kpsr in UREG_G0 and
1489 * XXX fork_kwim in UREG_G1 (global registers are considered
1490 * XXX volatile across a system call in the sparc ABI I think
1491 * XXX if it isn't we can use regs->y instead, anyone who depends
1492 * XXX upon the Y register being preserved across a fork deserves
1493 * XXX to lose).
1494 *
1495 * In fact we should take advantage of that fact for other things
1496 * during system calls...
1497 */
1498 .globl sys_fork, sys_vfork, sys_clone, sparc_exit
1499 .globl ret_from_syscall
1500 .align 32
1501sys_vfork: /* Under Linux, vfork and fork are just special cases of clone. */
1502 sethi %hi(0x4000 | 0x0100 | SIGCHLD), %o0
1503 or %o0, %lo(0x4000 | 0x0100 | SIGCHLD), %o0
1504 ba,pt %xcc, sys_clone
1505sys_fork: clr %o1
1506 mov SIGCHLD, %o0
1507sys_clone: flushw
1508 movrz %o1, %fp, %o1
1509 mov 0, %o3
1510 ba,pt %xcc, sparc_do_fork
1511 add %sp, PTREGS_OFF, %o2
1512ret_from_syscall:
David S. Millerdb7d9a42005-07-24 19:36:26 -07001513 /* Clear current_thread_info()->new_child, and
1514 * check performance counter stuff too.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 */
David S. Millerdb7d9a42005-07-24 19:36:26 -07001516 stb %g0, [%g6 + TI_NEW_CHILD]
1517 ldx [%g6 + TI_FLAGS], %l0
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 call schedule_tail
1519 mov %g7, %o0
1520 andcc %l0, _TIF_PERFCTR, %g0
1521 be,pt %icc, 1f
1522 nop
1523 ldx [%g6 + TI_PCR], %o7
1524 wr %g0, %o7, %pcr
1525
1526 /* Blackbird errata workaround. See commentary in
1527 * smp.c:smp_percpu_timer_interrupt() for more
1528 * information.
1529 */
1530 ba,pt %xcc, 99f
1531 nop
1532 .align 64
153399: wr %g0, %g0, %pic
1534 rd %pic, %g0
1535
15361: b,pt %xcc, ret_sys_call
1537 ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0
David S. Miller764afe22006-01-31 18:34:06 -08001538sparc_exit: rdpr %pstate, %g2
1539 wrpr %g2, PSTATE_IE, %pstate
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 rdpr %otherwin, %g1
1541 rdpr %cansave, %g3
1542 add %g3, %g1, %g3
1543 wrpr %g3, 0x0, %cansave
1544 wrpr %g0, 0x0, %otherwin
David S. Miller764afe22006-01-31 18:34:06 -08001545 wrpr %g2, 0x0, %pstate
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 ba,pt %xcc, sys_exit
1547 stb %g0, [%g6 + TI_WSAVED]
1548
1549linux_sparc_ni_syscall:
1550 sethi %hi(sys_ni_syscall), %l7
1551 b,pt %xcc, 4f
1552 or %l7, %lo(sys_ni_syscall), %l7
1553
1554linux_syscall_trace32:
David S. Miller8d8a6472005-07-10 16:55:48 -07001555 add %sp, PTREGS_OFF, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556 call syscall_trace
David S. Miller8d8a6472005-07-10 16:55:48 -07001557 clr %o1
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558 srl %i0, 0, %o0
David S. Miller8d8a6472005-07-10 16:55:48 -07001559 srl %i4, 0, %o4
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560 srl %i1, 0, %o1
1561 srl %i2, 0, %o2
1562 b,pt %xcc, 2f
1563 srl %i3, 0, %o3
1564
1565linux_syscall_trace:
David S. Miller8d8a6472005-07-10 16:55:48 -07001566 add %sp, PTREGS_OFF, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 call syscall_trace
David S. Miller8d8a6472005-07-10 16:55:48 -07001568 clr %o1
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569 mov %i0, %o0
1570 mov %i1, %o1
1571 mov %i2, %o2
1572 mov %i3, %o3
1573 b,pt %xcc, 2f
1574 mov %i4, %o4
1575
1576
1577 /* Linux 32-bit and SunOS system calls enter here... */
1578 .align 32
1579 .globl linux_sparc_syscall32
1580linux_sparc_syscall32:
1581 /* Direct access to user regs, much faster. */
1582 cmp %g1, NR_SYSCALLS ! IEU1 Group
1583 bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI
1584 srl %i0, 0, %o0 ! IEU0
1585 sll %g1, 2, %l4 ! IEU0 Group
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 srl %i4, 0, %o4 ! IEU1
1587 lduw [%l7 + %l4], %l7 ! Load
1588 srl %i1, 0, %o1 ! IEU0 Group
1589 ldx [%curptr + TI_FLAGS], %l0 ! Load
1590
1591 srl %i5, 0, %o5 ! IEU1
1592 srl %i2, 0, %o2 ! IEU0 Group
David S. Millerf7ceba32005-07-10 19:29:45 -07001593 andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 bne,pn %icc, linux_syscall_trace32 ! CTI
1595 mov %i0, %l5 ! IEU1
1596 call %l7 ! CTI Group brk forced
1597 srl %i3, 0, %o3 ! IEU0
1598 ba,a,pt %xcc, 3f
1599
1600 /* Linux native and SunOS system calls enter here... */
1601 .align 32
1602 .globl linux_sparc_syscall, ret_sys_call
1603linux_sparc_syscall:
1604 /* Direct access to user regs, much faster. */
1605 cmp %g1, NR_SYSCALLS ! IEU1 Group
1606 bgeu,pn %xcc, linux_sparc_ni_syscall ! CTI
1607 mov %i0, %o0 ! IEU0
1608 sll %g1, 2, %l4 ! IEU0 Group
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609 mov %i1, %o1 ! IEU1
1610 lduw [%l7 + %l4], %l7 ! Load
16114: mov %i2, %o2 ! IEU0 Group
1612 ldx [%curptr + TI_FLAGS], %l0 ! Load
1613
1614 mov %i3, %o3 ! IEU1
1615 mov %i4, %o4 ! IEU0 Group
David S. Millerf7ceba32005-07-10 19:29:45 -07001616 andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 bne,pn %icc, linux_syscall_trace ! CTI Group
1618 mov %i0, %l5 ! IEU0
16192: call %l7 ! CTI Group brk forced
1620 mov %i5, %o5 ! IEU0
1621 nop
1622
16233: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1624ret_sys_call:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
1626 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
1627 sra %o0, 0, %o0
1628 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
1629 sllx %g2, 32, %g2
1630
1631 /* Check if force_successful_syscall_return()
1632 * was invoked.
1633 */
Richard Mortimer695ca072006-01-09 14:35:50 -08001634 ldub [%curptr + TI_SYS_NOERROR], %l2
1635 brnz,a,pn %l2, 80f
David S. Millerdb7d9a42005-07-24 19:36:26 -07001636 stb %g0, [%curptr + TI_SYS_NOERROR]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 cmp %o0, -ERESTART_RESTARTBLOCK
1639 bgeu,pn %xcc, 1f
David S. Millerf7ceba32005-07-10 19:29:45 -07001640 andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164180:
1642 /* System call success, clear Carry condition code. */
1643 andn %g3, %g2, %g3
1644 stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
1645 bne,pn %icc, linux_syscall_trace2
1646 add %l1, 0x4, %l2 ! npc = npc+4
1647 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
1648 ba,pt %xcc, rtrap_clr_l6
1649 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
1650
16511:
1652 /* System call failure, set Carry condition code.
1653 * Also, get abs(errno) to return to the process.
1654 */
David S. Millerf7ceba32005-07-10 19:29:45 -07001655 andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 sub %g0, %o0, %o0
1657 or %g3, %g2, %g3
1658 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1659 mov 1, %l6
1660 stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
1661 bne,pn %icc, linux_syscall_trace2
1662 add %l1, 0x4, %l2 ! npc = npc+4
1663 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
1664
1665 b,pt %xcc, rtrap
1666 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
1667linux_syscall_trace2:
David S. Miller8d8a6472005-07-10 16:55:48 -07001668 add %sp, PTREGS_OFF, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 call syscall_trace
David S. Miller8d8a6472005-07-10 16:55:48 -07001670 mov 1, %o1
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
1672 ba,pt %xcc, rtrap
1673 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
1674
1675 .align 32
1676 .globl __flushw_user
1677__flushw_user:
1678 rdpr %otherwin, %g1
1679 brz,pn %g1, 2f
1680 clr %g2
16811: save %sp, -128, %sp
1682 rdpr %otherwin, %g1
1683 brnz,pt %g1, 1b
1684 add %g2, 1, %g2
16851: sub %g2, 1, %g2
1686 brnz,pt %g2, 1b
1687 restore %g0, %g0, %g0
16882: retl
1689 nop
David S. Miller56fb4df2006-02-26 23:24:22 -08001690
David S. Miller92704a12006-02-26 23:27:19 -08001691#ifdef CONFIG_SMP
1692 .globl hard_smp_processor_id
1693hard_smp_processor_id:
1694 __GET_CPUID(%o0)
David S. Miller56fb4df2006-02-26 23:24:22 -08001695 retl
1696 nop
David S. Miller92704a12006-02-26 23:27:19 -08001697#endif
David S. Miller85dfa192006-02-13 00:02:16 -08001698
1699 /* %o0: devhandle
1700 * %o1: devino
1701 *
1702 * returns %o0: sysino
1703 */
1704 .globl pci_sun4v_devino_to_sysino
1705sun4v_devino_to_sysino:
1706 mov HV_FAST_INTR_DEVINO2SYSINO, %o5
1707 ta HV_FAST_TRAP
1708 retl
1709 mov %o1, %o0