Home | History | Annotate | Line # | Download | only in m68k
      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)
     61 ENTRY_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)
     76 ENTRY_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)
     93 Lnobpe:
     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
    103 Lberr3:
    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
    110 Lberr60:
    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)
    126 ENTRY_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
    138 Lbe1stpg:
    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
    145 Lberr40:
    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)
    161 ENTRY_NOPROFILE(busaddrerr2030)
    162 GLOBAL(buserr2030)
    163 GLOBAL(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
    174 LbeX0:
    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
    179 LbeX1:
    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
    184 Lbe0:
    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
    192 Lbe3:
    193 	btst	#15,%d0			| FC set?
    194 	jeq	Lbe10			| no, done
    195 	addql	#2,%d1			| yes, adjust address
    196 	jra	Lbe10			| done
    197 Lbe4:
    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
    202 Lbe10:
    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
    223 Lbe10a:
    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 */
    237 Lismerr:
    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)
    241 Lmightnotbemerr:
    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)
    251 Lbehpmmu:
    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
    260 Lisaerr:
    261 	movl	#T_ADDRERR,%sp@-	| mark address error
    262 	jra	_ASM_LABEL(faultstkadj)	| and deal with it
    263 Lisberr1:
    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 
    276 Lisberr:				| also used by M68040/60
    277 	movl	#T_BUSERR,%sp@-		| mark bus error
    278 	jra	_ASM_LABEL(faultstkadj)	| and deal with it
    279 
    280