diff options
author | Michael Neuling <mikey@neuling.org> | 2012-12-20 09:06:44 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-01-10 01:01:44 -0500 |
commit | 9422de3e953d0e60eb95f5430a9dd803eec1c6d7 (patch) | |
tree | 7255a4a2b873a0c3daf7b312a0845202edf6b2d5 /arch/powerpc/xmon/xmon.c | |
parent | a8190a59e7440a7e3f7c0889d72a13e157988b3c (diff) |
powerpc: Hardware breakpoints rewrite to handle non DABR breakpoint registers
This is a rewrite so that we don't assume we are using the DABR throughout the
code. We now use the arch_hw_breakpoint to store the breakpoint in a generic
manner in the thread_struct, rather than storing the raw DABR value.
The ptrace GET/SET_DEBUGREG interface currently passes the raw DABR in from
userspace. We keep this functionality, so that future changes (like the POWER8
DAWR), will still fake the DABR to userspace.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/xmon/xmon.c')
-rw-r--r-- | arch/powerpc/xmon/xmon.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 1f8d2f10a432..529c1ed7f59f 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <asm/setjmp.h> | 43 | #include <asm/setjmp.h> |
44 | #include <asm/reg.h> | 44 | #include <asm/reg.h> |
45 | #include <asm/debug.h> | 45 | #include <asm/debug.h> |
46 | #include <asm/hw_breakpoint.h> | ||
46 | 47 | ||
47 | #ifdef CONFIG_PPC64 | 48 | #ifdef CONFIG_PPC64 |
48 | #include <asm/hvcall.h> | 49 | #include <asm/hvcall.h> |
@@ -607,7 +608,7 @@ static int xmon_sstep(struct pt_regs *regs) | |||
607 | return 1; | 608 | return 1; |
608 | } | 609 | } |
609 | 610 | ||
610 | static int xmon_dabr_match(struct pt_regs *regs) | 611 | static int xmon_break_match(struct pt_regs *regs) |
611 | { | 612 | { |
612 | if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT)) | 613 | if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT)) |
613 | return 0; | 614 | return 0; |
@@ -740,8 +741,14 @@ static void insert_bpts(void) | |||
740 | 741 | ||
741 | static void insert_cpu_bpts(void) | 742 | static void insert_cpu_bpts(void) |
742 | { | 743 | { |
743 | if (dabr.enabled) | 744 | struct arch_hw_breakpoint brk; |
744 | set_dabr(dabr.address | (dabr.enabled & 7), DABRX_ALL); | 745 | |
746 | if (dabr.enabled) { | ||
747 | brk.address = dabr.address; | ||
748 | brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL; | ||
749 | brk.len = 8; | ||
750 | set_break(&brk); | ||
751 | } | ||
745 | if (iabr && cpu_has_feature(CPU_FTR_IABR)) | 752 | if (iabr && cpu_has_feature(CPU_FTR_IABR)) |
746 | mtspr(SPRN_IABR, iabr->address | 753 | mtspr(SPRN_IABR, iabr->address |
747 | | (iabr->enabled & (BP_IABR|BP_IABR_TE))); | 754 | | (iabr->enabled & (BP_IABR|BP_IABR_TE))); |
@@ -769,7 +776,7 @@ static void remove_bpts(void) | |||
769 | 776 | ||
770 | static void remove_cpu_bpts(void) | 777 | static void remove_cpu_bpts(void) |
771 | { | 778 | { |
772 | set_dabr(0, 0); | 779 | hw_breakpoint_disable(); |
773 | if (cpu_has_feature(CPU_FTR_IABR)) | 780 | if (cpu_has_feature(CPU_FTR_IABR)) |
774 | mtspr(SPRN_IABR, 0); | 781 | mtspr(SPRN_IABR, 0); |
775 | } | 782 | } |
@@ -1138,7 +1145,7 @@ bpt_cmds(void) | |||
1138 | printf(badaddr); | 1145 | printf(badaddr); |
1139 | break; | 1146 | break; |
1140 | } | 1147 | } |
1141 | dabr.address &= ~7; | 1148 | dabr.address &= ~HW_BRK_TYPE_DABR; |
1142 | dabr.enabled = mode | BP_DABR; | 1149 | dabr.enabled = mode | BP_DABR; |
1143 | } | 1150 | } |
1144 | break; | 1151 | break; |
@@ -2917,7 +2924,7 @@ static void xmon_init(int enable) | |||
2917 | __debugger_bpt = xmon_bpt; | 2924 | __debugger_bpt = xmon_bpt; |
2918 | __debugger_sstep = xmon_sstep; | 2925 | __debugger_sstep = xmon_sstep; |
2919 | __debugger_iabr_match = xmon_iabr_match; | 2926 | __debugger_iabr_match = xmon_iabr_match; |
2920 | __debugger_dabr_match = xmon_dabr_match; | 2927 | __debugger_break_match = xmon_break_match; |
2921 | __debugger_fault_handler = xmon_fault_handler; | 2928 | __debugger_fault_handler = xmon_fault_handler; |
2922 | } else { | 2929 | } else { |
2923 | __debugger = NULL; | 2930 | __debugger = NULL; |
@@ -2925,7 +2932,7 @@ static void xmon_init(int enable) | |||
2925 | __debugger_bpt = NULL; | 2932 | __debugger_bpt = NULL; |
2926 | __debugger_sstep = NULL; | 2933 | __debugger_sstep = NULL; |
2927 | __debugger_iabr_match = NULL; | 2934 | __debugger_iabr_match = NULL; |
2928 | __debugger_dabr_match = NULL; | 2935 | __debugger_break_match = NULL; |
2929 | __debugger_fault_handler = NULL; | 2936 | __debugger_fault_handler = NULL; |
2930 | } | 2937 | } |
2931 | } | 2938 | } |