diff options
author | jake <jake@FreeBSD.org> | 2001-10-20 16:04:39 +0000 |
---|---|---|
committer | jake <jake@FreeBSD.org> | 2001-10-20 16:04:39 +0000 |
commit | cb7ca29ccfb777175e9f35287c61d53617f45a36 (patch) | |
tree | 440034bd5bbeef65a3eef45cdbf78e72ba4043b5 | |
parent | 21fd58664dc89376f0ffdc3776d8febdcd12b36c (diff) | |
download | FreeBSD-src-cb7ca29ccfb777175e9f35287c61d53617f45a36.zip FreeBSD-src-cb7ca29ccfb777175e9f35287c61d53617f45a36.tar.gz |
Add support for physical address hardware watchpoints.
-rw-r--r-- | sys/sparc64/include/trap.h | 5 | ||||
-rw-r--r-- | sys/sparc64/sparc64/trap.c | 29 |
2 files changed, 29 insertions, 5 deletions
diff --git a/sys/sparc64/include/trap.h b/sys/sparc64/include/trap.h index 26651bc..6a06430 100644 --- a/sys/sparc64/include/trap.h +++ b/sys/sparc64/include/trap.h @@ -64,8 +64,9 @@ #define T_FILL_RET 0x1e #define T_BREAKPOINT 0x1f #define T_SYSCALL 0x20 -#define T_RESTOREWP 0x21 -#define T_SOFT 0x22 +#define T_RSTRWP_PHYS 0x21 +#define T_RSTRWP_VIRT 0x22 +#define T_SOFT 0x23 #define T_KERNEL 0x40 #ifndef LOCORE diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c index e9577a9..8498b87 100644 --- a/sys/sparc64/sparc64/trap.c +++ b/sys/sparc64/sparc64/trap.c @@ -121,6 +121,8 @@ const char *trap_msg[] = { "fill", "breakpoint", "syscall", + "restore physical watchpoint", + "restore virtual watchpoint", "trap instruction", }; @@ -248,6 +250,20 @@ trap(struct trapframe *tf) if (error == 0) goto out; break; + case T_WATCH_PHYS | T_KERNEL: + TR3("trap: watch phys pa=%#lx tpc=%#lx, tnpc=%#lx", + watch_phys_get(&mask), tf->tf_tpc, tf->tf_tnpc); + PCPU_SET(wp_pstate, (tf->tf_tstate & TSTATE_PSTATE_MASK) >> + TSTATE_PSTATE_SHIFT); + tf->tf_tstate &= ~TSTATE_IE; + wrpr(pstate, rdpr(pstate), PSTATE_IE); + PCPU_SET(wp_insn, *((u_int *)tf->tf_tnpc)); + *((u_int *)tf->tf_tnpc) = 0x91d03002; /* ta %xcc, 2 */ + flush(tf->tf_tnpc); + PCPU_SET(wp_va, watch_phys_get(&mask)); + PCPU_SET(wp_mask, mask); + watch_phys_clear(); + goto out; case T_WATCH_VIRT | T_KERNEL: /* * At the moment, just print the information from the trap, @@ -260,8 +276,8 @@ trap(struct trapframe *tf) * disable interrupts temporarily. * This is obviously fragile and evilish. */ - printf("Virtual watchpoint triggered, tpc=0x%lx, tnpc=0x%lx\n", - tf->tf_tpc, tf->tf_tnpc); + TR3("trap: watch virt pa=%#lx tpc=%#lx, tnpc=%#lx", + watch_virt_get(&mask), tf->tf_tpc, tf->tf_tnpc); PCPU_SET(wp_pstate, (tf->tf_tstate & TSTATE_PSTATE_MASK) >> TSTATE_PSTATE_SHIFT); tf->tf_tstate &= ~TSTATE_IE; @@ -273,7 +289,14 @@ trap(struct trapframe *tf) PCPU_SET(wp_mask, mask); watch_virt_clear(); goto out; - case T_RESTOREWP | T_KERNEL: + case T_RSTRWP_PHYS | T_KERNEL: + tf->tf_tstate = (tf->tf_tstate & ~TSTATE_PSTATE_MASK) | + PCPU_GET(wp_pstate) << TSTATE_PSTATE_SHIFT; + watch_phys_set_mask(PCPU_GET(wp_va), PCPU_GET(wp_mask)); + *(u_int *)tf->tf_tpc = PCPU_GET(wp_insn); + flush(tf->tf_tpc); + goto out; + case T_RSTRWP_VIRT | T_KERNEL: /* * Undo the tweaks tone for T_WATCH, reset the watch point and * contunue execution. |