PERFORCE change 123213 for review
Marcel Moolenaar
marcel at FreeBSD.org
Mon Jul 9 16:53:49 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=123213
Change 123213 by marcel at marcel_xcllnt on 2007/07/09 16:53:19
Add hardware watchpoint support. Rough implementation.
Affected files ...
.. //depot/projects/powerpc/contrib/gdb/gdb/config/powerpc/nm-fbsd.h#2 edit
.. //depot/projects/powerpc/contrib/gdb/gdb/ppcfbsd-nat.c#3 edit
.. //depot/projects/powerpc/sys/powerpc/include/pcb.h#4 edit
.. //depot/projects/powerpc/sys/powerpc/include/reg.h#5 edit
.. //depot/projects/powerpc/sys/powerpc/include/spr.h#3 edit
.. //depot/projects/powerpc/sys/powerpc/powerpc/genassym.c#5 edit
.. //depot/projects/powerpc/sys/powerpc/powerpc/machdep.c#11 edit
.. //depot/projects/powerpc/sys/powerpc/powerpc/swtch.S#2 edit
.. //depot/projects/powerpc/sys/powerpc/powerpc/trap.c#7 edit
.. //depot/projects/powerpc/sys/powerpc/powerpc/vm_machdep.c#7 edit
Differences ...
==== //depot/projects/powerpc/contrib/gdb/gdb/config/powerpc/nm-fbsd.h#2 (text+ko) ====
@@ -15,4 +15,22 @@
/* Override child_pid_to_exec_file in 'inftarg.c'. */
#define CHILD_PID_TO_EXEC_FILE
+/*
+ * Hardware watchpoint support.
+ */
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
+ ppc_can_use_hwatch(type, cnt, ot)
+
+#define TARGET_REGION_OK_FOR_HW_WATCHPOINT(addr, len) \
+ ppc_region_ok_for_hwatch(addr, len)
+
+#define target_insert_watchpoint ppc_insert_watchpoint
+#define target_remove_watchpoint ppc_remove_watchpoint
+
+#define HAVE_NONSTEPPABLE_WATCHPOINT 1
+
+#define STOPPED_BY_WATCHPOINT(W) ppc_stopped_by_hwatch()
+
#endif /* NM_FBSD_H */
==== //depot/projects/powerpc/contrib/gdb/gdb/ppcfbsd-nat.c#3 (text+ko) ====
@@ -160,6 +160,67 @@
ppcfbsd_supply_fpreg (fpregs, -1);
}
+/*
+ * hardware watchpoint support.
+ */
+
+int
+ppc_can_use_hwatch(int type, int count, int type_used)
+{
+
+ // printf("XXX: %s(%d, %d, %d)\n", __func__, type, count, type_used);
+ return ((type == bp_hardware_watchpoint && count == 1) ? 1 : 0);
+}
+
+int
+ppc_region_ok_for_hwatch(CORE_ADDR addr, int len)
+{
+
+ // printf("XXX: %s(%lld, %d)\n", __func__, addr, len);
+ return ((addr >> 3 == (addr + len - 1) >> 3) ? 1 : 0);
+}
+
+int
+ppc_stopped_by_hwatch(void)
+{
+ struct dbreg dbreg;
+
+ // printf("XXX: %s(%d)\n", __func__, ws);
+ if (ptrace(PT_GETDBREGS, PIDGET(inferior_ptid),
+ (PTRACE_ARG3_TYPE)&dbreg, 0) == -1)
+ return (0);
+ if (dbreg.dabr == 0)
+ return (0);
+ return ((dbreg.wppc == read_pc()) ? 1 : 0);
+}
+
+int
+ppc_insert_watchpoint(CORE_ADDR addr, int len, int type)
+{
+ struct dbreg dbreg;
+
+ // printf("XXX: %s(%lld, %d, %d)\n", __func__, addr, len, type);
+ dbreg.dabr = addr & ~7U;
+ dbreg.dabr |= 0x6;
+ if (ptrace(PT_SETDBREGS, PIDGET(inferior_ptid),
+ (PTRACE_ARG3_TYPE)&dbreg, 0) == -1)
+ return (errno);
+ return (0);
+}
+
+int
+ppc_remove_watchpoint(CORE_ADDR addr, int len, int type)
+{
+ struct dbreg dbreg;
+
+ // printf("XXX: %s(%lld, %d, %d)\n", __func__, addr, len, type);
+ dbreg.dabr = 0;
+ if (ptrace(PT_SETDBREGS, PIDGET(inferior_ptid),
+ (PTRACE_ARG3_TYPE)&dbreg, 0) == -1)
+ return (errno);
+ return (0);
+}
+
/* Provide a prototype to silence -Wmissing-prototypes. */
void _initialize_ppcfbsd_nat (void);
==== //depot/projects/powerpc/sys/powerpc/include/pcb.h#4 (text+ko) ====
@@ -48,7 +48,12 @@
faultbuf *pcb_onfault; /* For use during
copyin/copyout */
int pcb_flags;
-#define PCB_FPU 1 /* Process had FPU initialized */
+#define PCB_FPU 1 /* Process had FPU initialized */
+#define PCB_DBREGS 2 /* Process had DB registers */
+
+ register_t pcb_dabr;
+ register_t pcb_wppc;
+
struct fpu {
double fpr[32];
double fpscr; /* FPSCR stored as double for easier access */
==== //depot/projects/powerpc/sys/powerpc/include/reg.h#5 (text+ko) ====
@@ -21,7 +21,8 @@
};
struct dbreg {
- unsigned long junk;
+ register_t dabr;
+ register_t wppc;
};
#ifdef _KERNEL
==== //depot/projects/powerpc/sys/powerpc/include/spr.h#3 (text+ko) ====
@@ -404,6 +404,7 @@
#define MSSCR0_EMODE 0x00200000 /* 10: MPX bus mode (read-only) */
#define MSSCR0_ABD 0x00100000 /* 11: address bus driven (read-only) */
#define MSSCR0_MBZ 0x000fffff /* 12-31: must be zero */
+#define SPR_DABRX 0x3f7 /* .6. DABR extension */
#define SPR_DAC2 0x3f7 /* 4.. Data Address Compare 2 */
#define SPR_L2PM 0x3f8 /* .6. L2 Private Memory Control Register */
#define SPR_L2CR 0x3f9 /* .6. L2 Control Register */
==== //depot/projects/powerpc/sys/powerpc/powerpc/genassym.c#5 (text+ko) ====
@@ -54,6 +54,7 @@
#include <machine/pcb.h>
#include <machine/pmap.h>
#include <machine/sigframe.h>
+#include <machine/spr.h>
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
@@ -134,8 +135,10 @@
ASSYM(PCB_LR, offsetof(struct pcb, pcb_lr));
ASSYM(PCB_USR, offsetof(struct pcb, pcb_usr));
ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
+ASSYM(PCB_DABR, offsetof(struct pcb, pcb_dabr));
ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
ASSYM(PCB_FPU, PCB_FPU);
+ASSYM(PCB_DBREGS, PCB_DBREGS);
ASSYM(TD_PROC, offsetof(struct thread, td_proc));
ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
@@ -152,3 +155,5 @@
ASSYM(SF_UC, offsetof(struct sigframe, sf_uc));
ASSYM(MAXCOMLEN, MAXCOMLEN);
+
+ASSYM(SPR_DABR, SPR_DABR);
==== //depot/projects/powerpc/sys/powerpc/powerpc/machdep.c#11 (text+ko) ====
@@ -114,6 +114,7 @@
#include <machine/powerpc.h>
#include <machine/reg.h>
#include <machine/sigframe.h>
+#include <machine/spr.h>
#include <machine/trap.h>
#include <machine/vmparam.h>
@@ -791,6 +792,22 @@
tf->srr0 = entry;
tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT;
+
+ /*
+ * Reset the hardware debug registers if they were in use.
+ * They won't have any meaning for the newly exec'd process.
+ */
+ if (td->td_pcb->pcb_flags & PCB_DBREGS) {
+ if (td->td_pcb == PCPU_GET(curpcb)) {
+ /*
+ * Clear the debug registers on the running
+ * CPU, otherwise they will end up affecting
+ * the next process we switch to.
+ */
+ mtspr(SPR_DABR, 0);
+ }
+ }
+
td->td_pcb->pcb_flags = 0;
}
@@ -808,8 +825,12 @@
int
fill_dbregs(struct thread *td, struct dbreg *dbregs)
{
- /* No debug registers on PowerPC */
- return (ENOSYS);
+ int has_dbregs;
+
+ has_dbregs = (td->td_pcb->pcb_flags & PCB_DBREGS) ? 1 : 0;
+ dbregs->dabr = (has_dbregs) ? td->td_pcb->pcb_dabr : 0;
+ dbregs->wppc = (has_dbregs) ? td->td_pcb->pcb_wppc : 0;
+ return (0);
}
int
@@ -841,8 +862,17 @@
int
set_dbregs(struct thread *td, struct dbreg *dbregs)
{
- /* No debug registers on PowerPC */
- return (ENOSYS);
+
+ td->td_pcb->pcb_dabr = dbregs->dabr;
+ td->td_pcb->pcb_wppc = 0;
+ if (dbregs->dabr != 0)
+ td->td_pcb->pcb_flags |= PCB_DBREGS;
+ else
+ td->td_pcb->pcb_flags &= ~PCB_DBREGS;
+ mtspr(SPR_DABRX, 1);
+ if (td == curthread)
+ mtspr(SPR_DABR, dbregs->dabr);
+ return (0);
}
int
==== //depot/projects/powerpc/sys/powerpc/powerpc/swtch.S#2 (text+ko) ====
@@ -90,7 +90,16 @@
mr %r14,%r3 /* Copy the old thread ptr... */
mr %r15,%r4 /* and the new thread ptr in scratch */
- lwz %r6,PCB_FLAGS(%r5) /* Save FPU context if needed */
+ lwz %r6,PCB_FLAGS(%r5)
+ /* Save and reset the DABR if needed */
+ andi. %r16, %r6, PCB_DBREGS
+ beq .L0
+ mfspr %r16, SPR_DABR
+ stw %r16, PCB_DABR(%r5)
+ li %r16, 0
+ mtspr SPR_DABR, %r16
+.L0:
+ /* Save FPU context if needed */
andi. %r6, %r6, PCB_FPU
beq .L1
bl save_fpu
@@ -107,13 +116,18 @@
stw %r17,PC_CURPCB(%r7)
lwz %r6, PCB_FLAGS(%r17) /* Restore FPU context if needed */
+ andi. %r16, %r6, PCB_DBREGS
+ beq .L2
+ lwz %r16, PCB_DABR(%r17)
+ mtspr SPR_DABR, %r16
+.L2:
andi. %r6, %r6, PCB_FPU
- beq .L2
+ beq .L3
mr %r3,%r15 /* Pass curthread to enable_fpu */
bl enable_fpu
/* thread to restore is in r3 */
-.L2:
+.L3:
mr %r3,%r17 /* Recover PCB ptr */
lmw %r12,PCB_CONTEXT(%r3) /* Load the non-volatile GP regs */
mr %r2,%r12
==== //depot/projects/powerpc/sys/powerpc/powerpc/trap.c#7 (text+ko) ====
@@ -176,6 +176,13 @@
break;
case EXC_DSI:
+ if (frame->dsisr & DSISR_DABR) {
+ td->td_pcb->pcb_wppc = frame->srr0;
+ frame->dar = td->td_pcb->pcb_dabr & ~7;
+ sig = SIGTRAP;
+ break;
+ }
+ /* FALLTHROUGH */
case EXC_ISI:
sig = trap_pfault(frame, 1);
break;
==== //depot/projects/powerpc/sys/powerpc/powerpc/vm_machdep.c#7 (text+ko) ====
@@ -90,6 +90,7 @@
#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/powerpc.h>
+#include <machine/spr.h>
#include <dev/ofw/openfirm.h>
@@ -269,6 +270,12 @@
void
cpu_thread_exit(struct thread *td)
{
+
+ /* Disable any hardware breakpoints. */
+ if (td->td_pcb->pcb_flags & PCB_DBREGS) {
+ mtspr(SPR_DABR, 0);
+ td->td_pcb->pcb_flags &= ~PCB_DBREGS;
+ }
}
void
More information about the p4-projects
mailing list