summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2001-10-20 16:04:39 +0000
committerjake <jake@FreeBSD.org>2001-10-20 16:04:39 +0000
commitcb7ca29ccfb777175e9f35287c61d53617f45a36 (patch)
tree440034bd5bbeef65a3eef45cdbf78e72ba4043b5
parent21fd58664dc89376f0ffdc3776d8febdcd12b36c (diff)
downloadFreeBSD-src-cb7ca29ccfb777175e9f35287c61d53617f45a36.zip
FreeBSD-src-cb7ca29ccfb777175e9f35287c61d53617f45a36.tar.gz
Add support for physical address hardware watchpoints.
-rw-r--r--sys/sparc64/include/trap.h5
-rw-r--r--sys/sparc64/sparc64/trap.c29
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.
OpenPOWER on IntegriCloud