Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 270112
b: refs/heads/master
c: 0d352e3
h: refs/heads/master
v: v3
  • Loading branch information
Will Deacon committed Aug 31, 2011
1 parent 4b5fe2f commit f5748c7
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6f26aa05c9edffff6a4c2cd71774bc659a5cceec
refs/heads/master: 0d352e3d006c9589f22580212c3822cf62b6d775
46 changes: 37 additions & 9 deletions trunk/arch/arm/kernel/hw_breakpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -857,11 +857,31 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
/*
* One-time initialisation.
*/
static void reset_ctrl_regs(void *info)
static cpumask_t debug_err_mask;

static int debug_reg_trap(struct pt_regs *regs, unsigned int instr)
{
int cpu = smp_processor_id();

pr_warning("Debug register access (0x%x) caused undefined instruction on CPU %d\n",
instr, cpu);

/* Set the error flag for this CPU and skip the faulting instruction. */
cpumask_set_cpu(cpu, &debug_err_mask);
instruction_pointer(regs) += 4;
return 0;
}

static struct undef_hook debug_reg_hook = {
.instr_mask = 0x0fe80f10,
.instr_val = 0x0e000e10,
.fn = debug_reg_trap,
};

static void reset_ctrl_regs(void *unused)
{
int i, raw_num_brps, err = 0, cpu = smp_processor_id();
u32 dbg_power;
cpumask_t *cpumask = info;

/*
* v7 debug contains save and restore registers so that debug state
Expand Down Expand Up @@ -893,7 +913,7 @@ static void reset_ctrl_regs(void *info)

if (err) {
pr_warning("CPU %d debug is powered down!\n", cpu);
cpumask_or(cpumask, cpumask, cpumask_of(cpu));
cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu));
return;
}

Expand Down Expand Up @@ -932,6 +952,7 @@ static int __cpuinit dbg_reset_notify(struct notifier_block *self,
{
if (action == CPU_ONLINE)
smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1);

return NOTIFY_OK;
}

Expand All @@ -942,7 +963,6 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = {
static int __init arch_hw_breakpoint_init(void)
{
u32 dscr;
cpumask_t cpumask = { CPU_BITS_NONE };

debug_arch = get_debug_arch();

Expand All @@ -955,21 +975,29 @@ static int __init arch_hw_breakpoint_init(void)
core_num_brps = get_num_brps();
core_num_wrps = get_num_wrps();

pr_info("found %d " "%s" "breakpoint and %d watchpoint registers.\n",
core_num_brps, core_has_mismatch_brps() ? "(+1 reserved) " :
"", core_num_wrps);
/*
* We need to tread carefully here because DBGSWENABLE may be
* driven low on this core and there isn't an architected way to
* determine that.
*/
register_undef_hook(&debug_reg_hook);

/*
* Reset the breakpoint resources. We assume that a halting
* debugger will leave the world in a nice state for us.
*/
on_each_cpu(reset_ctrl_regs, &cpumask, 1);
if (!cpumask_empty(&cpumask)) {
on_each_cpu(reset_ctrl_regs, NULL, 1);
unregister_undef_hook(&debug_reg_hook);
if (!cpumask_empty(&debug_err_mask)) {
core_num_brps = 0;
core_num_wrps = 0;
return 0;
}

pr_info("found %d " "%s" "breakpoint and %d watchpoint registers.\n",
core_num_brps, core_has_mismatch_brps() ? "(+1 reserved) " :
"", core_num_wrps);

ARM_DBG_READ(c1, 0, dscr);
if (dscr & ARM_DSCR_HDBGEN) {
max_watchpoint_len = 4;
Expand Down

0 comments on commit f5748c7

Please sign in to comment.