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