From 180e04ee41f988e707078620bae65d598c91314c Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Fri, 25 Jan 2013 14:48:57 +0100 Subject: [PATCH] omap: fix breakpoint instruction trap handling (from sources) --- sys/src/9/omap/arm.h | 6 ++++++ sys/src/9/omap/fns.h | 1 + sys/src/9/omap/l.s | 8 ++++++-- sys/src/9/omap/trap.c | 18 +++++++++++++++++- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/sys/src/9/omap/arm.h b/sys/src/9/omap/arm.h index 12443d849..0376f36fb 100644 --- a/sys/src/9/omap/arm.h +++ b/sys/src/9/omap/arm.h @@ -33,6 +33,12 @@ #define CpDFP 11 /* double FP */ #define CpSC 15 /* System Control */ + /* + * CpFSR op1==0, Crm==0 opcode 2 values. + */ +#define CpDFSR 0 /* data fault status */ +#define CpIFSR 1 /* instruction fault status */ + /* * Primary (CRn) CpSC registers. */ diff --git a/sys/src/9/omap/fns.h b/sys/src/9/omap/fns.h index 342af1604..a1e486dda 100644 --- a/sys/src/9/omap/fns.h +++ b/sys/src/9/omap/fns.h @@ -50,6 +50,7 @@ extern u32int fsrget(void); 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); diff --git a/sys/src/9/omap/l.s b/sys/src/9/omap/l.s index 9950cd2ad..0e9a5b67c 100644 --- a/sys/src/9/omap/l.s +++ b/sys/src/9/omap/l.s @@ -474,10 +474,14 @@ TEXT dacput(SB), 1, $-4 /* domain access control */ 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 */ MRC CpSC, 0, R0, C(CpFAR), C(0x0) RET diff --git a/sys/src/9/omap/trap.c b/sys/src/9/omap/trap.c index 2a97b71c5..7fab7c778 100644 --- a/sys/src/9/omap/trap.c +++ b/sys/src/9/omap/trap.c @@ -493,7 +493,23 @@ trap(Ureg *ureg) 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;