Handle breakpoint instructions in armv7+, which cause a PsrMabt exception instead of PsrMund. Reference: /n/sources/patch/applied/armv7-bkpt Date: Tue Jan 8 12:03:00 CET 2013 Signed-off-by: miller@hamnavoe.com --- /sys/src/9/omap/trap.c Tue Jan 8 12:01:20 2013 +++ /sys/src/9/omap/trap.c Tue Jan 8 12:01:17 2013 @@ -493,7 +493,23 @@ break; case PsrMabt: /* prefetch fault */ ldrexvalid = 0; - faultarm(ureg, ureg->pc, user, 1); + x = ifsrget(); + fsr = (x>>7) & 0x8 | x & 0x7; + switch(fsr){ + case 0x02: /* instruction debug event (BKPT) */ + if(user){ + snprint(buf, sizeof buf, "sys: breakpoint"); + postnote(up, 1, buf, NDebug); + }else{ + iprint("kernel bkpt: pc %#lux inst %#ux\n", + ureg->pc, *(u32int*)ureg->pc); + panic("kernel bkpt"); + } + break; + default: + faultarm(ureg, ureg->pc, user, 1); + break; + } break; case PsrMabt+1: /* data fault */ ldrexvalid = 0; --- /sys/src/9/omap/fns.h Tue Jan 8 12:01:23 2013 +++ /sys/src/9/omap/fns.h Tue Jan 8 12:01:21 2013 @@ -50,6 +50,7 @@ extern u32int getscr(void); extern u32int getpsr(void); extern ulong getwayssets(void); +extern u32int ifsrget(void); extern void intrsoff(void); extern int isaconfig(char*, int, ISAConf*); extern int isdmadone(int); --- /sys/src/9/omap/arm.h Tue Jan 8 12:01:28 2013 +++ /sys/src/9/omap/arm.h Tue Jan 8 12:01:25 2013 @@ -58,6 +58,12 @@ #define CpTTBctl 2 /* cortex */ /* + * CpFSR op1==0, Crm==0 opcode 2 values. + */ +#define CpDFSR 0 /* data fault status */ +#define CpIFSR 1 /* instruction fault status */ + +/* * CpID Secondary (CRm) registers. */ #define CpIDidct 0 --- /sys/src/9/omap/l.s Tue Jan 8 12:01:32 2013 +++ /sys/src/9/omap/l.s Tue Jan 8 12:01:30 2013 @@ -474,8 +474,12 @@ ISB RET -TEXT fsrget(SB), 1, $-4 /* fault status */ - MRC CpSC, 0, R0, C(CpFSR), C(0) +TEXT fsrget(SB), 1, $-4 /* data fault status */ + MRC CpSC, 0, R0, C(CpFSR), C(0), CpDFSR + RET + +TEXT ifsrget(SB), 1, $-4 /* instruction fault status */ + MRC CpSC, 0, R0, C(CpFSR), C(0), CpIFSR RET TEXT farget(SB), 1, $-4 /* fault address */ --- /sys/src/9/teg2/trap.c Tue Jan 8 12:01:38 2013 +++ /sys/src/9/teg2/trap.c Tue Jan 8 12:01:35 2013 @@ -815,7 +815,7 @@ trap(Ureg *ureg) { int clockintr, user, rem; - uintptr va, ifar; + uintptr va, ifar, ifsr; splhi(); /* paranoia */ if(up != nil) @@ -860,11 +860,26 @@ break; case PsrMabt: /* prefetch (instruction) fault */ va = ureg->pc; - ifar = cprdsc(0, CpFAR, 0, CpIFAR); - if (va != ifar) - iprint("trap: cpu%d: i-fault va %#p != ifar %#p\n", - m->machno, va, ifar); - faultarm(ureg, va, user, 1); + ifsr = cprdsc(0, CpFSR, 0, CpIFSR); + ifsr = (ifsr>>7) & 0x8 | ifsr & 0x7; + switch(ifsr){ + case 0x02: /* instruction debug event (BKPT) */ + if(user) + postnote(up, 1, "sys: breakpoint", NDebug); + else{ + iprint("kernel bkpt: pc %#lux inst %#ux\n", + va, *(u32int*)va); + panic("kernel bkpt"); + } + break; + default: + ifar = cprdsc(0, CpFAR, 0, CpIFAR); + if (va != ifar) + iprint("trap: cpu%d: i-fault va %#p != ifar %#p\n", + m->machno, va, ifar); + faultarm(ureg, va, user, 1); + break; + } break; case PsrMabt+1: /* data fault */ datafault(ureg, user);