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