Reorganize buserr/addrerr stuff, to allow omitting unused code in single-cpu

kernels, at the same time getting rid of up to 3 conditional branches and a
bit over one cacheline fetch (for the 68060; the saving is a bit smaller for
040 and yet smaller for the 020/30).
While we're here, also get rid of an redundant lea (using SP-relative
addressing) and of two redundant pushes.
While we're here, also fix a panic which would tear us down on 68060 machines
if a branch prediction error ever occured.
This commit is contained in:
is 1997-06-04 22:12:43 +00:00
parent f2b935d7c6
commit 6d6e724440
3 changed files with 100 additions and 44 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.81 1997/05/22 22:48:47 veego Exp $ */
/* $NetBSD: locore.s,v 1.82 1997/06/04 22:12:45 is Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -102,30 +102,34 @@ _doadump:
#include <m68k/m68k/trap_subr.s>
.globl _trap, _nofault, _longjmp
_buserr:
tstl _nofault | device probe?
jeq _addrerr | no, handle as usual
movl _nofault,sp@- | yes,
jbsr _longjmp | longjmp(nofault)
_addrerr:
#if defined(M68040) || defined(M68060)
.globl _addrerr4060
_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
cmpl #MMU_68040,_mmutype
jne Lbe030
movl a1@(8),sp@- | V = exception address
clrl sp@- | dummy code
moveq #0,d0
movw a1@(6),d0 | get vector offset
andw #0x0fff,d0
cmpw #12,d0 | is it address error
jeq Lisaerr
#ifdef M68060
btst #7,_machineid+3 | is it 68060?
jeq Lbe040
movel a1@(12),d0 | FSLW
movl #T_ADDRERR,sp@- | mark address error
jra _ASM_LABEL(faultstkadj) | and deal with it
#endif
#if defined(M68060)
.globl _buserr60
_buserr60:
tstl _nofault | device probe?
jeq Lnonofault60 | no, handle as usual
movl _nofault,sp@- | yes,
jbsr _longjmp | longjmp(nofault)
/* NOTREACHED */
Lnonofault60:
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
movel sp@(FR_HW+12),d0 | FSLW
btst #2,d0 | branch prediction error?
jeq Lnobpe
movc cacr,d2
@ -134,59 +138,85 @@ _addrerr:
movl d0,d1
andl #0x7ffd,d1
addql #1,L60bpe
jeq _ASM_LABEL(faultstkadjnotrap)
jeq _ASM_LABEL(faultstkadjnotrap2)
Lnobpe:
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
| operand case: 3,
| instruction case: 4+12+12
| XXX instr. case not done yet
andl #PG_FRAME,d1 | and truncate
Lberr3:
movl d1,sp@(4)
movl d1,sp@-
movl d0,sp@- | code is FSLW now.
andw #0x1f80,d0
jeq Lisberr
jra Lismerr
Lbe040:
movl #T_MMUFLT,sp@- | show that we are an MMU fault
jra _ASM_LABEL(faultstkadj) | and deal with it
#endif
movl a1@(20),d1 | get fault address
#if defined(M68040)
.globl _buserr40
_buserr40:
tstl _nofault | device probe?
jeq Lnonofault40 | no, handle as usual
movl _nofault,sp@- | yes,
jbsr _longjmp | longjmp(nofault)
Lnonofault40:
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
movl sp@(FR_HW+20),d1 | get fault address
moveq #0,d0
movw a1@(12),d0 | get SSW
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@(4) | pass fault address.
movl d0,sp@ | pass SSW as code
movl d1,sp@- | pass fault address.
movl d0,sp@- | pass SSW as code
btst #10,d0 | test ATC
jeq Lisberr | it is a bus error
jra Lismerr
Lbe030:
movl #T_MMUFLT,sp@- | show that we are an MMU fault
jra _ASM_LABEL(faultstkadj) | and deal with it
#endif
_buserr:
tstl _nofault | device probe?
jeq _addrerr | no, handle as usual
movl _nofault,sp@- | yes,
jbsr _longjmp | longjmp(nofault)
_addrerr:
#if !(defined(M68020) || defined(M68030))
jra _badtrap
#else
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
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
@ -197,14 +227,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
@ -214,7 +244,7 @@ Lbe10:
jne Lbe10a
movql #1,d0 | user program access FC
| (we dont seperate 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:
@ -241,7 +271,8 @@ Lisaerr:
jra _ASM_LABEL(faultstkadj) | and deal with it
Lisberr1:
clrw sp@ | re-clear pad word
Lisberr:
#endif
Lisberr: | also used by M68040/60
movl #T_BUSERR,sp@- | mark bus error
jra _ASM_LABEL(faultstkadj) | and deal with it

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.89 1997/04/09 19:32:09 thorpej Exp $ */
/* $NetBSD: machdep.c,v 1.90 1997/06/04 22:12:46 is Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -1245,11 +1245,16 @@ void
initcpu()
{
/* XXX should init '40 vecs here, too */
#if defined(M68060) || defined(DRACO)
#if defined(M68060) || defined(M68040) || defined(DRACO)
extern caddr_t vectab[256];
#endif
#if defined(M68060) || defined(M68040)
extern u_int8_t addrerr4060;
#endif
#ifdef M68060
extern u_int8_t buserr60;
#if defined(M060SP)
/*extern u_int8_t I_CALL_TOP[];*/
extern u_int8_t intemu60, fpiemu60, fpdemu60, fpeaemu60;
@ -1260,6 +1265,10 @@ initcpu()
extern u_int8_t fpfault;
#endif
#ifdef M68040
extern u_int8_t buserr40;
#endif
#ifdef DRACO
extern u_int8_t DraCoIntr, DraCoLev1intr, DraCoLev2intr;
u_char dracorev;
@ -1269,6 +1278,10 @@ initcpu()
if (machineid & AMIGA_68060) {
asm volatile ("movl %0,d0; .word 0x4e7b,0x0808" : :
"d"(m68060_pcr_init):"d0" );
/* bus/addrerr vectors */
vectab[2] = &buserr60;
vectab[3] = &addrerr4060;
#if defined(M060SP)
/* integer support */
@ -1301,6 +1314,16 @@ initcpu()
/*
* Vector initialization for special motherboards
*/
#ifdef M68040
#ifdef M68060
else
#endif
if (machineid & AMIGA_68040) {
/* addrerr vector */
vectab[2] = &buserr40;
vectab[3] = &addrerr4060;
}
#endif
#ifdef DRACO
dracorev = is_draco();

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap_subr.s,v 1.1 1997/04/25 01:33:18 thorpej Exp $ */
/* $NetBSD: trap_subr.s,v 1.2 1997/06/04 22:12:43 is Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -75,6 +75,8 @@ ASENTRY(faultstkadj)
/* for 68060 Branch Prediction Error handler */
_ASM_LABEL(faultstkadjnotrap):
lea sp@(12),sp | pop value args
/* for new 68060 Branch Prediction Error handler */
_ASM_LABEL(faultstkadjnotrap2):
movl sp@(FR_SP),a0 | restore user SP
movl a0,usp | from save area
movw sp@(FR_ADJ),d0 | need to adjust stack?