aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Kleikamp <shaggy@linux.vnet.ibm.com>2010-02-08 06:50:57 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-02-16 22:03:16 -0500
commit172ae2e7f8ff9053905a36672453a6d2ff95b182 (patch)
tree2469b6923a4d7756930ac9c83e8b8fc9bfcdcbe0
parent789c299ca280f96368c0296b739e89c0bb232f8a (diff)
powerpc/booke: Introduce new CONFIG options for advanced debug registers
powerpc/booke: Introduce new CONFIG options for advanced debug registers From: Dave Kleikamp <shaggy@linux.vnet.ibm.com> Introduce new config options to simplify the ifdefs pertaining to the advanced debug registers for booke and 40x processors: CONFIG_PPC_ADV_DEBUG_REGS - boolean: true for dac-based processors CONFIG_PPC_ADV_DEBUG_IACS - number of IAC registers CONFIG_PPC_ADV_DEBUG_DACS - number of DAC registers CONFIG_PPC_ADV_DEBUG_DVCS - number of DVC registers CONFIG_PPC_ADV_DEBUG_DAC_RANGE - DAC ranges supported Beginning conservatively, since I only have the facilities to test 440 hardware. I believe all 40x and booke platforms support at least 2 IAC and 2 DAC registers. For 440, 4 IAC and 2 DVC registers are enabled, as well as the DAC ranges. Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com> Acked-by: David Gibson <dwg@au1.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/Kconfig27
-rw-r--r--arch/powerpc/kernel/kgdb.c2
-rw-r--r--arch/powerpc/kernel/kprobes.c4
-rw-r--r--arch/powerpc/kernel/process.c10
-rw-r--r--arch/powerpc/kernel/ptrace.c18
-rw-r--r--arch/powerpc/kernel/signal.c2
-rw-r--r--arch/powerpc/kernel/signal_32.c8
-rw-r--r--arch/powerpc/kernel/traps.c6
8 files changed, 50 insertions, 27 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index bf15e7b4cd3d..654bba5cf6b4 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -240,6 +240,33 @@ config PPC_OF_PLATFORM_PCI
240config ARCH_SUPPORTS_DEBUG_PAGEALLOC 240config ARCH_SUPPORTS_DEBUG_PAGEALLOC
241 def_bool y 241 def_bool y
242 242
243config PPC_ADV_DEBUG_REGS
244 bool
245 depends on 40x || BOOKE
246 default y
247
248config PPC_ADV_DEBUG_IACS
249 int
250 depends on PPC_ADV_DEBUG_REGS
251 default 4 if 44x
252 default 2
253
254config PPC_ADV_DEBUG_DACS
255 int
256 depends on PPC_ADV_DEBUG_REGS
257 default 2
258
259config PPC_ADV_DEBUG_DVCS
260 int
261 depends on PPC_ADV_DEBUG_REGS
262 default 2 if 44x
263 default 0
264
265config PPC_ADV_DEBUG_DAC_RANGE
266 bool
267 depends on PPC_ADV_DEBUG_REGS && 44x
268 default y
269
243source "init/Kconfig" 270source "init/Kconfig"
244 271
245source "kernel/Kconfig.freezer" 272source "kernel/Kconfig.freezer"
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index b6bd1eaa1c24..41bada0298c8 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -333,7 +333,7 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
333 atomic_set(&kgdb_cpu_doing_single_step, -1); 333 atomic_set(&kgdb_cpu_doing_single_step, -1);
334 /* set the trace bit if we're stepping */ 334 /* set the trace bit if we're stepping */
335 if (remcom_in_buffer[0] == 's') { 335 if (remcom_in_buffer[0] == 's') {
336#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) 336#ifdef CONFIG_PPC_ADV_DEBUG_REGS
337 mtspr(SPRN_DBCR0, 337 mtspr(SPRN_DBCR0,
338 mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM); 338 mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
339 linux_regs->msr |= MSR_DE; 339 linux_regs->msr |= MSR_DE;
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index c9329786073b..3fd1af902112 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -36,7 +36,7 @@
36#include <asm/uaccess.h> 36#include <asm/uaccess.h>
37#include <asm/system.h> 37#include <asm/system.h>
38 38
39#ifdef CONFIG_BOOKE 39#ifdef CONFIG_PPC_ADV_DEBUG_REGS
40#define MSR_SINGLESTEP (MSR_DE) 40#define MSR_SINGLESTEP (MSR_DE)
41#else 41#else
42#define MSR_SINGLESTEP (MSR_SE) 42#define MSR_SINGLESTEP (MSR_SE)
@@ -110,7 +110,7 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
110 * like Decrementer or External Interrupt */ 110 * like Decrementer or External Interrupt */
111 regs->msr &= ~MSR_EE; 111 regs->msr &= ~MSR_EE;
112 regs->msr |= MSR_SINGLESTEP; 112 regs->msr |= MSR_SINGLESTEP;
113#ifdef CONFIG_BOOKE 113#ifdef CONFIG_PPC_ADV_DEBUG_REGS
114 regs->msr &= ~MSR_CE; 114 regs->msr &= ~MSR_CE;
115 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM); 115 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
116#endif 116#endif
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 7b816daf3eba..9be77e3936fb 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -258,7 +258,7 @@ void do_dabr(struct pt_regs *regs, unsigned long address,
258 return; 258 return;
259 259
260 /* Clear the DAC and struct entries. One shot trigger */ 260 /* Clear the DAC and struct entries. One shot trigger */
261#if defined(CONFIG_BOOKE) 261#ifdef CONFIG_PPC_ADV_DEBUG_REGS
262 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBSR_DAC1R | DBSR_DAC1W 262 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBSR_DAC1R | DBSR_DAC1W
263 | DBCR0_IDM)); 263 | DBCR0_IDM));
264#endif 264#endif
@@ -284,7 +284,7 @@ int set_dabr(unsigned long dabr)
284 return ppc_md.set_dabr(dabr); 284 return ppc_md.set_dabr(dabr);
285 285
286 /* XXX should we have a CPU_FTR_HAS_DABR ? */ 286 /* XXX should we have a CPU_FTR_HAS_DABR ? */
287#if defined(CONFIG_BOOKE) 287#ifdef CONFIG_PPC_ADV_DEBUG_REGS
288 mtspr(SPRN_DAC1, dabr); 288 mtspr(SPRN_DAC1, dabr);
289#elif defined(CONFIG_PPC_BOOK3S) 289#elif defined(CONFIG_PPC_BOOK3S)
290 mtspr(SPRN_DABR, dabr); 290 mtspr(SPRN_DABR, dabr);
@@ -371,7 +371,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
371 371
372#endif /* CONFIG_SMP */ 372#endif /* CONFIG_SMP */
373 373
374#if defined(CONFIG_BOOKE) 374#ifdef CONFIG_PPC_ADV_DEBUG_REGS
375 /* If new thread DAC (HW breakpoint) is the same then leave it */ 375 /* If new thread DAC (HW breakpoint) is the same then leave it */
376 if (new->thread.dabr) 376 if (new->thread.dabr)
377 set_dabr(new->thread.dabr); 377 set_dabr(new->thread.dabr);
@@ -514,7 +514,7 @@ void show_regs(struct pt_regs * regs)
514 printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); 514 printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer);
515 trap = TRAP(regs); 515 trap = TRAP(regs);
516 if (trap == 0x300 || trap == 0x600) 516 if (trap == 0x300 || trap == 0x600)
517#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 517#ifdef CONFIG_PPC_ADV_DEBUG_REGS
518 printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr); 518 printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr);
519#else 519#else
520 printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr); 520 printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
@@ -560,7 +560,7 @@ void flush_thread(void)
560 current->thread.dabr = 0; 560 current->thread.dabr = 0;
561 set_dabr(0); 561 set_dabr(0);
562 562
563#if defined(CONFIG_BOOKE) 563#ifdef CONFIG_PPC_ADV_DEBUG_REGS
564 current->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W); 564 current->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W);
565#endif 565#endif
566 } 566 }
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index ef149880c145..292c81432014 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -46,7 +46,7 @@
46/* 46/*
47 * Set of msr bits that gdb can change on behalf of a process. 47 * Set of msr bits that gdb can change on behalf of a process.
48 */ 48 */
49#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) 49#ifdef CONFIG_PPC_ADV_DEBUG_REGS
50#define MSR_DEBUGCHANGE 0 50#define MSR_DEBUGCHANGE 0
51#else 51#else
52#define MSR_DEBUGCHANGE (MSR_SE | MSR_BE) 52#define MSR_DEBUGCHANGE (MSR_SE | MSR_BE)
@@ -703,7 +703,7 @@ void user_enable_single_step(struct task_struct *task)
703 struct pt_regs *regs = task->thread.regs; 703 struct pt_regs *regs = task->thread.regs;
704 704
705 if (regs != NULL) { 705 if (regs != NULL) {
706#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) 706#ifdef CONFIG_PPC_ADV_DEBUG_REGS
707 task->thread.dbcr0 &= ~DBCR0_BT; 707 task->thread.dbcr0 &= ~DBCR0_BT;
708 task->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC; 708 task->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC;
709 regs->msr |= MSR_DE; 709 regs->msr |= MSR_DE;
@@ -720,7 +720,7 @@ void user_enable_block_step(struct task_struct *task)
720 struct pt_regs *regs = task->thread.regs; 720 struct pt_regs *regs = task->thread.regs;
721 721
722 if (regs != NULL) { 722 if (regs != NULL) {
723#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) 723#ifdef CONFIG_PPC_ADV_DEBUG_REGS
724 task->thread.dbcr0 &= ~DBCR0_IC; 724 task->thread.dbcr0 &= ~DBCR0_IC;
725 task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT; 725 task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT;
726 regs->msr |= MSR_DE; 726 regs->msr |= MSR_DE;
@@ -737,7 +737,7 @@ void user_disable_single_step(struct task_struct *task)
737 struct pt_regs *regs = task->thread.regs; 737 struct pt_regs *regs = task->thread.regs;
738 738
739 if (regs != NULL) { 739 if (regs != NULL) {
740#if defined(CONFIG_BOOKE) 740#ifdef CONFIG_PPC_ADV_DEBUG_REGS
741 /* If DAC don't clear DBCRO_IDM or MSR_DE */ 741 /* If DAC don't clear DBCRO_IDM or MSR_DE */
742 if (task->thread.dabr) 742 if (task->thread.dabr)
743 task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT); 743 task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT);
@@ -745,9 +745,6 @@ void user_disable_single_step(struct task_struct *task)
745 task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM); 745 task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM);
746 regs->msr &= ~MSR_DE; 746 regs->msr &= ~MSR_DE;
747 } 747 }
748#elif defined(CONFIG_40x)
749 task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM);
750 regs->msr &= ~MSR_DE;
751#else 748#else
752 regs->msr &= ~(MSR_SE | MSR_BE); 749 regs->msr &= ~(MSR_SE | MSR_BE);
753#endif 750#endif
@@ -769,7 +766,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
769 if ((data & ~0x7UL) >= TASK_SIZE) 766 if ((data & ~0x7UL) >= TASK_SIZE)
770 return -EIO; 767 return -EIO;
771 768
772#ifndef CONFIG_BOOKE 769#ifndef CONFIG_PPC_ADV_DEBUG_REGS
773 770
774 /* For processors using DABR (i.e. 970), the bottom 3 bits are flags. 771 /* For processors using DABR (i.e. 970), the bottom 3 bits are flags.
775 * It was assumed, on previous implementations, that 3 bits were 772 * It was assumed, on previous implementations, that 3 bits were
@@ -790,8 +787,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
790 /* Move contents to the DABR register */ 787 /* Move contents to the DABR register */
791 task->thread.dabr = data; 788 task->thread.dabr = data;
792 789
793#endif 790#else /* CONFIG_PPC_ADV_DEBUG_REGS */
794#if defined(CONFIG_BOOKE)
795 791
796 /* As described above, it was assumed 3 bits were passed with the data 792 /* As described above, it was assumed 3 bits were passed with the data
797 * address, but we will assume only the mode bits will be passed 793 * address, but we will assume only the mode bits will be passed
@@ -824,7 +820,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
824 task->thread.dbcr0 |= DBSR_DAC1W; 820 task->thread.dbcr0 |= DBSR_DAC1W;
825 821
826 task->thread.regs->msr |= MSR_DE; 822 task->thread.regs->msr |= MSR_DE;
827#endif 823#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
828 return 0; 824 return 0;
829} 825}
830 826
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 00b5078da9a3..ad7044b5a2c7 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -147,7 +147,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
147 */ 147 */
148 if (current->thread.dabr) { 148 if (current->thread.dabr) {
149 set_dabr(current->thread.dabr); 149 set_dabr(current->thread.dabr);
150#if defined(CONFIG_BOOKE) 150#ifdef CONFIG_PPC_ADV_DEBUG_REGS
151 mtspr(SPRN_DBCR0, current->thread.dbcr0); 151 mtspr(SPRN_DBCR0, current->thread.dbcr0);
152#endif 152#endif
153 } 153 }
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index d670429a1608..e4883ae36277 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -1078,7 +1078,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
1078 int i; 1078 int i;
1079 unsigned char tmp; 1079 unsigned char tmp;
1080 unsigned long new_msr = regs->msr; 1080 unsigned long new_msr = regs->msr;
1081#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 1081#ifdef CONFIG_PPC_ADV_DEBUG_REGS
1082 unsigned long new_dbcr0 = current->thread.dbcr0; 1082 unsigned long new_dbcr0 = current->thread.dbcr0;
1083#endif 1083#endif
1084 1084
@@ -1087,7 +1087,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
1087 return -EFAULT; 1087 return -EFAULT;
1088 switch (op.dbg_type) { 1088 switch (op.dbg_type) {
1089 case SIG_DBG_SINGLE_STEPPING: 1089 case SIG_DBG_SINGLE_STEPPING:
1090#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 1090#ifdef CONFIG_PPC_ADV_DEBUG_REGS
1091 if (op.dbg_value) { 1091 if (op.dbg_value) {
1092 new_msr |= MSR_DE; 1092 new_msr |= MSR_DE;
1093 new_dbcr0 |= (DBCR0_IDM | DBCR0_IC); 1093 new_dbcr0 |= (DBCR0_IDM | DBCR0_IC);
@@ -1103,7 +1103,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
1103#endif 1103#endif
1104 break; 1104 break;
1105 case SIG_DBG_BRANCH_TRACING: 1105 case SIG_DBG_BRANCH_TRACING:
1106#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 1106#ifdef CONFIG_PPC_ADV_DEBUG_REGS
1107 return -EINVAL; 1107 return -EINVAL;
1108#else 1108#else
1109 if (op.dbg_value) 1109 if (op.dbg_value)
@@ -1124,7 +1124,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
1124 failure is a problem, anyway, and it's very unlikely unless 1124 failure is a problem, anyway, and it's very unlikely unless
1125 the user is really doing something wrong. */ 1125 the user is really doing something wrong. */
1126 regs->msr = new_msr; 1126 regs->msr = new_msr;
1127#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 1127#ifdef CONFIG_PPC_ADV_DEBUG_REGS
1128 current->thread.dbcr0 = new_dbcr0; 1128 current->thread.dbcr0 = new_dbcr0;
1129#endif 1129#endif
1130 1130
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 895da29e7db8..4e293b75f951 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -299,7 +299,7 @@ static inline int check_io_access(struct pt_regs *regs)
299 return 0; 299 return 0;
300} 300}
301 301
302#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 302#ifdef CONFIG_PPC_ADV_DEBUG_REGS
303/* On 4xx, the reason for the machine check or program exception 303/* On 4xx, the reason for the machine check or program exception
304 is in the ESR. */ 304 is in the ESR. */
305#define get_reason(regs) ((regs)->dsisr) 305#define get_reason(regs) ((regs)->dsisr)
@@ -1033,7 +1033,7 @@ void SoftwareEmulation(struct pt_regs *regs)
1033} 1033}
1034#endif /* CONFIG_8xx */ 1034#endif /* CONFIG_8xx */
1035 1035
1036#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) 1036#ifdef CONFIG_PPC_ADV_DEBUG_REGS
1037 1037
1038void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status) 1038void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
1039{ 1039{
@@ -1102,7 +1102,7 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
1102 do_dabr(regs, mfspr(SPRN_DAC1), debug_status); 1102 do_dabr(regs, mfspr(SPRN_DAC1), debug_status);
1103 } 1103 }
1104} 1104}
1105#endif /* CONFIG_4xx || CONFIG_BOOKE */ 1105#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
1106 1106
1107#if !defined(CONFIG_TAU_INT) 1107#if !defined(CONFIG_TAU_INT)
1108void TAUException(struct pt_regs *regs) 1108void TAUException(struct pt_regs *regs)