Module Name: src Committed By: tsutsui Date: Sat Mar 15 09:22:37 UTC 2014
Added Files: src/sys/arch/m68k/m68k: busaddrerr.s Log Message: Add a common source of m68k bus error and address error handlers. This will be included from each MD locore.s as other common m68k asm files like trap_subr.s and support.s etc. To generate a diff of this commit: cvs rdiff -u -r0 -r1.1 src/sys/arch/m68k/m68k/busaddrerr.s Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Added files: Index: src/sys/arch/m68k/m68k/busaddrerr.s diff -u /dev/null src/sys/arch/m68k/m68k/busaddrerr.s:1.1 --- /dev/null Sat Mar 15 09:22:37 2014 +++ src/sys/arch/m68k/m68k/busaddrerr.s Sat Mar 15 09:22:36 2014 @@ -0,0 +1,272 @@ +/* $NetBSD: busaddrerr.s,v 1.1 2014/03/15 09:22:36 tsutsui Exp $ */ + +/* + * Copyright (c) 1988 University of Utah. + * Copyright (c) 1980, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: Utah $Hdr: locore.s 1.66 92/12/22$ + * + * @(#)locore.s 8.6 (Berkeley) 5/27/94 + */ + +/* + * bus error and address error handler routines common to all m68k ports. + */ + +/* + * NOTICE: This is not a standalone file. To use it, #include it in + * your port's locore.s, like so: + * + * #include <m68k/m68k/busaddrerr.s> + */ + +/* assume M68K_MMU_MOTOROLA is default if none is defined */ +#if !defined(M68K_MMU_MOTOROLA) && !defined(M68K_MMU_HP) +#define M68K_MMU_MOTOROLA +#endif + +/* + * address error handler for 68040/68060 + */ +#if defined(M68040) || defined(M68060) +ENTRY_NOPROFILE(addrerr4060) + clrl %sp@- | stack adjust count + moveml %d0-%d7/%a0-%a7,%sp@- | save user registers + movl %usp,%a0 | save the user SP + movl %a0,%sp@(FR_SP) | in the savearea + movl %sp@(FR_HW+8),%sp@- + clrl %sp@- | dummy code + movl #T_ADDRERR,%sp@- | mark address error + jra _ASM_LABEL(faultstkadj) | and deal with it +#endif + +/* + * bus error handler for 68060 + */ +#if defined(M68060) +ENTRY_NOPROFILE(buserr60) + clrl %sp@- | stack adjust count + moveml %d0-%d7/%a0-%a7,%sp@- | save user registers + movl %usp,%a0 | save the user SP + movl %a0,%sp@(FR_SP) | in the savearea + movel %sp@(FR_HW+12),%d0 | FSLW + btst #2,%d0 | branch prediction error? + jeq Lnobpe + movc %cacr,%d2 + orl #IC60_CABC,%d2 | clear all branch cache entries + movc %d2,%cacr + movl %d0,%d1 +#if defined(amiga) || defined(atari) + addql #1,L60bpe +#endif + andl #0x7ffd,%d1 | check other faults + jeq _ASM_LABEL(faultstkadjnotrap2) +Lnobpe: +| we need to adjust for misaligned addresses + movl %sp@(FR_HW+8),%d1 | grab VA + btst #27,%d0 | check for mis-aligned access + jeq Lberr3 | no, skip + addl #28,%d1 | yes, get into next page + | operand case: 3, + | instruction case: 4+12+12 + | XXX instr. case not done yet + andl #PG_FRAME,%d1 | and truncate +Lberr3: + movl %d1,%sp@- + movl %d0,%sp@- | code is FSLW now. + andw #0x1f80,%d0 + jeq Lberr60 | it is a bus error + movl #T_MMUFLT,%sp@- | show that we are an MMU fault + jra _ASM_LABEL(faultstkadj) | and deal with it +Lberr60: + tstl _C_LABEL(nofault) | catch bus error? + jeq Lisberr | no, handle as usual +#ifdef mac68k + movl %a2,_C_LABEL(mac68k_a2_fromfault) | save %a2 + movl %sp@(FR_HW+8+8),_C_LABEL(m68k_fault_addr) | save fault addr +#endif + movl _C_LABEL(nofault),%sp@- | yes, + jbsr _C_LABEL(longjmp) | longjmp(nofault) + /* NOTREACHED */ +#endif + +/* + * bus error handler for 68040 + */ +#if defined(M68040) +ENTRY_NOPROFILE(buserr40) + clrl %sp@- | stack adjust count + moveml %d0-%d7/%a0-%a7,%sp@- | save user registers + movl %usp,%a0 | save the user SP + movl %a0,%sp@(FR_SP) | in the savearea + movl %sp@(FR_HW+20),%d1 | get fault address + moveq #0,%d0 + movw %sp@(FR_HW+12),%d0 | get SSW + btst #11,%d0 | check for mis-aligned + jeq Lbe1stpg | no skip + addl #3,%d1 | get into next page + andl #PG_FRAME,%d1 | and truncate +Lbe1stpg: + movl %d1,%sp@- | pass fault address. + movl %d0,%sp@- | pass SSW as code + btst #10,%d0 | test ATC + jeq Lberr40 | it is a bus error + movl #T_MMUFLT,%sp@- | show that we are an MMU fault + jra _ASM_LABEL(faultstkadj) | and deal with it +Lberr40: + tstl _C_LABEL(nofault) | catch bus error? + jeq Lisberr | no, handle as usual +#ifdef mac68k + movl %a2,_C_LABEL(mac68k_a2_fromfault) | save %a2 + movl %sp@(FR_HW+8+20),_C_LABEL(m68k_fault_addr) | save fault addr +#endif + movl _C_LABEL(nofault),%sp@- | yes, + jbsr _C_LABEL(longjmp) | longjmp(nofault) + /* NOTREACHED */ +#endif + +/* + * bus error and address error handlers for 68020/68030 + */ +#if defined(M68020) || defined(M68030) +ENTRY_NOPROFILE(busaddrerr2030) + clrl %sp@- | stack adjust count + moveml %d0-%d7/%a0-%a7,%sp@- | save user registers + movl %usp,%a0 | save the user SP + movl %a0,%sp@(FR_SP) | in the savearea + moveq #0,%d0 + movw %sp@(FR_HW+10),%d0 | grab SSW for fault processing + btst #12,%d0 | RB set? + jeq LbeX0 | no, test RC + bset #14,%d0 | yes, must set FB + movw %d0,%sp@(FR_HW+10) | for hardware too +LbeX0: + btst #13,%d0 | RC set? + jeq LbeX1 | no, skip + bset #15,%d0 | yes, must set FC + movw %d0,%sp@(FR_HW+10) | for hardware too +LbeX1: + btst #8,%d0 | data fault? + jeq Lbe0 | no, check for hard cases + movl %sp@(FR_HW+16),%d1 | fault address is as given in frame + jra Lbe10 | thats it +Lbe0: + btst #4,%sp@(FR_HW+6) | long (type B) stack frame? + jne Lbe4 | yes, go handle + movl %sp@(FR_HW+2),%d1 | no, can use save PC + btst #14,%d0 | FB set? + jeq Lbe3 | no, try FC + addql #4,%d1 | yes, adjust address + jra Lbe10 | done +Lbe3: + btst #15,%d0 | FC set? + jeq Lbe10 | no, done + addql #2,%d1 | yes, adjust address + jra Lbe10 | done +Lbe4: + movl %sp@(FR_HW+36),%d1 | long format, use stage B address + btst #15,%d0 | FC set? + jeq Lbe10 | no, all done + subql #2,%d1 | yes, adjust address +Lbe10: + movl %d1,%sp@- | push fault VA + movl %d0,%sp@- | and padded SSW + movw %sp@(FR_HW+8+6),%d0 | get frame format/vector offset + andw #0x0FFF,%d0 | clear out frame format + cmpw #12,%d0 | address error vector? + jeq Lisaerr | yes, go to it +#if defined(M68K_MMU_MOTOROLA) +#if defined(M68K_MMU_HP) + tstl _C_LABEL(mmutype) | HP MMU? + jeq Lbehpmmu | yes, different MMU fault handler +#endif + movl %d1,%a0 | fault address + movl %sp@,%d0 | function code from ssw + btst #8,%d0 | data fault? + jne Lbe10a + movql #1,%d0 | user program access FC + | (we dont separate data/program) + btst #5,%sp@(FR_HW+8) | supervisor mode? + jeq Lbe10a | if no, done + movql #5,%d0 | else supervisor program access +Lbe10a: + ptestr %d0,%a0@,#7 | do a table search + pmove %psr,%sp@ | save result + movb %sp@,%d1 + btst #2,%d1 | invalid (incl. limit viol. and berr)? + jeq Lmightnotbemerr | no -> wp check + btst #7,%d1 | is it MMU table berr? + jne Lisberr1 | yes, needs not be fast. +#endif /* M68K_MMU_MOTOROLA */ +Lismerr: + movl #T_MMUFLT,%sp@- | show that we are an MMU fault + jra _ASM_LABEL(faultstkadj) | and deal with it +#if defined(M68K_MMU_MOTOROLA) +Lmightnotbemerr: + btst #3,%d1 | write protect bit set? + jeq Lisberr1 | no, must be bus error + movl %sp@,%d0 | ssw into low word of d0 + andw #0xc0,%d0 | write protect is set on page: + cmpw #0x40,%d0 | was it read cycle? + jne Lismerr | no, was not WPE, must be MMU fault + jra Lisberr1 | real bus err needs not be fast. +#endif /* M68K_MMU_MOTOROLA */ +#if defined(M68K_MMU_HP) +Lbehpmmu: + MMUADDR(%a0) + movl %a0@(MMUSTAT),%d0 | read MMU status + btst #3,%d0 | MMU fault? + jeq Lisberr1 | no, just a non-MMU bus error + andl #~MMU_FAULT,%a0@(MMUSTAT)| yes, clear fault bits + movw %d0,%sp@ | pass MMU stat in upper half of code + jra Lismerr | and handle it +#endif +Lisaerr: + movl #T_ADDRERR,%sp@- | mark address error + jra _ASM_LABEL(faultstkadj) | and deal with it +Lisberr1: + clrw %sp@ | re-clear pad word + tstl _C_LABEL(nofault) | catch bus error? + jeq Lisberr | no, handle as usual +#ifdef mac68k + movl %a2,_C_LABEL(mac68k_a2_fromfault) | save %a2 + movl %sp@(FR_HW+8+16),_C_LABEL(m68k_fault_addr) | save fault addr +#endif + movl _C_LABEL(nofault),%sp@- | yes, + jbsr _C_LABEL(longjmp) | longjmp(nofault) + /* NOTREACHED */ +#endif /* M68020 || M68030 */ + +Lisberr: | also used by M68040/60 + movl #T_BUSERR,%sp@- | mark bus error + jra _ASM_LABEL(faultstkadj) | and deal with it +