xref: /netbsd-src/sys/arch/m68k/m68k/busaddrerr.s (revision 4d0e49ff20b3eb5cbf5076ead107a0b1f1b2559d)
1/*	$NetBSD: busaddrerr.s,v 1.3 2024/01/13 18:40:12 thorpej Exp $	*/
2
3/*
4 * Copyright (c) 1988 University of Utah.
5 * Copyright (c) 1980, 1990, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * the Systems Programming Group of the University of Utah Computer
10 * Science Department.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 *    may be used to endorse or promote products derived from this software
22 *    without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * from: Utah $Hdr: locore.s 1.66 92/12/22$
37 *
38 *	@(#)locore.s	8.6 (Berkeley) 5/27/94
39 */
40
41/*
42 * bus error and address error handler routines common to all m68k ports.
43 */
44
45/*
46 * NOTICE: This is not a standalone file.  To use it, #include it in
47 * your port's locore.s, like so:
48 *
49 *	#include <m68k/m68k/busaddrerr.s>
50 */
51
52/* assume M68K_MMU_MOTOROLA is default if none is defined */
53#if !defined(M68K_MMU_MOTOROLA) && !defined(M68K_MMU_HP)
54#define M68K_MMU_MOTOROLA
55#endif
56
57/*
58 * address error handler for 68040/68060
59 */
60#if defined(M68040) || defined(M68060)
61ENTRY_NOPROFILE(addrerr4060)
62	clrl	%sp@-			| stack adjust count
63	moveml	%d0-%d7/%a0-%a7,%sp@-	| save user registers
64	movl	%usp,%a0		| save the user SP
65	movl	%a0,%sp@(FR_SP)		|   in the savearea
66	movl	%sp@(FR_HW+8),%sp@-
67	clrl	%sp@-			| dummy code
68	movl	#T_ADDRERR,%sp@-	| mark address error
69	jra	_ASM_LABEL(faultstkadj)	| and deal with it
70#endif
71
72/*
73 * bus error handler for 68060
74 */
75#if defined(M68060)
76ENTRY_NOPROFILE(buserr60)
77	clrl	%sp@-			| stack adjust count
78	moveml	%d0-%d7/%a0-%a7,%sp@-	| save user registers
79	movl	%usp,%a0		| save the user SP
80	movl	%a0,%sp@(FR_SP)		|   in the savearea
81	movel	%sp@(FR_HW+12),%d0	| FSLW
82	btst	#2,%d0			| branch prediction error?
83	jeq	Lnobpe
84	movc	%cacr,%d2
85	orl	#IC60_CABC,%d2		| clear all branch cache entries
86	movc	%d2,%cacr
87	movl	%d0,%d1
88#if defined(amiga) || defined(atari)
89	addql	#1,L60bpe
90#endif
91	andl	#0x7ffd,%d1		| check other faults
92	jeq	_ASM_LABEL(faultstkadjnotrap2)
93Lnobpe:
94| we need to adjust for misaligned addresses
95	movl	%sp@(FR_HW+8),%d1	| grab VA
96	btst	#27,%d0			| check for mis-aligned access
97	jeq	Lberr3			| no, skip
98	addl	#28,%d1			| yes, get into next page
99					| operand case: 3,
100					| instruction case: 4+12+12
101					| XXX instr. case not done yet
102	andl	#PG_FRAME,%d1		| and truncate
103Lberr3:
104	movl	%d1,%sp@-
105	movl	%d0,%sp@-		| code is FSLW now.
106	andw	#0x1f80,%d0
107	jeq	Lberr60			| it is a bus error
108	movl	#T_MMUFLT,%sp@-		| show that we are an MMU fault
109	jra	_ASM_LABEL(faultstkadj)	| and deal with it
110Lberr60:
111	tstl	_C_LABEL(nofault)	| catch bus error?
112	jeq	Lisberr			| no, handle as usual
113#ifdef mac68k
114	movl	%a2,_C_LABEL(mac68k_a2_fromfault) | save %a2
115	movl	%sp@(FR_HW+8+8),_C_LABEL(m68k_fault_addr) | save fault addr
116#endif
117	movl	_C_LABEL(nofault),%sp@-	| yes,
118	jbsr	_C_LABEL(longjmp)	|  longjmp(nofault)
119	/* NOTREACHED */
120#endif
121
122/*
123 * bus error handler for 68040
124 */
125#if defined(M68040)
126ENTRY_NOPROFILE(buserr40)
127	clrl	%sp@-			| stack adjust count
128	moveml	%d0-%d7/%a0-%a7,%sp@-	| save user registers
129	movl	%usp,%a0		| save the user SP
130	movl	%a0,%sp@(FR_SP)		|   in the savearea
131	movl	%sp@(FR_HW+20),%d1	| get fault address
132	moveq	#0,%d0
133	movw	%sp@(FR_HW+12),%d0	| get SSW
134	btst	#11,%d0			| check for mis-aligned
135	jeq	Lbe1stpg		| no skip
136	addl	#3,%d1			| get into next page
137	andl	#PG_FRAME,%d1		| and truncate
138Lbe1stpg:
139	movl	%d1,%sp@-		| pass fault address.
140	movl	%d0,%sp@-		| pass SSW as code
141	btst	#10,%d0			| test ATC
142	jeq	Lberr40			| it is a bus error
143	movl	#T_MMUFLT,%sp@-		| show that we are an MMU fault
144	jra	_ASM_LABEL(faultstkadj)	| and deal with it
145Lberr40:
146	tstl	_C_LABEL(nofault)	| catch bus error?
147	jeq	Lisberr			| no, handle as usual
148#ifdef mac68k
149	movl	%a2,_C_LABEL(mac68k_a2_fromfault) | save %a2
150	movl	%sp@(FR_HW+8+20),_C_LABEL(m68k_fault_addr) | save fault addr
151#endif
152	movl	_C_LABEL(nofault),%sp@-	| yes,
153	jbsr	_C_LABEL(longjmp)	|  longjmp(nofault)
154	/* NOTREACHED */
155#endif
156
157/*
158 * bus error and address error handlers for 68020/68030
159 */
160#if defined(M68020) || defined(M68030)
161ENTRY_NOPROFILE(busaddrerr2030)
162GLOBAL(buserr2030)
163GLOBAL(addrerr2030)
164	clrl	%sp@-			| stack adjust count
165	moveml	%d0-%d7/%a0-%a7,%sp@-	| save user registers
166	movl	%usp,%a0		| save the user SP
167	movl	%a0,%sp@(FR_SP)		|   in the savearea
168	moveq	#0,%d0
169	movw	%sp@(FR_HW+10),%d0	| grab SSW for fault processing
170	btst	#12,%d0			| RB set?
171	jeq	LbeX0			| no, test RC
172	bset	#14,%d0			| yes, must set FB
173	movw	%d0,%sp@(FR_HW+10)	| for hardware too
174LbeX0:
175	btst	#13,%d0			| RC set?
176	jeq	LbeX1			| no, skip
177	bset	#15,%d0			| yes, must set FC
178	movw	%d0,%sp@(FR_HW+10)	| for hardware too
179LbeX1:
180	btst	#8,%d0			| data fault?
181	jeq	Lbe0			| no, check for hard cases
182	movl	%sp@(FR_HW+16),%d1	| fault address is as given in frame
183	jra	Lbe10			| thats it
184Lbe0:
185	btst	#4,%sp@(FR_HW+6)	| long (type B) stack frame?
186	jne	Lbe4			| yes, go handle
187	movl	%sp@(FR_HW+2),%d1	| no, can use save PC
188	btst	#14,%d0			| FB set?
189	jeq	Lbe3			| no, try FC
190	addql	#4,%d1			| yes, adjust address
191	jra	Lbe10			| done
192Lbe3:
193	btst	#15,%d0			| FC set?
194	jeq	Lbe10			| no, done
195	addql	#2,%d1			| yes, adjust address
196	jra	Lbe10			| done
197Lbe4:
198	movl	%sp@(FR_HW+36),%d1	| long format, use stage B address
199	btst	#15,%d0			| FC set?
200	jeq	Lbe10			| no, all done
201	subql	#2,%d1			| yes, adjust address
202Lbe10:
203	movl	%d1,%sp@-		| push fault VA
204	movl	%d0,%sp@-		| and padded SSW
205	movw	%sp@(FR_HW+8+6),%d0	| get frame format/vector offset
206	andw	#0x0FFF,%d0		| clear out frame format
207	cmpw	#12,%d0			| address error vector?
208	jeq	Lisaerr			| yes, go to it
209#if defined(M68K_MMU_MOTOROLA)
210#if defined(M68K_MMU_HP)
211	tstl	_C_LABEL(mmutype)	| HP MMU?
212	jeq	Lbehpmmu		| yes, different MMU fault handler
213#endif
214	movl	%d1,%a0			| fault address
215	movl	%sp@,%d0		| function code from ssw
216	btst	#8,%d0			| data fault?
217	jne	Lbe10a
218	movql	#1,%d0			| user program access FC
219					| (we dont separate data/program)
220	btst	#5,%sp@(FR_HW+8)	| supervisor mode?
221	jeq	Lbe10a			| if no, done
222	movql	#5,%d0			| else supervisor program access
223Lbe10a:
224	ptestr	%d0,%a0@,#0		| only PTEST #0 can detect transparent
225	pmove	%psr,%sp@		|   translation (TT0 or TT1).
226	movw	%sp@,%d1
227	btst	#6,%d1			| transparent (TT0 or TT1)?
228	jne	Lisberr1		| yes -> bus error
229	ptestr	%d0,%a0@,#7		| no, do a table search
230	pmove	%psr,%sp@		| save result
231	movb	%sp@,%d1
232	btst	#2,%d1			| invalid (incl. limit viol. and berr)?
233	jeq	Lmightnotbemerr		| no -> wp check
234	btst	#7,%d1			| is it MMU table berr?
235	jne	Lisberr1		| yes, needs not be fast.
236#endif /* M68K_MMU_MOTOROLA */
237Lismerr:
238	movl	#T_MMUFLT,%sp@-		| show that we are an MMU fault
239	jra	_ASM_LABEL(faultstkadj)	| and deal with it
240#if defined(M68K_MMU_MOTOROLA)
241Lmightnotbemerr:
242	btst	#3,%d1			| write protect bit set?
243	jeq	Lisberr1		| no, must be bus error
244	movl	%sp@,%d0		| ssw into low word of d0
245	andw	#0xc0,%d0		| write protect is set on page:
246	cmpw	#0x40,%d0		| was it read cycle?
247	jne	Lismerr			| no, was not WPE, must be MMU fault
248	jra	Lisberr1		| real bus err needs not be fast.
249#endif /* M68K_MMU_MOTOROLA */
250#if defined(M68K_MMU_HP)
251Lbehpmmu:
252	MMUADDR(%a0)
253	movl    %a0@(MMUSTAT),%d0       | read MMU status
254        btst	#3,%d0			| MMU fault?
255	jeq	Lisberr1		| no, just a non-MMU bus error
256	andl	#~MMU_FAULT,%a0@(MMUSTAT)| yes, clear fault bits
257	movw	%d0,%sp@		| pass MMU stat in upper half of code
258	jra	Lismerr			| and handle it
259#endif
260Lisaerr:
261	movl	#T_ADDRERR,%sp@-	| mark address error
262	jra	_ASM_LABEL(faultstkadj)	| and deal with it
263Lisberr1:
264	clrw	%sp@			| re-clear pad word
265	tstl	_C_LABEL(nofault)	| catch bus error?
266	jeq	Lisberr			| no, handle as usual
267#ifdef mac68k
268	movl	%a2,_C_LABEL(mac68k_a2_fromfault) | save %a2
269	movl	%sp@(FR_HW+8+16),_C_LABEL(m68k_fault_addr) | save fault addr
270#endif
271	movl	_C_LABEL(nofault),%sp@-	| yes,
272	jbsr	_C_LABEL(longjmp)	|  longjmp(nofault)
273	/* NOTREACHED */
274#endif /* M68020 || M68030 */
275
276Lisberr:				| also used by M68040/60
277	movl	#T_BUSERR,%sp@-		| mark bus error
278	jra	_ASM_LABEL(faultstkadj)	| and deal with it
279
280