diff options
author | aiju <devnull@localhost> | 2017-06-12 19:03:07 +0000 |
---|---|---|
committer | aiju <devnull@localhost> | 2017-06-12 19:03:07 +0000 |
commit | 773be02aa18095e857c6659416d84951ceb60d41 (patch) | |
tree | 26daede4230e14d46d42efbcd6eab8e68adc7687 /sys/src/9/pc/trap.c | |
parent | 1cfa405d0a272cbd7df22d4b9767eb57e21cc21f (diff) |
kernel: add support for hardware watchpoints
Diffstat (limited to 'sys/src/9/pc/trap.c')
-rw-r--r-- | sys/src/9/pc/trap.c | 31 |
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]; |