]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/zynq/trap.c
zynq: remove unused statistics fields from Mach structure
[plan9front.git] / sys / src / 9 / zynq / trap.c
index 337877c9c8e656e15f92a822d025f082d76161a8..510860b6380269f15e68e9f8299400fbb6ddd28f 100644 (file)
@@ -20,7 +20,7 @@ _dumpstack(Ureg *ureg)
                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);
@@ -52,12 +52,28 @@ _dumpstack(Ureg *ureg)
        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){
@@ -70,16 +86,31 @@ faultarm(Ureg *ureg, ulong fsr, uintptr addr)
        }
        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;
@@ -88,18 +119,24 @@ faultarm(Ureg *ureg, ulong fsr, uintptr addr)
 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);
@@ -138,6 +175,7 @@ trap(Ureg *ureg)
                        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:
@@ -153,7 +191,7 @@ trap(Ureg *ureg)
                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){
@@ -385,6 +423,7 @@ noted(Ureg *ureg, ulong arg0)
                sp = oureg - 4 * BY2WD - ERRMAX;
                splhi();
                ureg->sp = sp;
+               ureg->r0 = (uintptr) oureg;
                ((ulong *) sp)[1] = oureg;
                ((ulong *) sp)[0] = 0;
                break;
@@ -408,9 +447,17 @@ dumpstack(void)
 }
 
 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
@@ -476,7 +523,7 @@ procsave(Proc *p)
        cycles(&t);
        p->kentry -= t;
        p->pcycles += t;
-       
+
        l1switch(&m->l1, 0);
 }