Skip to contentSkip to conversation

hw_breakpoint updates for 3.9

PATCH New Will Deacon 1 participant 4 messages Jan 11, 2013

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover hw_breakpoint updates for 3.9

Hello,

I have a small handful of hw_breakpoint updates, all from Dietmar, that I plan to send via Russell for 3.9.

Any comments, please shout.

Will

Dietmar Eggemann (3):
ARM: coresight: common definition for (OS) Lock Access Register key
value
ARM: hw_breakpoint: Check function for OS Save and Restore mechanism
ARM: hw_breakpoint: Debug powerdown support for self-hosted debug

 arch/arm/include/asm/cti.h                | 10 ++---
 arch/arm/include/asm/hardware/coresight.h |  6 +--
 arch/arm/include/asm/hw_breakpoint.h      |  3 ++
 arch/arm/kernel/hw_breakpoint.c           | 61 +++++++++++++++++++++++++++----
 4 files changed, 62 insertions(+), 18 deletions(-)
Signature · 1 line
1.8.0
#1 lore raw

PATCH 1/3 ARM: coresight: common definition for (OS) Lock Access Register key value

From: Dietmar Eggemann <[email protected]>

Coresight components and debug are using a common lock control mechansim. Writing 0xC5ACCE55 to the Lock Access Register (LAR) in case of a coresight components enables further access to the coresight device registers. Writing any other value to it removes the write access.
Writing 0xC5ACCE55 to the OS Lock Access Register (OSLAR) in case of debug locks the debug register for further access to the debug registers. Writing any other value to it unlocks the debug registers.

Unfortunately, the existing coresight code uses the terms lock and unlock the other way around. Unlocking stands for enabling write access and locking for removing write access.

That is why the definition of the LAR and OSLAR key value has been changed to CS_LAR_KEY.

---
 arch/arm/include/asm/cti.h                | 10 +++-------
 arch/arm/include/asm/hardware/coresight.h |  6 +++---
 arch/arm/kernel/hw_breakpoint.c           |  5 +++--
 3 files changed, 9 insertions(+), 12 deletions(-)
arch/arm/include/asm/cti.h +3 -7
index f2e5cad..2381199 100644
@@ -2,6 +2,7 @@
 #define __ASMARM_CTI_H
 
 #include	<asm/io.h>
+#include	<asm/hardware/coresight.h>
 
 /* The registers' definition is from section 3.2 of
  * Embedded Cross Trigger Revision: r0p0
@@ -35,11 +36,6 @@
 #define		LOCKACCESS		0xFB0
 #define		LOCKSTATUS		0xFB4
 
-/* write this value to LOCKACCESS will unlock the module, and
- * other value will lock the module
- */
-#define		LOCKCODE		0xC5ACCE55
-
 /**
  * struct cti - cross trigger interface struct
  * @base: mapped virtual address for the cti base
@@ -146,7 +142,7 @@ static inline void cti_irq_ack(struct cti *cti)
  */
 static inline void cti_unlock(struct cti *cti)
 {
-	__raw_writel(LOCKCODE, cti->base + LOCKACCESS);
+	__raw_writel(CS_LAR_KEY, cti->base + LOCKACCESS);
 }
 
 /**
@@ -158,6 +154,6 @@ static inline void cti_unlock(struct cti *cti)
  */
 static inline void cti_lock(struct cti *cti)
 {
-	__raw_writel(~LOCKCODE, cti->base + LOCKACCESS);
+	__raw_writel(~CS_LAR_KEY, cti->base + LOCKACCESS);
 }
 #endif
arch/arm/include/asm/hardware/coresight.h +3 -3
index 7ecd793..0cf7a6b 100644
@@ -36,7 +36,7 @@
 /* CoreSight Component Registers */
 #define CSCR_CLASS	0xff4
 
-#define UNLOCK_MAGIC	0xc5acce55
+#define CS_LAR_KEY	0xc5acce55
 
 /* ETM control register, "ETM Architecture", 3.3.1 */
 #define ETMR_CTRL		0
@@ -147,11 +147,11 @@
 
 #define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0)
 #define etm_unlock(t) \
