Add support for physical address hardware watchpoints.

This commit is contained in:
Jake Burkholder 2001-10-20 16:04:39 +00:00
parent 6c3dcb9735
commit 209cf80d43
2 changed files with 29 additions and 5 deletions

View File

@ -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

View File

@ -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.