Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[deliverable/linux.git] / arch / sparc / kernel / spiterrs.S
1 /* We need to carefully read the error status, ACK the errors,
2 * prevent recursive traps, and pass the information on to C
3 * code for logging.
4 *
5 * We pass the AFAR in as-is, and we encode the status
6 * information as described in asm-sparc64/sfafsr.h
7 */
8 .type __spitfire_access_error,#function
9 __spitfire_access_error:
10 /* Disable ESTATE error reporting so that we do not take
11 * recursive traps and RED state the processor.
12 */
13 stxa %g0, [%g0] ASI_ESTATE_ERROR_EN
14 membar #Sync
15
16 mov UDBE_UE, %g1
17 ldxa [%g0] ASI_AFSR, %g4 ! Get AFSR
18
19 /* __spitfire_cee_trap branches here with AFSR in %g4 and
20 * UDBE_CE in %g1. It only clears ESTATE_ERR_CE in the ESTATE
21 * Error Enable register.
22 */
23 __spitfire_cee_trap_continue:
24 ldxa [%g0] ASI_AFAR, %g5 ! Get AFAR
25
26 rdpr %tt, %g3
27 and %g3, 0x1ff, %g3 ! Paranoia
28 sllx %g3, SFSTAT_TRAP_TYPE_SHIFT, %g3
29 or %g4, %g3, %g4
30 rdpr %tl, %g3
31 cmp %g3, 1
32 mov 1, %g3
33 bleu %xcc, 1f
34 sllx %g3, SFSTAT_TL_GT_ONE_SHIFT, %g3
35
36 or %g4, %g3, %g4
37
38 /* Read in the UDB error register state, clearing the sticky
39 * error bits as-needed. We only clear them if the UE bit is
40 * set. Likewise, __spitfire_cee_trap below will only do so
41 * if the CE bit is set.
42 *
43 * NOTE: UltraSparc-I/II have high and low UDB error
44 * registers, corresponding to the two UDB units
45 * present on those chips. UltraSparc-IIi only
46 * has a single UDB, called "SDB" in the manual.
47 * For IIi the upper UDB register always reads
48 * as zero so for our purposes things will just
49 * work with the checks below.
50 */
51 1: ldxa [%g0] ASI_UDBH_ERROR_R, %g3
52 and %g3, 0x3ff, %g7 ! Paranoia
53 sllx %g7, SFSTAT_UDBH_SHIFT, %g7
54 or %g4, %g7, %g4
55 andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE
56 be,pn %xcc, 1f
57 nop
58 stxa %g3, [%g0] ASI_UDB_ERROR_W
59 membar #Sync
60
61 1: mov 0x18, %g3
62 ldxa [%g3] ASI_UDBL_ERROR_R, %g3
63 and %g3, 0x3ff, %g7 ! Paranoia
64 sllx %g7, SFSTAT_UDBL_SHIFT, %g7
65 or %g4, %g7, %g4
66 andcc %g3, %g1, %g3 ! UDBE_UE or UDBE_CE
67 be,pn %xcc, 1f
68 nop
69 mov 0x18, %g7
70 stxa %g3, [%g7] ASI_UDB_ERROR_W
71 membar #Sync
72
73 1: /* Ok, now that we've latched the error state, clear the
74 * sticky bits in the AFSR.
75 */
76 stxa %g4, [%g0] ASI_AFSR
77 membar #Sync
78
79 rdpr %tl, %g2
80 cmp %g2, 1
81 rdpr %pil, %g2
82 bleu,pt %xcc, 1f
83 wrpr %g0, PIL_NORMAL_MAX, %pil
84
85 ba,pt %xcc, etraptl1
86 rd %pc, %g7
87
88 ba,a,pt %xcc, 2f
89
90 1: ba,pt %xcc, etrap_irq
91 rd %pc, %g7
92
93 2:
94 #ifdef CONFIG_TRACE_IRQFLAGS
95 call trace_hardirqs_off
96 nop
97 #endif
98 mov %l4, %o1
99 mov %l5, %o2
100 call spitfire_access_error
101 add %sp, PTREGS_OFF, %o0
102 ba,a,pt %xcc, rtrap
103 .size __spitfire_access_error,.-__spitfire_access_error
104
105 /* This is the trap handler entry point for ECC correctable
106 * errors. They are corrected, but we listen for the trap so
107 * that the event can be logged.
108 *
109 * Disrupting errors are either:
110 * 1) single-bit ECC errors during UDB reads to system
111 * memory
112 * 2) data parity errors during write-back events
113 *
114 * As far as I can make out from the manual, the CEE trap is
115 * only for correctable errors during memory read accesses by
116 * the front-end of the processor.
117 *
118 * The code below is only for trap level 1 CEE events, as it
119 * is the only situation where we can safely record and log.
120 * For trap level >1 we just clear the CE bit in the AFSR and
121 * return.
122 *
123 * This is just like __spiftire_access_error above, but it
124 * specifically handles correctable errors. If an
125 * uncorrectable error is indicated in the AFSR we will branch
126 * directly above to __spitfire_access_error to handle it
127 * instead. Uncorrectable therefore takes priority over
128 * correctable, and the error logging C code will notice this
129 * case by inspecting the trap type.
130 */
131 .type __spitfire_cee_trap,#function
132 __spitfire_cee_trap:
133 ldxa [%g0] ASI_AFSR, %g4 ! Get AFSR
134 mov 1, %g3
135 sllx %g3, SFAFSR_UE_SHIFT, %g3
136 andcc %g4, %g3, %g0 ! Check for UE
137 bne,pn %xcc, __spitfire_access_error
138 nop
139
140 /* Ok, in this case we only have a correctable error.
141 * Indicate we only wish to capture that state in register
142 * %g1, and we only disable CE error reporting unlike UE
143 * handling which disables all errors.
144 */
145 ldxa [%g0] ASI_ESTATE_ERROR_EN, %g3
146 andn %g3, ESTATE_ERR_CE, %g3
147 stxa %g3, [%g0] ASI_ESTATE_ERROR_EN
148 membar #Sync
149
150 /* Preserve AFSR in %g4, indicate UDB state to capture in %g1 */
151 ba,pt %xcc, __spitfire_cee_trap_continue
152 mov UDBE_CE, %g1
153 .size __spitfire_cee_trap,.-__spitfire_cee_trap
154
155 .type __spitfire_data_access_exception_tl1,#function
156 __spitfire_data_access_exception_tl1:
157 rdpr %pstate, %g4
158 wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
159 mov TLB_SFSR, %g3
160 mov DMMU_SFAR, %g5
161 ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR
162 ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR
163 stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit
164 membar #Sync
165 rdpr %tt, %g3
166 cmp %g3, 0x80 ! first win spill/fill trap
167 blu,pn %xcc, 1f
168 cmp %g3, 0xff ! last win spill/fill trap
169 bgu,pn %xcc, 1f
170 nop
171 ba,pt %xcc, winfix_dax
172 rdpr %tpc, %g3
173 1: sethi %hi(109f), %g7
174 ba,pt %xcc, etraptl1
175 109: or %g7, %lo(109b), %g7
176 mov %l4, %o1
177 mov %l5, %o2
178 call spitfire_data_access_exception_tl1
179 add %sp, PTREGS_OFF, %o0
180 ba,a,pt %xcc, rtrap
181 .size __spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1
182
183 .type __spitfire_data_access_exception,#function
184 __spitfire_data_access_exception:
185 rdpr %pstate, %g4
186 wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
187 mov TLB_SFSR, %g3
188 mov DMMU_SFAR, %g5
189 ldxa [%g3] ASI_DMMU, %g4 ! Get SFSR
190 ldxa [%g5] ASI_DMMU, %g5 ! Get SFAR
191 stxa %g0, [%g3] ASI_DMMU ! Clear SFSR.FaultValid bit
192 membar #Sync
193 sethi %hi(109f), %g7
194 ba,pt %xcc, etrap
195 109: or %g7, %lo(109b), %g7
196 mov %l4, %o1
197 mov %l5, %o2
198 call spitfire_data_access_exception
199 add %sp, PTREGS_OFF, %o0
200 ba,a,pt %xcc, rtrap
201 .size __spitfire_data_access_exception,.-__spitfire_data_access_exception
202
203 .type __spitfire_insn_access_exception_tl1,#function
204 __spitfire_insn_access_exception_tl1:
205 rdpr %pstate, %g4
206 wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
207 mov TLB_SFSR, %g3
208 ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR
209 rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC
210 stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit
211 membar #Sync
212 sethi %hi(109f), %g7
213 ba,pt %xcc, etraptl1
214 109: or %g7, %lo(109b), %g7
215 mov %l4, %o1
216 mov %l5, %o2
217 call spitfire_insn_access_exception_tl1
218 add %sp, PTREGS_OFF, %o0
219 ba,a,pt %xcc, rtrap
220 .size __spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1
221
222 .type __spitfire_insn_access_exception,#function
223 __spitfire_insn_access_exception:
224 rdpr %pstate, %g4
225 wrpr %g4, PSTATE_MG|PSTATE_AG, %pstate
226 mov TLB_SFSR, %g3
227 ldxa [%g3] ASI_IMMU, %g4 ! Get SFSR
228 rdpr %tpc, %g5 ! IMMU has no SFAR, use TPC
229 stxa %g0, [%g3] ASI_IMMU ! Clear FaultValid bit
230 membar #Sync
231 sethi %hi(109f), %g7
232 ba,pt %xcc, etrap
233 109: or %g7, %lo(109b), %g7
234 mov %l4, %o1
235 mov %l5, %o2
236 call spitfire_insn_access_exception
237 add %sp, PTREGS_OFF, %o0
238 ba,a,pt %xcc, rtrap
239 .size __spitfire_insn_access_exception,.-__spitfire_insn_access_exception
This page took 0.035535 seconds and 5 git commands to generate.