-	do { etm_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0)
+	do { etm_writel((t), CS_LAR_KEY, CSMR_LOCKACCESS); } while (0)
 
 #define etb_lock(t) do { etb_writel((t), 0, CSMR_LOCKACCESS); } while (0)
 #define etb_unlock(t) \
-	do { etb_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0)
+	do { etb_writel((t), CS_LAR_KEY, CSMR_LOCKACCESS); } while (0)
 
 #endif /* __ASM_HARDWARE_CORESIGHT_H */
 
arch/arm/kernel/hw_breakpoint.c +3 -2
index 5ff2e77..34e9375 100644
@@ -35,6 +35,7 @@
 #include <asm/hw_breakpoint.h>
 #include <asm/kdebug.h>
 #include <asm/traps.h>
+#include <asm/hardware/coresight.h>
 
 /* Breakpoint currently in use for each BRP. */
 static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]);
@@ -955,9 +956,9 @@ static void reset_ctrl_regs(void *unused)
 
 	/*
 	 * Unconditionally clear the OS lock by writing a value
-	 * other than 0xC5ACCE55 to the access register.
+	 * other than CS_LAR_KEY to the access register.
 	 */
-	ARM_DBG_WRITE(c1, c0, 4, 0);
+	ARM_DBG_WRITE(c1, c0, 4, ~CS_LAR_KEY);
 	isb();
 
 	/*
Signature · 1 line
1.8.0
#2 lore raw

PATCH 2/3 ARM: hw_breakpoint: Check function for OS Save and Restore mechanism

In reply to Will Deacon

From: Dietmar Eggemann <[email protected]>

v7 debug introduced OS Save and Restore mechanism. On a v7 debug SinglePower system, i.e a system without a separate core and debug power domain, which does not support external debug over powerdown, it is implementation defined whether OS Save and Restore is implemented.
v7.1 debug requires OS Save and Restore mechanism. v6 debug and v6.1 debug do not implement it.

A new global variable bool has_ossr is introduced and is determined in arch_hw_breakpoint_init() like debug_arch or the number of BRPs/WRPs.

The logic how to check if OS Save and Restore is supported has changed with this patch. In reset_ctrl_regs() a mask consisting of OSLM[1] (OSLSR.3) and OSLM[0] (OSLSR.0) was used to check if the system supports OS Save and Restore. In the new function core_has_os_save_restore() only OSLM[0] is used. It is not necessary to check OSLM[1] too since it is v7.1 debug specific and v7.1 debug requires OS Save and Restore and thus OS Lock.

---
 arch/arm/include/asm/hw_breakpoint.h |  3 +++
 arch/arm/kernel/hw_breakpoint.c      | 28 +++++++++++++++++++++++-----
 2 files changed, 26 insertions(+), 5 deletions(-)
arch/arm/include/asm/hw_breakpoint.h +3 -0
index 01169dd..eef55ea 100644
@@ -85,6 +85,9 @@ static inline void decode_ctrl_reg(u32 reg,
 #define ARM_DSCR_HDBGEN		(1 << 14)
 #define ARM_DSCR_MDBGEN		(1 << 15)
 
+/* OSLSR os lock model bits */
+#define ARM_OSLSR_OSLM0		(1 << 0)
+
 /* opcode2 numbers for the co-processor instructions. */
 #define ARM_OP2_BVR		4
 #define ARM_OP2_BCR		5
arch/arm/kernel/hw_breakpoint.c +23 -5
index 34e9375..201d440 100644
@@ -50,6 +50,9 @@ static int core_num_wrps;
 /* Debug architecture version. */
 static u8 debug_arch;
 
+/* Does debug architecture support OS Save and Restore? */
+static bool has_ossr;
+
 /* Maximum supported watchpoint length. */
 static u8 max_watchpoint_len;
 
@@ -904,6 +907,23 @@ static struct undef_hook debug_reg_hook = {
 	.fn		= debug_reg_trap,
 };
 
