summaryrefslogtreecommitdiff
path: root/sys/src/9/pc/trap.c
diff options
context:
space:
mode:
authoraiju <devnull@localhost>2017-06-12 19:03:07 +0000
committeraiju <devnull@localhost>2017-06-12 19:03:07 +0000
commit773be02aa18095e857c6659416d84951ceb60d41 (patch)
tree26daede4230e14d46d42efbcd6eab8e68adc7687 /sys/src/9/pc/trap.c
parent1cfa405d0a272cbd7df22d4b9767eb57e21cc21f (diff)
kernel: add support for hardware watchpoints
Diffstat (limited to 'sys/src/9/pc/trap.c')
-rw-r--r--sys/src/9/pc/trap.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/sys/src/9/pc/trap.c b/sys/src/9/pc/trap.c
index 3fa728975..b7877563d 100644
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -13,6 +13,7 @@ static int trapinited;
void noted(Ureg*, ulong);
+static void debugexc(Ureg*, void*);
static void debugbpt(Ureg*, void*);
static void fault386(Ureg*, void*);
static void doublefault(Ureg*, void*);
@@ -222,6 +223,7 @@ trapinit(void)
* Special traps.
* Syscall() is called directly without going through trap().
*/
+ trapenable(VectorDE, debugexc, 0, "debugexc");
trapenable(VectorBPT, debugbpt, 0, "debugpt");
trapenable(VectorPF, fault386, 0, "fault386");
trapenable(Vector2F, doublefault, 0, "doublefault");
@@ -627,6 +629,35 @@ dumpstack(void)
}
static void
+debugexc(Ureg *, void *)
+{
+ u32int dr6, m;
+ char buf[ERRMAX];
+ char *p, *e;
+ int i;
+
+ dr6 = getdr6();
+ if(up == nil)
+ panic("kernel debug exception dr6=%#.8ux", dr6);
+ putdr6(up->dr[6]);
+ m = up->dr[7];
+ m = (m >> 4 | m >> 3) & 8 | (m >> 3 | m >> 2) & 4 | (m >> 2 | m >> 1) & 2 | (m >> 1 | m) & 1;
+ m &= dr6;
+ if(m == 0){
+ sprint(buf, "sys: debug exception dr6=%#.8ux", dr6);
+ postnote(up, 1, buf, NDebug);
+ }else{
+ p = buf;
+ e = buf + sizeof(buf);
+ p = seprint(p, e, "sys: watchpoint ");
+ for(i = 0; i < 4; i++)
+ if((m & 1<<i) != 0)
+ p = seprint(p, e, "%d%s", i, (m >> i + 1 != 0) ? "," : "");
+ postnote(up, 1, buf, NDebug);
+ }
+}
+
+static void
debugbpt(Ureg* ureg, void*)
{
char buf[ERRMAX];