shithub: riscv

Download patch

ref: 9e45c8bc9b652f8675d31f8014d33c5b430c765b
parent: 04efb3a4a3995015ba739372336e5e4286b96413
author: cinap_lenrek <[email protected]>
date: Thu Jan 1 06:32:00 EST 2015

zynq: differentiate various pagefault types in faultarm()

--- a/sys/src/9/zynq/trap.c
+++ b/sys/src/9/zynq/trap.c
@@ -52,11 +52,27 @@
 	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);
@@ -70,16 +86,31 @@
 	}
 	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;