Re: [PATCH] save and restore etm state across core OFF modes

Alexander Shishkin
2010-01-12T17:31:25Z

On Tue, Jan 12, 2010 at 11:13:13 -0600, Nishanth Menon wrote:
> Alexander Shishkin had written, on 01/12/2010 11:04 AM, the following:
> >This prevents ETM stalls whenever core enters OFF mode. Original patch
> >author is Richard Woodruff <r-woodruff2@ti.com>.
> >
> >This patch applies on top of pm branch.
> >
> >Signed-off-by: Alexander Shishkin <virtuoso@slind.org>
> >CC: Richard Woodruff <r-woodruff2@ti.com>
>
> thanks..
>
> >---
> > arch/arm/mach-omap2/Kconfig | 9 ++
> > arch/arm/mach-omap2/control.c | 2 +-
> > arch/arm/mach-omap2/sleep34xx.S | 133 +++++++++++++++++++++++++++++
> > arch/arm/plat-omap/include/plat/control.h | 2 +-
> > 4 files changed, 144 insertions(+), 2 deletions(-)
> >
> >diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
> >index 606bf04..02ea136 100644
> >--- a/arch/arm/mach-omap2/Kconfig
> >+++ b/arch/arm/mach-omap2/Kconfig
> >@@ -153,6 +153,15 @@ config MACH_OMAP_4430SDP
> > bool "OMAP 4430 SDP board"
> > depends on ARCH_OMAP4
> >+config ENABLE_OFF_MODE_JTAG_ETM_DEBUG
> >+ bool "Enable hardware emulation context save and restore"
> >+ depends on ARCH_OMAP3
> >+ default y
> >+ help
> >+ This option enables JTAG & ETM debugging across power states.
> >+ With out this option emulation features are reset across OFF
> >+ mode state changes.
> >+
> > config OMAP3_EMU
> > bool "OMAP3 debugging peripherals"
> > depends on ARCH_OMAP3
> >diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
> >index cdd1f35..78f4634 100644
> >--- a/arch/arm/mach-omap2/control.c
> >+++ b/arch/arm/mach-omap2/control.c
> >@@ -93,7 +93,7 @@ void *omap3_secure_ram_storage;
> > * The address is stored in scratchpad, so that it can be used
> > * during the restore path.
> > */
> >-u32 omap3_arm_context[128];
> >+u32 omap3_arm_context[256];
> > struct omap3_control_regs {
> > u32 sysconfig;
> >diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
> >index 69521be..0a5ec86 100644
> >--- a/arch/arm/mach-omap2/sleep34xx.S
> >+++ b/arch/arm/mach-omap2/sleep34xx.S
> >@@ -59,6 +59,13 @@
> > #define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
> > #define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
> >+#define CORTEX_CORSIGHT_OFF (0x00011000)
> >+#define CORTEX_EMU_DEBUG_V (L4_EMU_34XX_VIRT + CORTEX_CORSIGHT_OFF)
> >+#define CORTEX_EMU_DEBUG_P (L4_EMU_34XX_PHYS + CORTEX_CORSIGHT_OFF)
> >+#define ETM_CORSIGHT_OFF (0x00010000)
> >+#define CORTEX_EMU_ETM_V (L4_EMU_34XX_VIRT + ETM_CORSIGHT_OFF)
> >+#define CORTEX_EMU_ETM_P (L4_EMU_34XX_PHYS + ETM_CORSIGHT_OFF)
> >+
> > .text
> > /* Function to aquire the semaphore in scratchpad */
> > ENTRY(lock_scratchpad_sem)
> >@@ -226,6 +233,18 @@ loop:
> > nop
> > bl wait_sdrc_ok
> >+#ifdef CONFIG_ENABLE_OFF_MODE_JTAG_ETM_DEBUG
> >+ /*
> >+ * Restore Coresight debug registers
> >+ */
> >+ ldr r6, debug_vbase /* base Vaddr of CortexA8-Debug */
> >+ ldr r4, debug_xlar_key /* get lock key for OSLAR */
> >+ bl unlock_debug /* remove global lock if set */
> >+ ldr r6, etm_vbase /* base Vaddr of ETM */
> >+ bl unlock_debug /* remove global lock if set */
> >+ str r6, [r6, #0x300] /* clear OSLAR lock using non-key */
> >+#endif
> >+
> > ldmfd sp!, {r0-r12, pc} @ restore regs and return
> > restore_es3:
> > /*b restore_es3*/ @ Enable to debug restore code
> >@@ -385,6 +404,50 @@ logic_l1_restore:
> > /*normal memory remap register */
> > MCR p15, 0, r5, c10, c2, 1
> >+#ifdef CONFIG_ENABLE_OFF_MODE_JTAG_ETM_DEBUG
> >+ /*
> >+ * Restore Coresight debug registers
> >+ */
> >+ ldr r6, debug_pbase /* base paddr of CortexA8-Debug */
> >+ ldr r4, debug_xlar_key /* get lock key for OSLAR */
> >+ bl unlock_debug /* remove global lock if set */
> >+ str r4, [r6, #0x300] /* reset-pointer (already locked) */
> >+ ldr r4, [r6, #0x308] /* dummy read */
> >+ ldr r4, [r3], #4 /* load save size */
> >+ cmp r4, #0 /* check for zero */
> >+debug_restore:
> >+ ittt ne /* t2/compat if-then block */
> >+ ldrne r5, [r3], #4 /* get save value */
> >+ strne r5, [r6,#0x308] /* restore cp14 value */
> >+ subnes r4, r4, #1 /* decrement loop */
> >+ bne debug_restore /* loop till done */
> >+ str r5, [r6, #0x300] /* clear lock */
> >+ /*
> >+ * Restore CoreSight ETM registers
> >+ */
> >+ ldr r6, etm_pbase /* base paddr of ETM */
> >+ ldr r4, debug_xlar_key /* get lock key for OSLAR */
> >+ bl unlock_debug /* remove global lock if set */
> >+ ldr r4, [r3], #4 /* load save size */
> >+ cmp r4, #0 /* check for zero */
> >+ beq etm_skip
> >+ sub r4, #1
> >+ ldr r7, [r3], #4 /* get/store first value to r7 */
> >+ mov r5, #0x3 /* enable programming in ETMCR*/
> >+ lsl r5, r5, #10
> >+ orr r5, r7
> >+ str r5,[r6], #4
> >+ cmp r4, #0 /* check for zero */
> >+etm_restore:
> >+ ldrne r5, [r3], #4 /* get save value */
> >+ strne r5, [r6], #4 /* restore cp14 value */
> >+ subnes r4, r4, #1 /* decrement loop */
> >+ bne etm_restore /* loop till done */
> >+ ldr r6, etm_pbase /* base paddr of ETM */
> >+ str r7,[r6] /* dis-able programming in ETMCR */
> >+etm_skip:
> >+#endif
> >+
> > /* Restore cpsr */
> > ldmia r3!,{r4} /*load CPSR from SDRAM*/
> > msr cpsr, r4 /*store cpsr */
> >@@ -506,6 +569,39 @@ l1_logic_lost:
> > mrc p15, 0, r5, c10, c2, 1
> > stmia r8!,{r4-r5}
> >+#ifdef CONFIG_ENABLE_OFF_MODE_JTAG_ETM_DEBUG
> >+ /*
> >+ * Save Coresight debug registers
> >+ */
> >+ ldr r6, debug_vbase /* base vaddr of CortexA8-Debug */
> >+ ldr r4, debug_xlar_key /* get lock key for OSLAR */
> >+ bl unlock_debug /* force global unlock */
> >+ str r4, [r6, #0x300] /* lock debug access */
> >+ ldr r4, [r6, #0x308] /* OSSRR returns size on first read */
> >+ str r4, [r8], #4 /* push item to save area */
> >+ cmp r4, #0 /* zero check */
> >+debug_save:
> >+ ittt ne /* thumb 2 compat if-then block */
> >+ ldrne r5, [r6, #0x308] /* get reg value */
> >+ strne r5, [r8], #4 /* push item to save area */
> >+ subnes r4, r4, #1 /* decrement size */
> >+ bne debug_save /* loop till done */
> >+ /*
> >+ * Save etm registers
> >+ */
> >+ ldr r6, etm_vbase /* base vaddr of CortexA8-Debug */
> >+ ldr r4, debug_xlar_key /* get lock key for OSLAR */
> >+ bl unlock_debug /* force global unlock */
> >+ mov r4, #128 /* OSSRR returns size on first read */
> >+ str r4, [r8], #4 /* push item to save area */
> >+ cmp r4, #0 /* zero check */
> >+etm_save:
> >+ ldrne r5, [r6], #4 /* get reg value */
> >+ strne r5, [r8], #4 /* push item to save area */
> >+ subnes r4, r4, #1 /* decrement size */
> >+ bne etm_save /* loop till done */
> >+#endif
> >+
> > /* Store current cpsr*/
> > mrs r2, cpsr
> > stmia r8!, {r2}
> >@@ -520,6 +616,7 @@ clean_caches:
> > cmp r9, #1 /* Check whether L2 inval is required or not*/
> > bne skip_l2_inval
> > clean_l2:
> >+#if 0
>
> my aversion to #if 0 kicks in here :(.. do we have an alternative
> like using the CONFIG_ENABLE_OFF_MODE_JTAG_ETM_DEBUG or something
> else?

Fair enough. I could replace it with "#if !defined(...)" as the first
thing that comes to mind. This way it will only take disabling the
config option to catch any possible regressions in between. Does this
sound reasonable?

Regards,
--
Alex