Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 172ae2e7 authored by Dave Kleikamp's avatar Dave Kleikamp Committed by Benjamin Herrenschmidt
Browse files

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: default avatarDave Kleikamp <shaggy@linux.vnet.ibm.com>
Acked-by: default avatarDavid Gibson <dwg@au1.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 789c299c
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -240,6 +240,33 @@ config PPC_OF_PLATFORM_PCI
config ARCH_SUPPORTS_DEBUG_PAGEALLOC
	def_bool y

config PPC_ADV_DEBUG_REGS
	bool
	depends on 40x || BOOKE
	default y

config PPC_ADV_DEBUG_IACS
	int
	depends on PPC_ADV_DEBUG_REGS
	default 4 if 44x
	default 2

config PPC_ADV_DEBUG_DACS
	int
	depends on PPC_ADV_DEBUG_REGS
	default 2

config PPC_ADV_DEBUG_DVCS
	int
	depends on PPC_ADV_DEBUG_REGS
	default 2 if 44x
	default 0

config PPC_ADV_DEBUG_DAC_RANGE
	bool
	depends on PPC_ADV_DEBUG_REGS && 44x
	default y

source "init/Kconfig"

source "kernel/Kconfig.freezer"
+1 −1
Original line number Diff line number Diff line
@@ -333,7 +333,7 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
		atomic_set(&kgdb_cpu_doing_single_step, -1);
		/* set the trace bit if we're stepping */
		if (remcom_in_buffer[0] == 's') {
#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
			mtspr(SPRN_DBCR0,
			      mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
			linux_regs->msr |= MSR_DE;
+2 −2
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@
#include <asm/uaccess.h>
#include <asm/system.h>

#ifdef CONFIG_BOOKE
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
#define MSR_SINGLESTEP	(MSR_DE)
#else
#define MSR_SINGLESTEP	(MSR_SE)
@@ -110,7 +110,7 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
	 * like Decrementer or External Interrupt */
	regs->msr &= ~MSR_EE;
	regs->msr |= MSR_SINGLESTEP;
#ifdef CONFIG_BOOKE
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
	regs->msr &= ~MSR_CE;
	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
#endif
+5 −5
Original line number Diff line number Diff line
@@ -258,7 +258,7 @@ void do_dabr(struct pt_regs *regs, unsigned long address,
		return;

	/* Clear the DAC and struct entries.  One shot trigger */
#if defined(CONFIG_BOOKE)
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBSR_DAC1R | DBSR_DAC1W
							| DBCR0_IDM));
#endif
@@ -284,7 +284,7 @@ int set_dabr(unsigned long dabr)
		return ppc_md.set_dabr(dabr);

	/* XXX should we have a CPU_FTR_HAS_DABR ? */
#if defined(CONFIG_BOOKE)
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
	mtspr(SPRN_DAC1, dabr);
#elif defined(CONFIG_PPC_BOOK3S)
	mtspr(SPRN_DABR, dabr);
@@ -371,7 +371,7 @@ struct task_struct *__switch_to(struct task_struct *prev,

#endif /* CONFIG_SMP */

#if defined(CONFIG_BOOKE)
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
	/* If new thread DAC (HW breakpoint) is the same then leave it */
	if (new->thread.dabr)
		set_dabr(new->thread.dabr);
@@ -514,7 +514,7 @@ void show_regs(struct pt_regs * regs)
	printk("  CR: %08lx  XER: %08lx\n", regs->ccr, regs->xer);
	trap = TRAP(regs);
	if (trap == 0x300 || trap == 0x600)
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
		printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr);
#else
		printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
@@ -560,7 +560,7 @@ void flush_thread(void)
		current->thread.dabr = 0;
		set_dabr(0);

#if defined(CONFIG_BOOKE)
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
		current->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W);
#endif
	}
+7 −11
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@
/*
 * Set of msr bits that gdb can change on behalf of a process.
 */
#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
#define MSR_DEBUGCHANGE	0
#else
#define MSR_DEBUGCHANGE	(MSR_SE | MSR_BE)
@@ -703,7 +703,7 @@ void user_enable_single_step(struct task_struct *task)
	struct pt_regs *regs = task->thread.regs;

	if (regs != NULL) {
#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
		task->thread.dbcr0 &= ~DBCR0_BT;
		task->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC;
		regs->msr |= MSR_DE;
@@ -720,7 +720,7 @@ void user_enable_block_step(struct task_struct *task)
	struct pt_regs *regs = task->thread.regs;

	if (regs != NULL) {
#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
		task->thread.dbcr0 &= ~DBCR0_IC;
		task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT;
		regs->msr |= MSR_DE;
@@ -737,7 +737,7 @@ void user_disable_single_step(struct task_struct *task)
	struct pt_regs *regs = task->thread.regs;

	if (regs != NULL) {
#if defined(CONFIG_BOOKE)
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
		/* If DAC don't clear DBCRO_IDM or MSR_DE */
		if (task->thread.dabr)
			task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT);
@@ -745,9 +745,6 @@ void user_disable_single_step(struct task_struct *task)
			task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM);
			regs->msr &= ~MSR_DE;
		}
#elif defined(CONFIG_40x)
		task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM);
		regs->msr &= ~MSR_DE;
#else
		regs->msr &= ~(MSR_SE | MSR_BE);
#endif
@@ -769,7 +766,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
	if ((data & ~0x7UL) >= TASK_SIZE)
		return -EIO;

#ifndef CONFIG_BOOKE
#ifndef CONFIG_PPC_ADV_DEBUG_REGS

	/* For processors using DABR (i.e. 970), the bottom 3 bits are flags.
	 *  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,
	/* Move contents to the DABR register */
	task->thread.dabr = data;

#endif
#if defined(CONFIG_BOOKE)
#else /* CONFIG_PPC_ADV_DEBUG_REGS */

	/* As described above, it was assumed 3 bits were passed with the data
	 *  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,
		task->thread.dbcr0 |= DBSR_DAC1W;

	task->thread.regs->msr |= MSR_DE;
#endif
#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
	return 0;
}

Loading