1 /* These get patched into the trap table at boot time
2 * once we know we have a cheetah processor.
4 .globl cheetah_fecc_trap_vector
5 .type cheetah_fecc_trap_vector,#function
6 cheetah_fecc_trap_vector:
8 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1
9 andn %g1, DCU_DC | DCU_IC, %g1
10 stxa %g1, [%g0] ASI_DCU_CONTROL_REG
12 sethi %hi(cheetah_fast_ecc), %g2
13 jmpl %g2 + %lo(cheetah_fast_ecc), %g0
15 .size cheetah_fecc_trap_vector,.-cheetah_fecc_trap_vector
17 .globl cheetah_fecc_trap_vector_tl1
18 .type cheetah_fecc_trap_vector_tl1,#function
19 cheetah_fecc_trap_vector_tl1:
21 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1
22 andn %g1, DCU_DC | DCU_IC, %g1
23 stxa %g1, [%g0] ASI_DCU_CONTROL_REG
25 sethi %hi(cheetah_fast_ecc), %g2
26 jmpl %g2 + %lo(cheetah_fast_ecc), %g0
28 .size cheetah_fecc_trap_vector_tl1,.-cheetah_fecc_trap_vector_tl1
30 .globl cheetah_cee_trap_vector
31 .type cheetah_cee_trap_vector,#function
32 cheetah_cee_trap_vector:
34 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1
36 stxa %g1, [%g0] ASI_DCU_CONTROL_REG
38 sethi %hi(cheetah_cee), %g2
39 jmpl %g2 + %lo(cheetah_cee), %g0
41 .size cheetah_cee_trap_vector,.-cheetah_cee_trap_vector
43 .globl cheetah_cee_trap_vector_tl1
44 .type cheetah_cee_trap_vector_tl1,#function
45 cheetah_cee_trap_vector_tl1:
47 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1
49 stxa %g1, [%g0] ASI_DCU_CONTROL_REG
51 sethi %hi(cheetah_cee), %g2
52 jmpl %g2 + %lo(cheetah_cee), %g0
54 .size cheetah_cee_trap_vector_tl1,.-cheetah_cee_trap_vector_tl1
56 .globl cheetah_deferred_trap_vector
57 .type cheetah_deferred_trap_vector,#function
58 cheetah_deferred_trap_vector:
60 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1;
61 andn %g1, DCU_DC | DCU_IC, %g1;
62 stxa %g1, [%g0] ASI_DCU_CONTROL_REG;
64 sethi %hi(cheetah_deferred_trap), %g2
65 jmpl %g2 + %lo(cheetah_deferred_trap), %g0
67 .size cheetah_deferred_trap_vector,.-cheetah_deferred_trap_vector
69 .globl cheetah_deferred_trap_vector_tl1
70 .type cheetah_deferred_trap_vector_tl1,#function
71 cheetah_deferred_trap_vector_tl1:
73 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1;
74 andn %g1, DCU_DC | DCU_IC, %g1;
75 stxa %g1, [%g0] ASI_DCU_CONTROL_REG;
77 sethi %hi(cheetah_deferred_trap), %g2
78 jmpl %g2 + %lo(cheetah_deferred_trap), %g0
80 .size cheetah_deferred_trap_vector_tl1,.-cheetah_deferred_trap_vector_tl1
82 /* Cheetah+ specific traps. These are for the new I/D cache parity
83 * error traps. The first argument to cheetah_plus_parity_handler
84 * is encoded as follows:
86 * Bit0: 0=dcache,1=icache
87 * Bit1: 0=recoverable,1=unrecoverable
89 .globl cheetah_plus_dcpe_trap_vector
90 .type cheetah_plus_dcpe_trap_vector,#function
91 cheetah_plus_dcpe_trap_vector:
93 sethi %hi(do_cheetah_plus_data_parity), %g7
94 jmpl %g7 + %lo(do_cheetah_plus_data_parity), %g0
100 .size cheetah_plus_dcpe_trap_vector,.-cheetah_plus_dcpe_trap_vector
102 .type do_cheetah_plus_data_parity,#function
103 do_cheetah_plus_data_parity:
105 wrpr %g0, PIL_NORMAL_MAX, %pil
106 ba,pt %xcc, etrap_irq
108 #ifdef CONFIG_TRACE_IRQFLAGS
109 call trace_hardirqs_off
113 call cheetah_plus_parity_error
114 add %sp, PTREGS_OFF, %o1
115 ba,a,pt %xcc, rtrap_irq
116 .size do_cheetah_plus_data_parity,.-do_cheetah_plus_data_parity
118 .globl cheetah_plus_dcpe_trap_vector_tl1
119 .type cheetah_plus_dcpe_trap_vector_tl1,#function
120 cheetah_plus_dcpe_trap_vector_tl1:
122 wrpr PSTATE_IG | PSTATE_PEF | PSTATE_PRIV, %pstate
123 sethi %hi(do_dcpe_tl1), %g3
124 jmpl %g3 + %lo(do_dcpe_tl1), %g0
129 .size cheetah_plus_dcpe_trap_vector_tl1,.-cheetah_plus_dcpe_trap_vector_tl1
131 .globl cheetah_plus_icpe_trap_vector
132 .type cheetah_plus_icpe_trap_vector,#function
133 cheetah_plus_icpe_trap_vector:
135 sethi %hi(do_cheetah_plus_insn_parity), %g7
136 jmpl %g7 + %lo(do_cheetah_plus_insn_parity), %g0
142 .size cheetah_plus_icpe_trap_vector,.-cheetah_plus_icpe_trap_vector
144 .type do_cheetah_plus_insn_parity,#function
145 do_cheetah_plus_insn_parity:
147 wrpr %g0, PIL_NORMAL_MAX, %pil
148 ba,pt %xcc, etrap_irq
150 #ifdef CONFIG_TRACE_IRQFLAGS
151 call trace_hardirqs_off
155 call cheetah_plus_parity_error
156 add %sp, PTREGS_OFF, %o1
157 ba,a,pt %xcc, rtrap_irq
158 .size do_cheetah_plus_insn_parity,.-do_cheetah_plus_insn_parity
160 .globl cheetah_plus_icpe_trap_vector_tl1
161 .type cheetah_plus_icpe_trap_vector_tl1,#function
162 cheetah_plus_icpe_trap_vector_tl1:
164 wrpr PSTATE_IG | PSTATE_PEF | PSTATE_PRIV, %pstate
165 sethi %hi(do_icpe_tl1), %g3
166 jmpl %g3 + %lo(do_icpe_tl1), %g0
171 .size cheetah_plus_icpe_trap_vector_tl1,.-cheetah_plus_icpe_trap_vector_tl1
173 /* If we take one of these traps when tl >= 1, then we
174 * jump to interrupt globals. If some trap level above us
175 * was also using interrupt globals, we cannot recover.
176 * We may use all interrupt global registers except %g6.
179 .type do_dcpe_tl1,#function
181 rdpr %tl, %g1 ! Save original trap level
182 mov 1, %g2 ! Setup TSTATE checking loop
183 sethi %hi(TSTATE_IG), %g3 ! TSTATE mask bit
184 1: wrpr %g2, %tl ! Set trap level to check
185 rdpr %tstate, %g4 ! Read TSTATE for this level
186 andcc %g4, %g3, %g0 ! Interrupt globals in use?
187 bne,a,pn %xcc, do_dcpe_tl1_fatal ! Yep, irrecoverable
188 wrpr %g1, %tl ! Restore original trap level
189 add %g2, 1, %g2 ! Next trap level
190 cmp %g2, %g1 ! Hit them all yet?
191 ble,pt %icc, 1b ! Not yet
193 wrpr %g1, %tl ! Restore original trap level
194 do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
195 sethi %hi(dcache_parity_tl1_occurred), %g2
196 lduw [%g2 + %lo(dcache_parity_tl1_occurred)], %g1
198 stw %g1, [%g2 + %lo(dcache_parity_tl1_occurred)]
199 /* Reset D-cache parity */
200 sethi %hi(1 << 16), %g1 ! D-cache size
201 mov (1 << 5), %g2 ! D-cache line size
202 sub %g1, %g2, %g1 ! Move down 1 cacheline
203 1: srl %g1, 14, %g3 ! Compute UTAG
205 stxa %g3, [%g1] ASI_DCACHE_UTAG
207 sub %g2, 8, %g3 ! 64-bit data word within line
209 stxa %g0, [%g1 + %g3] ASI_DCACHE_DATA
211 subcc %g3, 8, %g3 ! Next 64-bit data word
214 subcc %g1, %g2, %g1 ! Next cacheline
217 ba,pt %xcc, dcpe_icpe_tl1_common
223 1: or %g7, %lo(1b), %g7
225 call cheetah_plus_parity_error
226 add %sp, PTREGS_OFF, %o1
229 .size do_dcpe_tl1,.-do_dcpe_tl1
232 .type do_icpe_tl1,#function
234 rdpr %tl, %g1 ! Save original trap level
235 mov 1, %g2 ! Setup TSTATE checking loop
236 sethi %hi(TSTATE_IG), %g3 ! TSTATE mask bit
237 1: wrpr %g2, %tl ! Set trap level to check
238 rdpr %tstate, %g4 ! Read TSTATE for this level
239 andcc %g4, %g3, %g0 ! Interrupt globals in use?
240 bne,a,pn %xcc, do_icpe_tl1_fatal ! Yep, irrecoverable
241 wrpr %g1, %tl ! Restore original trap level
242 add %g2, 1, %g2 ! Next trap level
243 cmp %g2, %g1 ! Hit them all yet?
244 ble,pt %icc, 1b ! Not yet
246 wrpr %g1, %tl ! Restore original trap level
247 do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
248 sethi %hi(icache_parity_tl1_occurred), %g2
249 lduw [%g2 + %lo(icache_parity_tl1_occurred)], %g1
251 stw %g1, [%g2 + %lo(icache_parity_tl1_occurred)]
253 sethi %hi(1 << 15), %g1 ! I-cache size
254 mov (1 << 5), %g2 ! I-cache line size
256 1: or %g1, (2 << 3), %g3
257 stxa %g0, [%g3] ASI_IC_TAG
262 ba,pt %xcc, dcpe_icpe_tl1_common
268 1: or %g7, %lo(1b), %g7
270 call cheetah_plus_parity_error
271 add %sp, PTREGS_OFF, %o1
274 .size do_icpe_tl1,.-do_icpe_tl1
276 .type dcpe_icpe_tl1_common,#function
277 dcpe_icpe_tl1_common:
278 /* Flush D-cache, re-enable D/I caches in DCU and finally
279 * retry the trapping instruction.
281 sethi %hi(1 << 16), %g1 ! D-cache size
282 mov (1 << 5), %g2 ! D-cache line size
284 1: stxa %g0, [%g1] ASI_DCACHE_TAG
289 ldxa [%g0] ASI_DCU_CONTROL_REG, %g1
290 or %g1, (DCU_DC | DCU_IC), %g1
291 stxa %g1, [%g0] ASI_DCU_CONTROL_REG
294 .size dcpe_icpe_tl1_common,.-dcpe_icpe_tl1_common
296 /* Capture I/D/E-cache state into per-cpu error scoreboard.
298 * %g1: (TL>=0) ? 1 : 0
303 * %g6: unused, will have current thread ptr after etrap
306 .type __cheetah_log_error,#function
308 /* Put "TL1" software bit into AFSR. */
313 /* Get log entry pointer for this cpu at this trap level. */
314 BRANCH_IF_JALAPENO(g2,g3,50f)
315 ldxa [%g0] ASI_SAFARI_CONFIG, %g2
320 50: ldxa [%g0] ASI_JBUS_CONFIG, %g2
325 sethi %hi(cheetah_error_log), %g3
326 ldx [%g3 + %lo(cheetah_error_log)], %g3
334 /* %g1 holds pointer to the top of the logging scoreboard */
344 /* %g1 now points to D-cache logging area */
345 set 0x3ff8, %g2 /* DC_addr mask */
346 and %g5, %g2, %g2 /* DC_addr bits of AFAR */
348 or %g3, 1, %g3 /* PHYS tag + valid */
350 10: ldxa [%g2] ASI_DCACHE_TAG, %g7
351 cmp %g3, %g7 /* TAG match? */
355 /* Yep, what we want, capture state. */
356 stx %g2, [%g1 + 0x20]
357 stx %g7, [%g1 + 0x28]
359 /* A membar Sync is required before and after utag access. */
361 ldxa [%g2] ASI_DCACHE_UTAG, %g7
363 stx %g7, [%g1 + 0x30]
364 ldxa [%g2] ASI_DCACHE_SNOOP_TAG, %g7
365 stx %g7, [%g1 + 0x38]
368 12: ldxa [%g2 + %g3] ASI_DCACHE_DATA, %g7
370 add %g3, (1 << 5), %g3
378 13: sethi %hi(1 << 14), %g7
387 /* %g1 now points to I-cache logging area */
388 20: set 0x1fe0, %g2 /* IC_addr mask */
389 and %g5, %g2, %g2 /* IC_addr bits of AFAR */
390 sllx %g2, 1, %g2 /* IC_addr[13:6]==VA[12:5] */
391 srlx %g5, (13 - 8), %g3 /* Make PTAG */
392 andn %g3, 0xff, %g3 /* Mask off undefined bits */
394 21: ldxa [%g2] ASI_IC_TAG, %g7
400 /* Yep, what we want, capture state. */
401 stx %g2, [%g1 + 0x40]
402 stx %g7, [%g1 + 0x48]
403 add %g2, (1 << 3), %g2
404 ldxa [%g2] ASI_IC_TAG, %g7
405 add %g2, (1 << 3), %g2
406 stx %g7, [%g1 + 0x50]
407 ldxa [%g2] ASI_IC_TAG, %g7
408 add %g2, (1 << 3), %g2
409 stx %g7, [%g1 + 0x60]
410 ldxa [%g2] ASI_IC_TAG, %g7
411 stx %g7, [%g1 + 0x68]
412 sub %g2, (3 << 3), %g2
413 ldxa [%g2] ASI_IC_STAG, %g7
414 stx %g7, [%g1 + 0x58]
418 22: ldxa [%g2 + %g3] ASI_IC_INSTR, %g7
420 add %g3, (1 << 3), %g3
428 23: sethi %hi(1 << 14), %g7
437 /* %g1 now points to E-cache logging area */
438 30: andn %g5, (32 - 1), %g2
439 stx %g2, [%g1 + 0x20]
440 ldxa [%g2] ASI_EC_TAG_DATA, %g7
441 stx %g7, [%g1 + 0x28]
442 ldxa [%g2] ASI_EC_R, %g0
445 31: ldxa [%g3] ASI_EC_DATA, %g7
459 ba,pt %xcc, c_deferred
460 .size __cheetah_log_error,.-__cheetah_log_error
462 /* Cheetah FECC trap handling, we get here from tl{0,1}_fecc
463 * in the trap table. That code has done a memory barrier
464 * and has disabled both the I-cache and D-cache in the DCU
465 * control register. The I-cache is disabled so that we may
466 * capture the corrupted cache line, and the D-cache is disabled
467 * because corrupt data may have been placed there and we don't
468 * want to reference it.
470 * %g1 is one if this trap occurred at %tl >= 1.
472 * Next, we turn off error reporting so that we don't recurse.
474 .globl cheetah_fast_ecc
475 .type cheetah_fast_ecc,#function
477 ldxa [%g0] ASI_ESTATE_ERROR_EN, %g2
478 andn %g2, ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN, %g2
479 stxa %g2, [%g0] ASI_ESTATE_ERROR_EN
482 /* Fetch and clear AFSR/AFAR */
483 ldxa [%g0] ASI_AFSR, %g4
484 ldxa [%g0] ASI_AFAR, %g5
485 stxa %g4, [%g0] ASI_AFSR
488 ba,pt %xcc, __cheetah_log_error
490 .size cheetah_fast_ecc,.-cheetah_fast_ecc
492 .type c_fast_ecc,#function
495 wrpr %g0, PIL_NORMAL_MAX, %pil
496 ba,pt %xcc, etrap_irq
498 #ifdef CONFIG_TRACE_IRQFLAGS
499 call trace_hardirqs_off
504 call cheetah_fecc_handler
505 add %sp, PTREGS_OFF, %o0
506 ba,a,pt %xcc, rtrap_irq
507 .size c_fast_ecc,.-c_fast_ecc
509 /* Our caller has disabled I-cache and performed membar Sync. */
511 .type cheetah_cee,#function
513 ldxa [%g0] ASI_ESTATE_ERROR_EN, %g2
514 andn %g2, ESTATE_ERROR_CEEN, %g2
515 stxa %g2, [%g0] ASI_ESTATE_ERROR_EN
518 /* Fetch and clear AFSR/AFAR */
519 ldxa [%g0] ASI_AFSR, %g4
520 ldxa [%g0] ASI_AFAR, %g5
521 stxa %g4, [%g0] ASI_AFSR
524 ba,pt %xcc, __cheetah_log_error
526 .size cheetah_cee,.-cheetah_cee
528 .type c_cee,#function
531 wrpr %g0, PIL_NORMAL_MAX, %pil
532 ba,pt %xcc, etrap_irq
534 #ifdef CONFIG_TRACE_IRQFLAGS
535 call trace_hardirqs_off
540 call cheetah_cee_handler
541 add %sp, PTREGS_OFF, %o0
542 ba,a,pt %xcc, rtrap_irq
545 /* Our caller has disabled I-cache+D-cache and performed membar Sync. */
546 .globl cheetah_deferred_trap
547 .type cheetah_deferred_trap,#function
548 cheetah_deferred_trap:
549 ldxa [%g0] ASI_ESTATE_ERROR_EN, %g2
550 andn %g2, ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN, %g2
551 stxa %g2, [%g0] ASI_ESTATE_ERROR_EN
554 /* Fetch and clear AFSR/AFAR */
555 ldxa [%g0] ASI_AFSR, %g4
556 ldxa [%g0] ASI_AFAR, %g5
557 stxa %g4, [%g0] ASI_AFSR
560 ba,pt %xcc, __cheetah_log_error
562 .size cheetah_deferred_trap,.-cheetah_deferred_trap
564 .type c_deferred,#function
567 wrpr %g0, PIL_NORMAL_MAX, %pil
568 ba,pt %xcc, etrap_irq
570 #ifdef CONFIG_TRACE_IRQFLAGS
571 call trace_hardirqs_off
576 call cheetah_deferred_handler
577 add %sp, PTREGS_OFF, %o0
578 ba,a,pt %xcc, rtrap_irq
579 .size c_deferred,.-c_deferred