incorpaorated floppy code from Brad Pepers, needs work doesn't work on my

machine.  more clenaup in trap.c
This commit is contained in:
chopps 1994-04-05 18:08:56 +00:00
parent 10466baa67
commit 602ef3f30f
4 changed files with 397 additions and 313 deletions

View File

@ -38,7 +38,7 @@
* from: Utah $Hdr: autoconf.c 1.31 91/01/21$
*
* @(#)autoconf.c 7.5 (Berkeley) 5/7/91
* $Id: autoconf.c,v 1.12 1994/03/28 06:15:55 chopps Exp $
* $Id: autoconf.c,v 1.13 1994/04/05 18:08:56 chopps Exp $
*/
/*
@ -586,6 +586,9 @@ same_hw_device(hw, ad)
case D_PPORT:
found = dr_type(ad->amiga_driver, "par");
break;
case D_FLOP:
found = dr_type(ad->amiga_driver, "fp");
break;
default:
break;
}
@ -701,6 +704,15 @@ find_devs()
hw->hw_serno = 0;
hw++;
hw->hw_pa = 0;
hw->hw_size = 0;
hw->hw_kva = CUSTOMbase;
hw->hw_manufacturer = MANUF_BUILTIN;
hw->hw_product = PROD_BUILTIN_FLOP;
hw->hw_type = B_BUILTIN | D_FLOP;
hw->hw_serno = 0;
hw++;
hw->hw_pa = 0;
hw->hw_size = 0;
hw->hw_kva = (caddr_t) CUSTOMbase;

View File

@ -27,7 +27,7 @@
* on the Hardware Reference Manual. It is NOT based on the Amiga's
* hardware/custom.h.
*
* $Id: custom.h,v 1.5 1994/02/11 06:59:34 chopps Exp $
* $Id: custom.h,v 1.6 1994/04/05 18:09:00 chopps Exp $
*/
#ifndef _amiga_custom_
@ -286,6 +286,23 @@ extern volatile struct Custom *CUSTOMbase;
#define INTF_DSKBLK (1<<INTB_DSKBLK)
#define INTF_TBE (1<<INTB_TBE)
/* Bit definitions for adkcon, adkconr */
#define ADKB_SETCLR 15
#define ADKB_PRECOMP1 14
#define ADKB_PRECOMP0 13
#define ADKB_MFMPREC 12
#define ADKB_UARTBRK 11
#define ADKB_WORDSYNC 10
#define ADKB_MSBSYNC 9
#define ADKB_FAST 8
#define ADKF_SETCLR (1<<ADKB_SETCLR)
#define ADKF_PRECOMP1 (1<<ADKB_PRECOMP1)
#define ADKF_PRECOMP0 (1<<ADKB_PRECOMP0)
#define ADKF_MFMPREC (1<<ADKB_MFMPREC)
#define ADKF_UARTBRK (1<<ADKB_UARTBRK)
#define ADKF_WORDSYNC (1<<ADKB_WORDSYNC)
#define ADKF_MSBSYNC (1<<ADKB_MSBSYNC)
#define ADKF_FAST (1<<ADKB_FAST)
#endif /* _machine_custom_ */

View File

@ -38,7 +38,7 @@
* from: Utah $Hdr: machdep.c 1.63 91/04/24$
*
* @(#)machdep.c 7.16 (Berkeley) 6/3/91
* $Id: machdep.c,v 1.14 1994/03/30 17:24:08 chopps Exp $
* $Id: machdep.c,v 1.15 1994/04/05 18:09:02 chopps Exp $
*/
#include <sys/param.h>
@ -1392,15 +1392,17 @@ intrhand(sr)
{
ser_outintr ();
}
if (ireq & INTF_DSKBLK)
{
fpintr(0);
custom.intreq = INTF_DSKBLK;
}
if (ireq & INTF_SOFTINT)
{
/* first call installed callbacks, then clear the softint-bit */
call_sicallbacks ();
custom.intreq = INTF_SOFTINT;
}
custom.intreq = INTF_DSKBLK;
break;
case 2:

View File

@ -38,7 +38,7 @@
* from: Utah $Hdr: trap.c 1.32 91/04/06$
*
* @(#)trap.c 7.15 (Berkeley) 8/2/91
* $Id: trap.c,v 1.12 1994/04/04 11:10:55 chopps Exp $
* $Id: trap.c,v 1.13 1994/04/05 18:09:04 chopps Exp $
*/
#include <sys/param.h>
@ -119,7 +119,7 @@ static void
userret(p, pc, oticks)
struct proc *p;
int pc;
struct timeval oticks;
struct timeval *oticks;
{
int sig, s;
@ -149,8 +149,8 @@ userret(p, pc, oticks)
int ticks;
struct timeval *tv = &p->p_stime;
ticks = ((tv->tv_sec - oticks.tv_sec) * 1000 +
(tv->tv_usec - oticks.tv_usec) / 1000) / (tick / 1000);
ticks = ((tv->tv_sec - oticks->tv_sec) * 1000 +
(tv->tv_usec - oticks->tv_usec) / 1000) / (tick / 1000);
if (ticks) {
#ifdef PROFTIMER
extern int profscale;
@ -163,6 +163,239 @@ userret(p, pc, oticks)
curpri = p->p_pri;
}
void
panictrap(type, code, v, fp)
int type;
u_int code, v;
struct frame *fp;
{
static int panicing = 0;
if (panicing++ == 0) {
printf("trap type %d, code = %x, v = %x\n", type, code, v);
regdump(fp->f_regs, 128);
}
type &= ~T_USER;
DCIS(); /* XXX? push cache */
if ((u_int)type < trap_types)
panic(trap_type[type]);
panic("trap");
/*NOTREACHED*/
}
/*
* return to fault handler
*/
void
trapcpfault(p, fp)
struct proc *p;
struct frame *fp;
{
/*
* We have arranged to catch this fault in one of the
* copy to/from user space routines, set PC to return to
* indicated location and set flag informing buserror code
* that it may need to clean up stack frame.
*/
fp->f_stackadj = exframesize[fp->f_format];
fp->f_format = fp->f_vector = 0;
fp->f_pc = (int) p->p_addr->u_pcb.pcb_onfault;
}
void
trapmmufault(type, code, v, fp, p, sticks)
int type;
u_int code, v;
struct frame *fp;
struct proc *p;
struct timeval *sticks;
{
extern vm_map_t kernel_map;
struct vmspace *vm;
vm_prot_t ftype;
vm_offset_t va;
vm_map_t map;
u_int nss;
int rv;
vm = p->p_vmspace;
/*
* It is only a kernel address space fault iff:
* 1. (type & T_USER) == 0 and
* 2. pcb_onfault not set or
* 3. pcb_onfault set but supervisor space data fault
* The last can occur during an exec() copyin where the
* argument space is lazy-allocated.
*/
#ifdef DEBUG
/*
* Print out some data about the fault
*/
if (mmudebug && cpu040) {
printf ("68040 access error: pc %x, code %x,"
" ea %x, fa %x\n", fp->f_pc, code, fp->f_fmt7.f_ea, v);
if (curpcb)
printf (" curpcb %x ->pcb_ustp %x / %x\n",
curpcb, curpcb->pcb_ustp,
curpcb->pcb_ustp << PG_SHIFT);
}
#endif
if (type == T_MMUFLT &&
(p->p_addr->u_pcb.pcb_onfault == 0 ||
(cpu040 && (code & SSW_TMMASK) == FC_SUPERD) ||
(!cpu040 && (code & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD))))
map = kernel_map;
else
map = &vm->vm_map;
if ((cpu040 && (code & SSW_RW040) == 0) ||
(!cpu040 && (code & (SSW_DF|SSW_RW)) ==
SSW_DF)) /* what about RMW? */
ftype = VM_PROT_READ | VM_PROT_WRITE;
else
ftype = VM_PROT_READ;
va = trunc_page((vm_offset_t)v);
#ifdef DEBUG
if (map == kernel_map && va == 0) {
printf("trap: bad kernel access at %x\n", v);
panictrap(type, code, v, fp);
}
#endif
#ifndef no_386bsd_code
/*
* XXX: rude hack to make stack limits "work"
*/
nss = 0;
if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) {
nss = clrnd(btoc(USRSTACK - (unsigned)va));
if (nss > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur)) {
rv = KERN_FAILURE;
goto nogo;
}
}
#endif
#ifdef DEBUG
if (mmudebug)
printf("vm_fault(%x,%x,%d,0)\n", map, va, ftype);
#endif
rv = vm_fault(map, va, ftype, FALSE);
#ifdef DEBUG
if (mmudebug)
printf("vmfault %s %x returned %d\n",
map == kernel_map ? "kernel" : "user", va, rv);
#endif
if (cpu040) {
if(rv != KERN_SUCCESS) {
goto nogo;
}
/*
* The 68040 doesn't re-run instructions that cause
* write page faults (unless due to a move16 isntruction).
* So once the page is repaired, we have to write the
* value of WB2D out to memory ourselves. Because
* the writeback could possibly span two pages in
* memory, so we need to check both "ends" of the
* address to see if they are in the same page or not.
* If not, then we need to make sure the second page
* is valid, and bring it into memory if it's not.
*
* This whole process needs to be repeated for WB3 as well.
* <sigh>
*/
/* Check WB1 */
if (fp->f_fmt7.f_wb1s & WBS_VALID) {
printf ("trap: wb1 was valid, not handled yet\n");
panictrap(type, code, v, fp);
}
/*
* Check WB2
* skip if it's for a move16 instruction
*/
if(fp->f_fmt7.f_wb2s & WBS_VALID &&
((fp->f_fmt7.f_wb2s & WBS_TTMASK)==WBS_TT_MOVE16) == 0) {
if (_write_back(2, fp->f_fmt7.f_wb2s,
fp->f_fmt7.f_wb2d, fp->f_fmt7.f_wb2a, map)
!= KERN_SUCCESS)
goto nogo;
if ((fp->f_fmt7.f_wb2s & WBS_TMMASK)
!= (code & SSW_TMMASK))
panictrap(type, code, v, fp);
}
/* Check WB3 */
if(fp->f_fmt7.f_wb3s & WBS_VALID) {
vm_map_t wb3_map;
if ((fp->f_fmt7.f_wb3s & WBS_TMMASK) == WBS_TM_SDATA)
wb3_map = kernel_map;
else
wb3_map = &vm->vm_map;
if (_write_back(3, fp->f_fmt7.f_wb3s,
fp->f_fmt7.f_wb3d, fp->f_fmt7.f_wb3a, wb3_map)
!= KERN_SUCCESS)
goto nogo;
}
}
#ifdef no_386bsd_code
/*
* If this was a stack access we keep track of the maximum
* accessed stack size. Also, if vm_fault gets a protection
* failure it is due to accessing the stack region outside
* the current limit and we need to reflect that as an access
* error.
*/
if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) {
if (rv == KERN_SUCCESS) {
nss = clrnd(btoc(USRSTACK-(unsigned)va));
if (nss > vm->vm_ssize)
vm->vm_ssize = nss;
} else if (rv == KERN_PROTECTION_FAILURE)
rv = KERN_INVALID_ADDRESS;
}
if (rv == KERN_SUCCESS) {
if (type == T_MMUFLT)
return;
userret(p, fp->f_pc, sticks);
reutrn;
}
#else /* use hacky 386bsd_code */
if (rv == KERN_SUCCESS) {
/*
* XXX: continuation of rude stack hack
*/
if (nss > vm->vm_ssize)
vm->vm_ssize = nss;
if (type == T_MMUFLT)
return;
userret(p, fp->f_pc, sticks);
return;
}
nogo:
#endif
if (type == T_MMUFLT) {
if (p->p_addr->u_pcb.pcb_onfault) {
trapcpfault(p, fp);
return;
}
printf("vm_fault(%x, %x, %x, 0) -> %x\n",
map, va, ftype, rv);
printf(" type %x, code [mmu,,ssw]: %x\n",
type, code);
panictrap(type, code, v, fp);
}
trapsignal(p, (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV, v);
if ((type & T_USER) == 0)
return;
userret(p, fp->f_pc, sticks);
}
/*
* Trap is called from locore to handle most types of processor traps,
* including events such as simulated software interrupts/AST's.
@ -171,20 +404,19 @@ userret(p, pc, oticks)
/*ARGSUSED*/
trap(type, code, v, frame)
int type;
unsigned code;
register unsigned v;
u_int code, v;
struct frame frame;
{
register int i;
unsigned ucode = 0;
register struct proc *p = curproc;
struct timeval syst;
unsigned ncode;
static int panicing = 0;
int s;
struct proc *p;
u_int ncode, ucode;
int i, s;
p = curproc;
ucode = 0;
cnt.v_trap++;
syst = p->p_stime;
if (USERMODE(frame.f_sr)) {
type |= T_USER;
p->p_regs = frame.f_regs;
@ -198,51 +430,84 @@ trap(type, code, v, frame)
#endif
switch (type) {
default:
dopanic:
if (! panicing++)
{
printf("trap type %d, code = %x, v = %x\n", type, code, v);
regdump(frame.f_regs, 128);
}
type &= ~T_USER;
DCIS(); /* push cache */
if ((unsigned)type < trap_types)
panic(trap_type[type]);
panic("trap");
case T_BUSERR: /* kernel bus error */
panictrap(type, code, v, &frame);
/*
* Kernel Bus error
*/
case T_BUSERR:
if (!p->p_addr->u_pcb.pcb_onfault)
goto dopanic;
/*
* If we have arranged to catch this fault in any of the
* copy to/from user space routines, set PC to return to
* indicated location and set flag informing buserror code
* that it may need to clean up stack frame.
*/
copyfault:
frame.f_stackadj = exframesize[frame.f_format];
frame.f_format = frame.f_vector = 0;
frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault;
panictrap(type, code, v, &frame);
trapcpfault(p, &frame);
return;
case T_BUSERR|T_USER: /* bus error */
case T_ADDRERR|T_USER: /* address error */
/*
* User Bus/Addr error.
*/
case T_BUSERR|T_USER:
case T_ADDRERR|T_USER:
i = SIGBUS;
break;
#ifdef FPCOPROC
case T_COPERR: /* kernel coprocessor violation */
#endif
case T_FMTERR: /* kernel format error */
/*
* The user has most likely trashed the RTE or FP state info
* in the stack frame of a signal handler.
* User illegal/privleged inst fault
*/
case T_ILLINST|T_USER:
case T_PRIVINST|T_USER:
ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */
i = SIGILL;
break;
/*
* divde by zero, CHK/TRAPV inst
*/
case T_ZERODIV|T_USER:
case T_CHKINST|T_USER:
case T_TRAPVINST|T_USER:
ucode = frame.f_format;
i = SIGFPE;
break;
#ifdef FPCOPROC
/*
* User coprocessor violation
*/
case T_COPERR|T_USER:
ucode = 0;
i = SIGFPE; /* XXX What is a proper response here? */
break;
/*
* 6888x exceptions
*/
case T_FPERR|T_USER:
/*
* We pass along the 68881 status register which locore
* stashed in code for us. Note that there is a
* possibility that the bit pattern of this register
* will conflict with one of the FPE_* codes defined
* in signal.h. Fortunately for us, the only such
* codes we use are all in the range 1-7 and the low
* 3 bits of the status register are defined as 0 so
* there is no clash.
*/
ucode = code;
i = SIGFPE;
break;
/*
* Kernel coprocessor violation
*/
case T_COPERR:
/*FALLTHROUGH*/
#endif
/*
* Kernel format error
*/
case T_FMTERR:
/*
* The user has most likely trashed the RTE or FP state info
* in the stack frame of a signal handler.
*/
type |= T_USER;
#ifdef DEBUG
printf("pid %d: kernel %s exception\n", p->p_pid,
type==T_COPERR ? "coprocessor" : "format");
type==T_COPERR ? "coprocessor" : "format");
#endif
p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL;
i = sigmask(SIGILL);
p->p_sigignore &= ~i;
@ -251,84 +516,48 @@ copyfault:
i = SIGILL;
ucode = frame.f_format; /* XXX was ILL_RESAD_FAULT */
break;
#ifdef FPCOPROC
case T_COPERR|T_USER: /* user coprocessor violation */
/* What is a proper response here? */
ucode = 0;
i = SIGFPE;
break;
case T_FPERR|T_USER: /* 68881 exceptions */
/*
* We pass along the 68881 status register which locore stashed
* in code for us. Note that there is a possibility that the
* bit pattern of this register will conflict with one of the
* FPE_* codes defined in signal.h. Fortunately for us, the
* only such codes we use are all in the range 1-7 and the low
* 3 bits of the status register are defined as 0 so there is
* no clash.
*/
ucode = code;
i = SIGFPE;
break;
#endif
case T_ILLINST|T_USER: /* illegal instruction fault */
case T_PRIVINST|T_USER: /* privileged instruction fault */
ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */
i = SIGILL;
break;
case T_ZERODIV|T_USER: /* Divide by zero */
ucode = frame.f_format; /* XXX was FPE_INTDIV_TRAP */
i = SIGFPE;
break;
case T_CHKINST|T_USER: /* CHK instruction trap */
ucode = frame.f_format; /* XXX was FPE_SUBRNG_TRAP */
i = SIGFPE;
break;
case T_TRAPVINST|T_USER: /* TRAPV instruction trap */
ucode = frame.f_format; /* XXX was FPE_INTOVF_TRAP */
i = SIGFPE;
break;
/*
* XXX: Trace traps are a nightmare.
* Trace traps.
*
* HP-UX uses trap #1 for breakpoints,
* HPBSD uses trap #2,
* SUN 3.x uses trap #15,
* KGDB uses trap #15 (for kernel breakpoints; handled elsewhere).
* M68k NetBSD uses trap #2,
* SUN 3.x uses trap #15,
* KGDB uses trap #15 (for kernel breakpoints; handled elsewhere).
*
* HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
* Amiga traps get mapped by locore.s into T_TRACE.
* SUN 3.x traps get passed through as T_TRAP15 and are not really
* supported yet.
*/
case T_TRACE: /* kernel trace trap */
case T_TRAP15: /* SUN trace trap */
case T_TRACE:
case T_TRAP15:
frame.f_sr &= ~PSL_T;
i = SIGTRAP;
break;
case T_TRACE|T_USER: /* user trace trap */
case T_TRAP15|T_USER: /* SUN user trace trap */
case T_TRACE|T_USER:
case T_TRAP15|T_USER:
#ifdef COMPAT_SUNOS
/* SunOS seems to use Trap #2 for some obscure fpu operations.
So far, just ignore it, but DONT trap on it.. */
if (p->p_emul == EMUL_SUNOS)
goto out;
/*
* XXX This comment/code is not consistent XXX
* SunOS seems to use Trap #2 for some obscure
* fpu operations. So far, just ignore it, but
* DONT trap on it..
*/
if (p->p_emul == EMUL_SUNOS) {
userret(p, frame.f_pc, &syst);
return;
}
#endif
frame.f_sr &= ~PSL_T;
i = SIGTRAP;
break;
case T_ASTFLT: /* system async trap, cannot happen */
goto dopanic;
case T_ASTFLT|T_USER: /* user async trap */
/*
* Kernel AST (should not happen)
*/
case T_ASTFLT:
panictrap(type, code, v, &frame);
/*
* User AST
*/
case T_ASTFLT|T_USER:
astpending = 0;
/*
* We check for software interrupts first. This is because
@ -339,9 +568,11 @@ copyfault:
* IPL while processing the SIR.
*/
spl1();
/* fall into... */
case T_SSIR: /* software interrupt */
/*FALLTHROUGH*/
/*
* Software interrupt
*/
case T_SSIR:
case T_SSIR|T_USER:
if (ssir & SIR_NET) {
siroff(SIR_NET);
@ -367,204 +598,26 @@ copyfault:
p->p_flag &= ~SOWEUPC;
}
#endif
goto out;
case T_MMUFLT: /* kernel mode page fault */
/* fall into ... */
userret(p, frame.f_pc, &syst);
return;
/*
* Kernel/User page fault
*/
case T_MMUFLT:
case T_MMUFLT|T_USER: /* page fault */
{
register vm_offset_t va;
register struct vmspace *vm = p->p_vmspace;
register vm_map_t map;
int rv;
vm_prot_t ftype;
extern vm_map_t kernel_map;
unsigned nss;
/*
* It is only a kernel address space fault iff:
* 1. (type & T_USER) == 0 and
* 2. pcb_onfault not set or
* 3. pcb_onfault set but supervisor space data fault
* The last can occur during an exec() copyin where the
* argument space is lazy-allocated.
*/
#ifdef DEBUG
/*
* Print out some data about the fault
*/
if (mmudebug && cpu040) {
printf ("68040 access error: pc %x, code %x, ea %x, fa %x\n",
frame.f_pc, code, frame.f_fmt7.f_ea, v);
if (curpcb)
printf (" curpcb %x ->pcb_ustp %x / %x\n", curpcb,
curpcb->pcb_ustp, curpcb->pcb_ustp << PG_SHIFT);
}
#endif
if (type == T_MMUFLT &&
(!p->p_addr->u_pcb.pcb_onfault ||
(cpu040 && (code & SSW_TMMASK) == FC_SUPERD) ||
(!cpu040 && (code & (SSW_DF|FC_SUPERD)) ==
(SSW_DF|FC_SUPERD))))
map = kernel_map;
else
map = &vm->vm_map;
if ((cpu040 && (code & SSW_RW040) == 0) ||
(!cpu040 && (code & (SSW_DF|SSW_RW)) ==
SSW_DF)) /* what about RMW? */
ftype = VM_PROT_READ | VM_PROT_WRITE;
else
ftype = VM_PROT_READ;
va = trunc_page((vm_offset_t)v);
#ifdef DEBUG
if (map == kernel_map && va == 0) {
printf("trap: bad kernel access at %x\n", v);
goto dopanic;
}
#endif
#ifndef no_386bsd_code
/*
* XXX: rude hack to make stack limits "work"
*/
nss = 0;
if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) {
nss = clrnd(btoc(USRSTACK - (unsigned)va));
if (nss > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur)) {
/*pg("trap rlimit %d, maxsaddr %x va %x ", nss, vm->vm_maxsaddr, va);*/
rv = KERN_FAILURE;
goto nogo;
}
}
#endif
#ifdef DEBUG
if (mmudebug)
printf("vm_fault(%x,%x,%d,0)\n", map, va, ftype);
#endif
rv = vm_fault(map, va, ftype, FALSE);
#ifdef DEBUG
if (mmudebug)
printf("vmfault %s %x returned %d\n", map == kernel_map ? "kernel" : "user", va, rv);
#endif
if (cpu040) {
if(rv != KERN_SUCCESS) {
goto nogo;
}
/* Okay folks, here's the deal. The 68040 doesn't re-run instructions
that cause write page faults (unless due to a move16 isntruction).
So once the page is repaired, we have to write the value of WB2D
out to memory ourselves. Because the writeback could possibly span
two pages in memory, so we need to check both "ends" of the address
to see if they are in the same page or not. If not, then we need
to make sure the second page is valid, and bring it into memory if
it's not.
This whole process needs to be repeated for WB3 as well. <sigh> */
/* WB1 Valid? */
if (frame.f_fmt7.f_wb1s & WBS_VALID)
{
/* Panic for now */
printf ("trap: wb1 was valid, but I'm not ready to do it\n");
goto dopanic;
}
/* WB2 Valid? */
if(frame.f_fmt7.f_wb2s & WBS_VALID &&
/* We can skip WB2 if it's for a move16 instruction */
!((frame.f_fmt7.f_wb2s & WBS_TTMASK) == WBS_TT_MOVE16))
{
if (_write_back (2, frame.f_fmt7.f_wb2s, frame.f_fmt7.f_wb2d,
frame.f_fmt7.f_wb2a, map) != KERN_SUCCESS)
goto nogo;
if ((frame.f_fmt7.f_wb2s & WBS_TMMASK) != (code & SSW_TMMASK))
goto dopanic;
}
/* WB3 Valid? */
if(frame.f_fmt7.f_wb3s & WBS_VALID)
{
vm_map_t wb3_map;
if ((frame.f_fmt7.f_wb3s & WBS_TMMASK) == WBS_TM_SDATA)
wb3_map = kernel_map;
else
wb3_map = &vm->vm_map;
if (_write_back (3, frame.f_fmt7.f_wb3s, frame.f_fmt7.f_wb3d,
frame.f_fmt7.f_wb3a, wb3_map) != KERN_SUCCESS)
goto nogo;
#ifdef DEBUG
if (mmudebug & 2)
goto dopanic;
#endif
}
}
#ifdef no_386bsd_code
/*
* If this was a stack access we keep track of the maximum
* accessed stack size. Also, if vm_fault gets a protection
* failure it is due to accessing the stack region outside
* the current limit and we need to reflect that as an access
* error.
*/
if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) {
if (rv == KERN_SUCCESS) {
nss = clrnd(btoc(USRSTACK-(unsigned)va));
if (nss > vm->vm_ssize)
vm->vm_ssize = nss;
} else if (rv == KERN_PROTECTION_FAILURE)
rv = KERN_INVALID_ADDRESS;
}
if (rv == KERN_SUCCESS) {
if (type == T_MMUFLT)
return;
goto out;
}
#else /* use hacky 386bsd_code */
if (rv == KERN_SUCCESS) {
/*
* XXX: continuation of rude stack hack
*/
if (nss > vm->vm_ssize)
vm->vm_ssize = nss;
if (type == T_MMUFLT)
return;
goto out;
}
nogo:
#endif
if (type == T_MMUFLT) {
if (p->p_addr->u_pcb.pcb_onfault)
goto copyfault;
printf("vm_fault(%x, %x, %x, 0) -> %x\n",
map, va, ftype, rv);
printf(" type %x, code [mmu,,ssw]: %x\n",
type, code);
goto dopanic;
}
ucode = v;
i = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV;
break;
}
trapmmufault(type, code, v, &frame, p, &syst);
return;
}
if (i != SIGTRAP)
printf("trapsignal(%d, %d, %d, %x, %x)\n", p->p_pid, i, ucode, v, frame.f_regs[PC]);
#ifdef DEBUG
if (mmudebug & 2) /* Panic if bit 1 of mmudebug set */
goto dopanic;
if (i != SIGTRAP)
printf("trapsignal(%d, %d, %d, %x, %x)\n", p->p_pid, i,
ucode, v, frame.f_regs[PC]);
#endif
trapsignal(p, i, ucode);
if ((type & T_USER) == 0)
return;
out:
userret(p, frame.f_pc, syst);
userret(p, frame.f_pc, &syst);
}
/*
@ -696,7 +749,7 @@ syscall(code, frame)
p->p_md.md_flags &= ~MDP_STACKADJ;
}
#endif
userret(p, frame.f_pc, syst);
userret(p, frame.f_pc, &syst);
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSRET))
ktrsysret(p->p_tracep, code, error, rval[0]);