iprint("dumpstack disabled\n");
return;
}
- iprint("dumpstack\n");
+ iprint("cpu%d: dumpstack\n", m->machno);
x = 0;
x += iprint("ktrace /arm/9zynq %.8lux %.8lux %.8lux <<EOF\n", ureg->pc, ureg->sp, ureg->r14);
iprint("EOF\n");
}
+static char*
+faulterr[0x20] = {
+[0x01] "alignement fault",
+[0x02] "debug event",
+[0x04] "fault on instruction cache maintenance",
+[0x08] "synchronous external abort",
+[0x0C] "synchronous external abort on translation table walk L1",
+[0x0E] "synchronous external abort on translation table walk L2",
+[0x10] "tlb conflict abort",
+[0x16] "asynchronous external abort",
+[0x19] "synchronous parity error on memory access",
+[0x1C] "synchronous parity error on translation table walk L1",
+[0x1E] "synchronous parity error on translation table walk L2",
+};
+
static void
faultarm(Ureg *ureg, ulong fsr, uintptr addr)
{
- int user, insyscall, read, n;
+ int user, insyscall, read;
static char buf[ERRMAX];
-
+ char *err;
+
read = (fsr & (1<<11)) == 0;
user = userureg(ureg);
if(!user){
}
if(up == nil)
panic("user fault: up=nil pc=%#.8lux addr=%#.8lux fsr=%#.8lux", ureg->pc, addr, fsr);
+
insyscall = up->insyscall;
up->insyscall = 1;
- n = fault(addr, read);
- if(n < 0){
+ switch(fsr & 0x1F){
+ case 0x05: /* translation fault L1 */
+ case 0x07: /* translation fault L2 */
+ case 0x03: /* access flag fault L1 */
+ case 0x06: /* access flag fault L2 */
+ case 0x09: /* domain fault L1 */
+ case 0x0B: /* domain fault L2 */
+ case 0x0D: /* permission fault L1 */
+ case 0x0F: /* permission fault L2 */
+ if(fault(addr, read) == 0)
+ break;
+ /* wet floor */
+ default:
+ err = faulterr[fsr & 0x1F];
+ if(err == nil)
+ err = "fault";
if(!user){
dumpregs(ureg);
_dumpstack(ureg);
- panic("kernel fault: pc=%#.8lux addr=%#.8lux fsr=%#.8lux", ureg->pc, addr, fsr);
+ panic("kernel %s: pc=%#.8lux addr=%#.8lux fsr=%#.8lux", err, ureg->pc, addr, fsr);
}
- sprint(buf, "sys: trap: fault %s addr=%#.8lux", read ? "read" : "write", addr);
+ sprint(buf, "sys: trap: %s %s addr=%#.8lux", err, read ? "read" : "write", addr);
postnote(up, 1, buf, NDebug);
}
up->insyscall = insyscall;
static void
mathtrap(Ureg *, ulong)
{
+ int s;
+
if((up->fpstate & FPillegal) != 0){
postnote(up, 1, "sys: floating point in note handler", NDebug);
return;
}
switch(up->fpstate){
case FPinit:
+ s = splhi();
fpinit();
up->fpstate = FPactive;
+ splx(s);
break;
case FPinactive:
+ s = splhi();
fprestore(&up->fpsave);
up->fpstate = FPactive;
+ splx(s);
break;
case FPactive:
postnote(up, 1, "sys: floating point error", NDebug);
postnote(up, 1, "sys: trap: invalid opcode", NDebug);
break;
}
+ dumpregs(ureg);
panic("invalid opcode at pc=%#.8lux lr=%#.8lux", ureg->pc, ureg->r14);
break;
case PsrMiabt:
intr(ureg);
break;
default:
- print("unknown trap type %ulx\n", ureg->type);
+ iprint("cpu%d: unknown trap type %ulx\n", m->machno, ureg->type);
}
splhi();
if(user){
sp = oureg - 4 * BY2WD - ERRMAX;
splhi();
ureg->sp = sp;
+ ureg->r0 = (uintptr) oureg;
((ulong *) sp)[1] = oureg;
((ulong *) sp)[0] = 0;
break;
}
void
-dumpregs(Ureg *)
+dumpregs(Ureg *ureg)
{
- print("dumpregs\n");
+ iprint("trap: %lux psr %8.8lux type %2.2lux pc %8.8lux link %8.8lux\n",
+ ureg->type, ureg->psr, ureg->type, ureg->pc, ureg->link);
+ iprint("R14 %8.8lux R13 %8.8lux R12 %8.8lux R11 %8.8lux R10 %8.8lux\n",
+ ureg->r14, ureg->r13, ureg->r12, ureg->r11, ureg->r10);
+ iprint("R9 %8.8lux R8 %8.8lux R7 %8.8lux R6 %8.8lux R5 %8.8lux\n",
+ ureg->r9, ureg->r8, ureg->r7, ureg->r6, ureg->r5);
+ iprint("R4 %8.8lux R3 %8.8lux R2 %8.8lux R1 %8.8lux R0 %8.8lux\n",
+ ureg->r4, ureg->r3, ureg->r2, ureg->r1, ureg->r0);
+ iprint("pc %#lux link %#lux\n", ureg->pc, ureg->link);
}
void
cycles(&t);
p->kentry -= t;
p->pcycles += t;
-
+
l1switch(&m->l1, 0);
}