Pull in latest Amiga bus/address error handling.

This commit is contained in:
leo 1997-07-05 20:50:41 +00:00
parent 15de91e26d
commit a323500b0f
2 changed files with 197 additions and 149 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: atari_init.c,v 1.31 1997/06/10 18:37:50 veego Exp $ */
/* $NetBSD: atari_init.c,v 1.32 1997/07/05 20:50:41 leo Exp $ */
/*
* Copyright (c) 1995 Leo Weppelman
@ -143,6 +143,7 @@ u_long st_pool_virt, st_pool_phys;
* Some of the code in here is `stolen' from Amiga MACH, and was
* written by Bryan Ford and Niklas Hallqvist.
*
* Very crude 68040 support by Michael L. Hitch.
*/
void
@ -208,17 +209,17 @@ char *esym_addr; /* Address of kernel '_esym' symbol */
PAGE_MASK = NBPG-1;
PAGE_SHIFT = PG_SHIFT;
/*
* Initialize cpu specific stuff
*/
initcpu();
/*
* Determine the type of machine we are running on. This needs
* to be done early!
*/
set_machtype();
/*
* Initialize cpu specific stuff
*/
initcpu();
/*
* We run the kernel from ST memory at the moment.
* The kernel segment table is put just behind the loaded image.
@ -906,48 +907,70 @@ int m68060_pcr_init = 0x21; /* make this patchable */
static void
initcpu()
{
/* XXX should init '40 vecs here, too */
typedef void trapfun __P((void));
switch (cputype) {
#if defined(M68060)
extern caddr_t vectab[256];
case CPU_68060:
{
extern trapfun *vectab[256];
extern trapfun buserr60, addrerr4060, fpfault;
#if defined(M060SP)
extern u_int8_t FP_CALL_TOP[], I_CALL_TOP[];
#else
extern trapfun illinst;
#endif
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)
extern u_int8_t FP_CALL_TOP[], I_CALL_TOP[];
/* integer support */
vectab[61] = (trapfun *)&I_CALL_TOP[128 + 0x00];
/* floating point support */
/*
* XXX maybe we really should run-time check for the
* stack frame format here:
*/
vectab[11] = (trapfun *)&FP_CALL_TOP[128 + 0x30];
vectab[55] = (trapfun *)&FP_CALL_TOP[128 + 0x38];
vectab[60] = (trapfun *)&FP_CALL_TOP[128 + 0x40];
vectab[54] = (trapfun *)&FP_CALL_TOP[128 + 0x00];
vectab[52] = (trapfun *)&FP_CALL_TOP[128 + 0x08];
vectab[53] = (trapfun *)&FP_CALL_TOP[128 + 0x10];
vectab[51] = (trapfun *)&FP_CALL_TOP[128 + 0x18];
vectab[50] = (trapfun *)&FP_CALL_TOP[128 + 0x20];
vectab[49] = (trapfun *)&FP_CALL_TOP[128 + 0x28];
#else
extern u_int8_t illinst;
vectab[61] = illinst;
#endif
extern u_int8_t fpfault;
vectab[48] = fpfault;
}
break;
#endif /* defined(M68060) */
#if defined(M68040)
case CPU_68040:
{
extern trapfun *vectab[256];
extern trapfun buserr40, addrerr4060;
if (cputype == CPU_68060) {
asm volatile ("movl %0,d0; .word 0x4e7b,0x0808" : :
"d"(m68060_pcr_init):"d0" );
#if defined(M060SP)
/* integer support */
vectab[61] = &I_CALL_TOP[128 + 0x00];
/* floating point support */
/*
* XXX maybe we really should run-time check for the
* stack frame format here:
*/
vectab[11] = &FP_CALL_TOP[128 + 0x30];
vectab[55] = &FP_CALL_TOP[128 + 0x38];
vectab[60] = &FP_CALL_TOP[128 + 0x40];
vectab[54] = &FP_CALL_TOP[128 + 0x00];
vectab[52] = &FP_CALL_TOP[128 + 0x08];
vectab[53] = &FP_CALL_TOP[128 + 0x10];
vectab[51] = &FP_CALL_TOP[128 + 0x18];
vectab[50] = &FP_CALL_TOP[128 + 0x20];
vectab[49] = &FP_CALL_TOP[128 + 0x28];
#else
vectab[61] = &illinst;
#endif
vectab[48] = &fpfault;
/* bus/addrerr vectors */
vectab[2] = buserr40;
vectab[3] = addrerr4060;
}
break;
#endif /* defined(M68040) */
}
DCIS();
#endif
}
#ifdef DEBUG

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.43 1997/07/04 20:52:50 is Exp $ */
/* $NetBSD: locore.s,v 1.44 1997/07/05 20:51:14 leo Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -86,32 +86,28 @@ _doadump:
#include <m68k/m68k/trap_subr.s>
.globl _trap, _nofault, _longjmp
.globl _buserr60 | for 060SP
#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
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 /* defined(M68040) || defined(M68060) */
#if defined(M68060)
.globl _buserr60
_buserr60:
_buserr:
tstl _nofault | device probe?
jeq _addrerr | no, handle as usual
movl _nofault,sp@- | yes,
jbsr _longjmp | longjmp(nofault)
_addrerr:
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
cmpl #CPU_68060,_cputype | is it 68060?
jne Lbe040
movel a1@(12),d0 | FSLW
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
@ -120,116 +116,145 @@ _addrerr:
movl d0,d1
addql #1,L60bpe
andl #0x7ffd,d1
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:
#endif /* M68060 */
movl a1@(20),d1 | get fault address
movl #T_MMUFLT,sp@- | show that we are an MMU fault
jra _ASM_LABEL(faultstkadj) | and deal with it
#endif /* defined(M68060) */
#if defined(M68040)
.globl _buserr40
_buserr40:
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
btst #11,d0 | check for mis-aligned
jeq Lbe1stpg | no skip
addl #3,d1 | get into next page
andl #PG_FRAME,d1 | and truncate
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
btst #10,d0 | test ATC
jeq Lisberr | it's a bus error
jra Lismerr
Lbe030:
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
movl #T_MMUFLT,sp@- | show that we are an MMU fault
jra _ASM_LABEL(faultstkadj) | and deal with it
#endif /* defined(M68040) */
/*
* This is where the default vectors end-up!
*/
_buserr:
_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
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 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,a1@(10) | for hardware too
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 a1@(16),d1 | fault address is as given in frame
jra Lbe10 | thats it
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,a1@(6) | long (type B) stack frame?
jne Lbe4 | yes, go handle
movl a1@(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
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
btst #15,d0 | FC set?
jeq Lbe10 | no, done
addql #2,d1 | yes, adjust address
jra Lbe10 | done
Lbe4:
movl a1@(36),d1 | long format, use stage B address
btst #15,d0 | FC set?
jeq Lbe10 | no, all done
subql #2,d1 | yes, adjust 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
andw #0x0FFF,d0 | clear out frame format
cmpw #12,d0 | address error vector?
jeq Lisaerr | yes, go to it
movl d1,a0 | fault address
movl sp@,d0 | function code from ssw
btst #8,d0 | data fault?
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
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 don't separate data/program)
btst #5,a1@ | supervisor mode?
jeq Lbe10a | if no, done
movql #5,d0 | else supervisor program access
movql #1,d0 | user program access FC
| (we dont seperate 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
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 a MMU table berr?
jeq Lismerr | no, must be fast
jra Lisberr1 | real bus err needs not be fast
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.
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 a read cycle?
jeq Lisberr1 | yes, was not WPE, must be bus error
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
movl #T_MMUFLT,sp@- | show that we are an MMU fault
jra _ASM_LABEL(faultstkadj) | and deal with it
Lisaerr:
movl #T_ADDRERR,sp@- | mark address error
jra _ASM_LABEL(faultstkadj) | and deal with it
movl #T_ADDRERR,sp@- | mark address error
jra _ASM_LABEL(faultstkadj) | and deal with it
Lisberr1:
clrw sp@ | re-clear pad word
Lisberr:
movl #T_BUSERR,sp@- | mark bus error
jra _ASM_LABEL(faultstkadj) | and deal with it
clrw sp@ | re-clear pad word
#endif /* !(defined(M68020) || defined(M68030)) */
Lisberr: | also used by M68040/60
tstl _nofault | device probe?
jeq LberrIsProbe | no, handle as usual
movl _nofault,sp@- | yes,
jbsr _longjmp | longjmp(nofault)
/* NOTREACHED */
LberrIsProbe:
movl #T_BUSERR,sp@- | mark bus error
jra _ASM_LABEL(faultstkadj) | and deal with it
/*
* FP exceptions.