+/* Does this core support OS Save and Restore? */
+static bool core_has_os_save_restore(void)
+{
+	u32 oslsr;
+
+	switch (get_debug_arch()) {
+	case ARM_DEBUG_ARCH_V7_1:
+		return true;
+	case ARM_DEBUG_ARCH_V7_ECP14:
+		ARM_DBG_READ(c1, c1, 4, oslsr);
+		if (oslsr & ARM_OSLSR_OSLM0)
+			return true;
+	default:
+		return false;
+	}
+}
+
 static void reset_ctrl_regs(void *unused)
 {
 	int i, raw_num_brps, err = 0, cpu = smp_processor_id();
@@ -931,11 +951,7 @@ static void reset_ctrl_regs(void *unused)
 		if ((val & 0x1) == 0)
 			err = -EPERM;
 
-		/*
-		 * Check whether we implement OS save and restore.
-		 */
-		ARM_DBG_READ(c1, c1, 4, val);
-		if ((val & 0x9) == 0)
+		if (!has_ossr)
 			goto clear_vcr;
 		break;
 	case ARM_DEBUG_ARCH_V7_1:
@@ -1025,6 +1041,8 @@ static int __init arch_hw_breakpoint_init(void)
 		return 0;
 	}
 
+	has_ossr = core_has_os_save_restore();
+
 	/* Determine how many BRPs/WRPs are available. */
 	core_num_brps = get_num_brps();
 	core_num_wrps = get_num_wrps();
Signature · 1 line
1.8.0
#3 lore raw

PATCH 3/3 ARM: hw_breakpoint: Debug powerdown support for self-hosted debug

In reply to Will Deacon

From: Dietmar Eggemann <[email protected]>

This patch introduces debug powerdown support for self-hosted debug for v7 and v7.1 debug architecture for a SinglePower system, i.e. a system without a separate core and debug power domain. On a SinglePower system the OS Lock is lost over a powerdown.

If CONFIG_CPU_PM is set the new function pm_init() registers hw_breakpoint with CPU PM for a system supporting OS Save and Restore.

Receiving a CPU PM EXIT notifier indicates that a single CPU has exited a low power state. A call to reset_ctrl_regs() is hooked into the CPU PM EXIT notifier chain. This function makes sure that the sticky power-down is clear (only v7 debug), the OS Double Lock is clear (only v7.1 debug) and it clears the OS Lock for v7 debug (for a system supporting OS Save and Restore) and v7.1 debug. Furthermore, it clears any vector-catch events and all breakpoint/watchpoint control/value registers for v7 and v7.1 debug.

[will: removed redundant has_ossr check]
---
 arch/arm/kernel/hw_breakpoint.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)
arch/arm/kernel/hw_breakpoint.c +27 -1
index 201d440..5eae53e 100644
@@ -28,6 +28,7 @@
 #include <linux/perf_event.h>
 #include <linux/hw_breakpoint.h>
 #include <linux/smp.h>
+#include <linux/cpu_pm.h>
 
 #include <asm/cacheflush.h>
 #include <asm/cputype.h>
@@ -1032,6 +1033,30 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = {
 	.notifier_call = dbg_reset_notify,
 };
 
+#ifdef CONFIG_CPU_PM
+static int dbg_cpu_pm_notify(struct notifier_block *self, unsigned long action,
+			     void *v)
+{
+	if (action == CPU_PM_EXIT)
+		reset_ctrl_regs(NULL);
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata dbg_cpu_pm_nb = {
+	.notifier_call = dbg_cpu_pm_notify,
+};
+
+static void __init pm_init(void)
+{
+	cpu_pm_register_notifier(&dbg_cpu_pm_nb);
+}
+#else
+static inline void pm_init(void)
+{
+}
+#endif
+
 static int __init arch_hw_breakpoint_init(void)
 {
 	debug_arch = get_debug_arch();
@@ -1081,8 +1106,9 @@ static int __init arch_hw_breakpoint_init(void)
 	hook_ifault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP,
 			TRAP_HWBKPT, "breakpoint debug exception");
 
-	/* Register hotplug notifier. */
+	/* Register hotplug and PM notifiers. */
 	register_cpu_notifier(&dbg_reset_nb);
+	pm_init();
 	return 0;
 }
 arch_initcall(arch_hw_breakpoint_init);
Signature · 1 line
1.8.0