Module Name: src Committed By: tsutsui Date: Fri Mar 14 20:24:24 UTC 2014
Modified Files: src/sys/arch/x68k/x68k: locore.s vectors.s Log Message: Sync bus error and address error handlers with other m68k implementation. Tested on X68030. Needs tests on 040 and 060turbo (though it should work as other m68k ports). The x68k port implemented 68060 support including these vector handlers as early as amiga back in 1996, but even after amiga's locore.s was improved several times (updating vectors at runtime to switch handlers per CPU types etc.), x68k's one has not been updated. After that, atari and mac68k pulled amiga's implementation, hp300 pulled mac68k, and then most other m68k ports pulled hp300 ones. Probably that's the reason why only x68k had different implementations (i.e. no reason that avoids using common handler implementation), and now it's time to prepare common arch/m68k/m68k/busaddrerr.s. To generate a diff of this commit: cvs rdiff -u -r1.114 -r1.115 src/sys/arch/x68k/x68k/locore.s cvs rdiff -u -r1.17 -r1.18 src/sys/arch/x68k/x68k/vectors.s Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x68k/x68k/locore.s diff -u src/sys/arch/x68k/x68k/locore.s:1.114 src/sys/arch/x68k/x68k/locore.s:1.115 --- src/sys/arch/x68k/x68k/locore.s:1.114 Sat Mar 8 17:44:37 2014 +++ src/sys/arch/x68k/x68k/locore.s Fri Mar 14 20:24:24 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.s,v 1.114 2014/03/08 17:44:37 tsutsui Exp $ */ +/* $NetBSD: locore.s,v 1.115 2014/03/14 20:24:24 tsutsui Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -185,6 +185,35 @@ Lis68020: movl #CPU_68020,%a0@ | and a 68020 CPU Lstart1: + /* + * Now that we know what CPU we have, initialize the address error + * and bus error handlers in the vector table: + * + * vectab+8 bus error + * vectab+12 address error + */ + RELOC(cputype,%a0) + RELOC(vectab,%a2) +#if defined(M68060) + cmpl #CPU_68060,%a0@ | 68060? + jne 1f + movl #_C_LABEL(buserr60),%a2@(8) + movl #_C_LABEL(addrerr4060),%a2@(12) + jra Lstart2 +1: +#endif +#if defined(M68040) + cmpl #CPU_68040,%a0@ | 68040? + jne 1f + movl #_C_LABEL(buserr40),%a2@(8) + movl #_C_LABEL(addrerr4060),%a2@(12) + jra Lstart2 +1: +#endif + movl #_C_LABEL(busaddrerr2030),%a2@(8) + movl #_C_LABEL(busaddrerr2030),%a2@(12) + +Lstart2: /* initialize source/destination control registers for movs */ moveq #FC_USERD,%d0 | user space movc %d0,%sfc | as source @@ -205,10 +234,10 @@ Lstart1: #if NKSYMS || defined(DDB) || defined(MODULAR) RELOC(esym,%a0) | end of static kernel test/data/syms movl %a0@,%d5 - jne Lstart2 + jne Lstart3 #endif movl #_C_LABEL(end),%d5 | end of static kernel text/data -Lstart2: +Lstart3: RELOC(setmemrange,%a0) | call setmemrange() jbsr %a0@ | to probe all memory regions addl #PAGE_SIZE-1,%d5 @@ -363,39 +392,36 @@ Lenab3: */ #include <m68k/m68k/trap_subr.s> -ENTRY_NOPROFILE(buserr) -ENTRY_NOPROFILE(buserr60) | XXX - tstl _C_LABEL(nofault) | device probe? - jeq Lberr | no, handle as usual - movl _C_LABEL(nofault),%sp@- | yes, - jbsr _C_LABEL(longjmp) | longjmp(nofault) -Lberr: #if defined(M68040) || defined(M68060) - cmpl #MMU_68040,_C_LABEL(mmutype) | 68040/060? - jne _C_LABEL(addrerr) | no, skip +ENTRY_NOPROFILE(addrerr4060) clrl %sp@- | stack adjust count moveml #0xFFFF,%sp@- | save user registers movl %usp,%a0 | save the user SP movl %a0,%sp@(FR_SP) | in the savearea - lea %sp@(FR_HW),%a1 | grab base of HW berr frame + 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 + #if defined(M68060) - cmpl #CPU_68060,_C_LABEL(cputype) | 68060? - jne Lbenot060 - movel %a1@(12),%d0 | grap FSLW +ENTRY_NOPROFILE(buserr60) | XXX + 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 | no, skip - movc %cacr,%d1 - orl #IC60_CABC,%d1 | clear all branch cache entries - movc %d1,%cacr + jeq Lnobpe + movc %cacr,%d2 + orl #IC60_CABC,%d2 | clear all branch cache entries + movc %d2,%cacr movl %d0,%d1 andl #0x7ffd,%d1 | check other faults jeq _ASM_LABEL(faultstkadjnotrap2) Lnobpe: -| XXX this is not needed. -| movl %d0,%sp@ | code is FSLW now. - | we need to adjust for misaligned addresses - movl %a1@(8),%d1 | grab VA + 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 @@ -404,68 +430,74 @@ Lnobpe: | XXX instr. case not done yet andl #PG_FRAME,%d1 | and truncate Lberr3: - movl %d1,%sp@- | push fault VA - movl %d0,%sp@- | and FSLW + movl %d1,%sp@- + movl %d0,%sp@- | code is FSLW now. andw #0x1f80,%d0 - jeq Lisberr - jra Lismerr -Lbenot060: + 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 + movl _C_LABEL(nofault),%sp@- | yes, + jbsr _C_LABEL(longjmp) | longjmp(nofault) + /* NOTREACHED */ #endif + +#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 %a1@(12),%d0 | grab SSW - movl %a1@(20),%d1 | and fault VA - btst #11,%d0 | check for mis-aligned access - jeq Lberr2 | no, skip - addl #3,%d1 | yes, get into next page + 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 -Lberr2: - movl %d1,%sp@- | push fault VA - movl %d0,%sp@- | and padded SSW - btst #10,%d0 | ATC bit set? - jeq Lisberr | no, must be a real bus error - movc %dfc,%d1 | yes, get MMU fault - movc %d0,%dfc | store faulting function code - movl %sp@(4),%a0 | get faulting address - .word 0xf568 | ptestr a0@ - movc %d1,%dfc - .long 0x4e7a0805 | movc mmusr,d0 - movw %d0,%sp@ | save (ONLY LOW 16 BITS!) - jra Lismerr +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 + movl _C_LABEL(nofault),%sp@- | yes, + jbsr _C_LABEL(longjmp) | longjmp(nofault) + /* NOTREACHED */ #endif -ENTRY_NOPROFILE(addrerr) + +#if defined(M68020) || defined(M68030) +ENTRY_NOPROFILE(busaddrerr2030) clrl %sp@- | stack adjust count - moveml #0xFFFF,%sp@- | save user registers + moveml %d0-%d7/%a0-%a7,%sp@- | save user registers movl %usp,%a0 | save the user SP movl %a0,%sp@(FR_SP) | in the savearea - lea %sp@(FR_HW),%a1 | grab base of HW berr frame -#if defined(M68040) || defined(M68060) - cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? - jne Lbenot040 | no, skip - movl %a1@(8),%sp@- | yes, push fault address - clrl %sp@- | no SSW for address fault - jra Lisaerr | go deal with it -Lbenot040: -#endif moveq #0,%d0 - movw %a1@(10),%d0 | grab SSW for fault processing + 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,%a1@(10) | for hardware too + 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,%a1@(10) | for hardware too + movw %d0,%sp@(FR_HW+10) | for hardware too LbeX1: btst #8,%d0 | data fault? jeq Lbe0 | no, check for hard cases - movl %a1@(16),%d1 | fault address is as given in frame + movl %sp@(FR_HW+16),%d1 | fault address is as given in frame jra Lbe10 | thats it Lbe0: - btst #4,%a1@(6) | long (type B) stack frame? + btst #4,%sp@(FR_HW+6) | long (type B) stack frame? jne Lbe4 | yes, go handle - movl %a1@(2),%d1 | no, can use save PC + 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 @@ -476,14 +508,14 @@ Lbe3: addql #2,%d1 | yes, adjust address jra Lbe10 | done Lbe4: - movl %a1@(36),%d1 | long format, use stage B address + 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 %a1@(6),%d0 | get frame format/vector offset + 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 @@ -493,34 +525,41 @@ Lbe10: jne Lbe10a movql #1,%d0 | user program access FC | (we dont separate data/program) - btst #5,%a1@ | supervisor mode? + 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)? + btst #2,%d1 | invalid (incl. limit viol. and berr)? jeq Lmightnotbemerr | no -> wp check btst #7,%d1 | is it MMU table berr? - jeq Lismerr | no, must be fast - jra Lisberr1 | real bus err needs not be fast + jne Lisberr1 | yes, needs not be fast. +Lismerr: + movl #T_MMUFLT,%sp@- | show that we are an MMU fault + jra _ASM_LABEL(faultstkadj) | and deal with it 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? - jeq Lisberr1 | yes, was not WPE, must be bus err -Lismerr: - movl #T_MMUFLT,%sp@- | show that we are an MMU fault - jra _ASM_LABEL(faultstkadj) | and deal with it + jne Lismerr | no, was not WPE, must be MMU fault + jra Lisberr1 | real bus err needs not be fast. Lisaerr: movl #T_ADDRERR,%sp@- | mark address error jra _ASM_LABEL(faultstkadj) | and deal with it Lisberr1: clrw %sp@ | re-clear pad word -Lisberr: + tstl _C_LABEL(nofault) | catch bus error? + jeq Lisberr | no, handle as usual + 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 Index: src/sys/arch/x68k/x68k/vectors.s diff -u src/sys/arch/x68k/x68k/vectors.s:1.17 src/sys/arch/x68k/x68k/vectors.s:1.18 --- src/sys/arch/x68k/x68k/vectors.s:1.17 Sun Apr 29 07:17:12 2012 +++ src/sys/arch/x68k/x68k/vectors.s Fri Mar 14 20:24:24 2014 @@ -1,4 +1,4 @@ -| $NetBSD: vectors.s,v 1.17 2012/04/29 07:17:12 tsutsui Exp $ +| $NetBSD: vectors.s,v 1.18 2014/03/14 20:24:24 tsutsui Exp $ | Copyright (c) 1988 University of Utah | Copyright (c) 1990, 1993 @@ -35,8 +35,8 @@ GLOBAL(vectab) .long 0x4ef80000 /* 0: jmp 0x0000:w (unused reset SSP) */ VECTOR_UNUSED /* 1: NOT USED (reset PC) */ - VECTOR(buserr) /* 2: bus error */ - VECTOR(addrerr) /* 3: address error */ + VECTOR_UNUSED /* 2: bus error (set per CPU types) */ + VECTOR_UNUSED /* 3: address error (set per CPU types) */ VECTOR(illinst) /* 4: illegal instruction */ VECTOR(zerodiv) /* 5: zero divide */ VECTOR(chkinst) /* 6: CHK instruction */