diff options
Diffstat (limited to 'arch/arm/kernel/hw_breakpoint.c')
| -rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 44 | 
1 files changed, 26 insertions, 18 deletions
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index c9f3f046757..d600bd35070 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -137,11 +137,10 @@ static u8 get_debug_arch(void)  	u32 didr;  	/* Do we implement the extended CPUID interface? */ -	if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { -		pr_warning("CPUID feature registers not supported. " -				"Assuming v6 debug is present.\n"); +	if (WARN_ONCE((((read_cpuid_id() >> 16) & 0xf) != 0xf), +	    "CPUID feature registers not supported. " +	    "Assuming v6 debug is present.\n"))  		return ARM_DEBUG_ARCH_V6; -	}  	ARM_DBG_READ(c0, 0, didr);  	return (didr >> 16) & 0xf; @@ -152,6 +151,12 @@ u8 arch_get_debug_arch(void)  	return debug_arch;  } +static int debug_arch_supported(void) +{ +	u8 arch = get_debug_arch(); +	return arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14; +} +  /* Determine number of BRP register available. */  static int get_num_brp_resources(void)  { @@ -268,6 +273,9 @@ out:  int hw_breakpoint_slots(int type)  { +	if (!debug_arch_supported()) +		return 0; +  	/*  	 * We can be called early, so don't rely on  	 * our static variables being initialised. @@ -834,11 +842,11 @@ static void reset_ctrl_regs(void *unused)  	/*  	 * v7 debug contains save and restore registers so that debug state -	 * can be maintained across low-power modes without leaving -	 * the debug logic powered up. It is IMPLEMENTATION DEFINED whether -	 * we can write to the debug registers out of reset, so we must -	 * unlock the OS Lock Access Register to avoid taking undefined -	 * instruction exceptions later on. +	 * can be maintained across low-power modes without leaving the debug +	 * logic powered up. It is IMPLEMENTATION DEFINED whether we can access +	 * the debug registers out of reset, so we must unlock the OS Lock +	 * Access Register to avoid taking undefined instruction exceptions +	 * later on.  	 */  	if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) {  		/* @@ -882,7 +890,7 @@ static int __init arch_hw_breakpoint_init(void)  	debug_arch = get_debug_arch(); -	if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) { +	if (!debug_arch_supported()) {  		pr_info("debug architecture 0x%x unsupported.\n", debug_arch);  		return 0;  	} @@ -899,18 +907,18 @@ static int __init arch_hw_breakpoint_init(void)  		pr_info("%d breakpoint(s) reserved for watchpoint "  				"single-step.\n", core_num_reserved_brps); +	/* +	 * 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, NULL, 1); +  	ARM_DBG_READ(c1, 0, dscr);  	if (dscr & ARM_DSCR_HDBGEN) { +		max_watchpoint_len = 4;  		pr_warning("halting debug mode enabled. Assuming maximum " -				"watchpoint size of 4 bytes."); +			   "watchpoint size of %u bytes.", max_watchpoint_len);  	} else { -		/* -		 * Reset the breakpoint resources. We assume that a halting -		 * debugger will leave the world in a nice state for us. -		 */ -		smp_call_function(reset_ctrl_regs, NULL, 1); -		reset_ctrl_regs(NULL); -  		/* Work out the maximum supported watchpoint length. */  		max_watchpoint_len = get_max_wp_len();  		pr_info("maximum watchpoint size is %u bytes.\n",  |