#include "ureg.h"
#include "sysreg.h"
+int (*buserror)(Ureg*);
+
/* SPSR bits user can modify */
#define USPSRMASK (0xFULL<<28)
}
if(intr == 3){
case 0x2F: // SError interrupt
+ if(buserror != nil && (*buserror)(ureg))
+ break;
dumpregs(ureg);
panic("SError interrupt");
break;
insyscall = up->insyscall;
up->insyscall = 1;
- if(!userureg(ureg) && waserror()){
- if(up->nerrlab == 0){
- pprint("suicide: sys: %s\n", up->errstr);
- pexit(up->errstr, 1);
+ if(!userureg(ureg)){
+ extern void _peekinst(void);
+
+ if(ureg->pc == (uintptr)_peekinst){
+ ureg->pc = ureg->link;
+ goto out;
+ }
+
+ if(waserror()){
+ if(up->nerrlab == 0){
+ pprint("suicide: sys: %s\n", up->errstr);
+ pexit(up->errstr, 1);
+ }
+ up->insyscall = insyscall;
+ nexterror();
}
- up->insyscall = insyscall;
- nexterror();
}
addr = getfar();
case 8: case 9: case 10: case 11: // Access flag fault.
case 12: case 13: case 14: case 15: // Permission fault.
case 48: // tlb conflict fault.
- if(fault(addr, read) == 0)
+ if(fault(addr, ureg->pc, read) == 0)
break;
/* wet floor */
if(!userureg(ureg))
poperror();
+out:
up->insyscall = insyscall;
}
cureg = (Ureg*) (p->sched.sp + 16);
memmove(cureg, ureg, sizeof(Ureg));
cureg->r0 = 0;
-
- p->psstate = 0;
- p->insyscall = 0;
}
uintptr