Skip to contentSkip to conversation

OMAP: use fncpy to copy the PM code functions to SRAM

PATCH Superseded jean.pihet at newoldbits.com 4 participants 9 messages Jan 18, 2011 – Jan 25, 2011

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

PATCH v2 1/1 OMAP: use fncpy to copy the PM code functions to SRAM

From: Jean Pihet <[email protected]>

The new fncpy API is better suited for copying some code to SRAM at runtime. This patch changes the ad-hoc code to the more generic fncpy API.

Tested OK on OMAP3 in low power modes (RET/OFF) using omap2plus_defconfig with !CONFIG_THUMB2_KERNEL. Compile tested on OMAP1/2 using omap1_defconfig.

---
 arch/arm/mach-omap1/pm.h               |    6 +++---
 arch/arm/mach-omap1/sleep.S            |    3 +++
 arch/arm/mach-omap1/sram.S             |    1 +
 arch/arm/mach-omap2/pm.h               |    2 +-
 arch/arm/mach-omap2/sleep24xx.S        |    2 ++
 arch/arm/mach-omap2/sleep34xx.S        |    2 ++
 arch/arm/mach-omap2/sram242x.S         |    3 +++
 arch/arm/mach-omap2/sram243x.S         |    3 +++
 arch/arm/mach-omap2/sram34xx.S         |    1 +
 arch/arm/plat-omap/include/plat/sram.h |   14 +++++++++++++-
 arch/arm/plat-omap/sram.c              |   14 +++++++++-----
 11 files changed, 41 insertions(+), 10 deletions(-)
arch/arm/mach-omap1/pm.h +3 -3
index 56a6479..cd926dc 100644
@@ -123,9 +123,9 @@ extern void allow_idle_sleep(void);
 extern void omap1_pm_idle(void);
 extern void omap1_pm_suspend(void);
 
-extern void omap7xx_cpu_suspend(unsigned short, unsigned short);
-extern void omap1510_cpu_suspend(unsigned short, unsigned short);
-extern void omap1610_cpu_suspend(unsigned short, unsigned short);
+extern void omap7xx_cpu_suspend(unsigned long, unsigned long);
+extern void omap1510_cpu_suspend(unsigned long, unsigned long);
+extern void omap1610_cpu_suspend(unsigned long, unsigned long);
 extern void omap7xx_idle_loop_suspend(void);
 extern void omap1510_idle_loop_suspend(void);
 extern void omap1610_idle_loop_suspend(void);
arch/arm/mach-omap1/sleep.S +3 -0
index ef771ce..c875bdc 100644
@@ -58,6 +58,7 @@
  */
 
 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	.align	3
 ENTRY(omap7xx_cpu_suspend)
 
 	@ save registers on stack
@@ -137,6 +138,7 @@ ENTRY(omap7xx_cpu_suspend_sz)
 #endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */
 
 #ifdef CONFIG_ARCH_OMAP15XX
+	.align	3
 ENTRY(omap1510_cpu_suspend)
 
 	@ save registers on stack
@@ -211,6 +213,7 @@ ENTRY(omap1510_cpu_suspend_sz)
 #endif /* CONFIG_ARCH_OMAP15XX */
 
 #if defined(CONFIG_ARCH_OMAP16XX)
+	.align	3
 ENTRY(omap1610_cpu_suspend)
 
 	@ save registers on stack
arch/arm/mach-omap1/sram.S +1 -0
index 7724e52..692587d 100644
@@ -18,6 +18,7 @@
 /*
  * Reprograms ULPD and CKCTL.
  */
+	.align	3
 ENTRY(omap1_sram_reprogram_clock)
 	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
 
arch/arm/mach-omap2/pm.h +1 -1
index 1c1b0ab..39580e6 100644
@@ -92,7 +92,7 @@ extern void omap24xx_idle_loop_suspend(void);
 extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
 					void __iomem *sdrc_power);
 extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
-extern void save_secure_ram_context(u32 *addr);
+extern int save_secure_ram_context(u32 *addr);
 extern void omap3_save_scratchpad_contents(void);
 
 extern unsigned int omap24xx_idle_loop_suspend_sz;
arch/arm/mach-omap2/sleep24xx.S +2 -0
index c7780cc..b5071a4 100644
@@ -47,6 +47,7 @@
  * Note: This code get's copied to internal SRAM at boot. When the OMAP
  *	 wakes up it continues execution at the point it went to sleep.
  */
+	.align	3
 ENTRY(omap24xx_idle_loop_suspend)
 	stmfd	sp!, {r0, lr}		@ save registers on stack
 	mov	r0, #0			@ clear for mcr setup
@@ -82,6 +83,7 @@ ENTRY(omap24xx_idle_loop_suspend_sz)
  * The DLL load value is not kept in RETENTION or OFF.	It needs to be restored
  * at wake
  */
+	.align	3
 ENTRY(omap24xx_cpu_suspend)
 	stmfd	sp!, {r0 - r12, lr}	@ save registers on stack
 	mov	r3, #0x0		@ clear for mcr call
arch/arm/mach-omap2/sleep34xx.S +2 -0
index 98d8232..951a0be 100644
@@ -118,6 +118,7 @@ ENTRY(enable_omap3630_toggle_l2_on_restore)
 
 	.text
 /* Function to call rom code to save secure ram context */
+	.align	3
 ENTRY(save_secure_ram_context)
 	stmfd	sp!, {r1-r12, lr}	@ save registers on stack
 	adr	r3, api_params		@ r3 points to parameters
@@ -169,6 +170,7 @@ ENTRY(save_secure_ram_context_sz)
  *   depending on the low power mode (non-OFF vs OFF modes),
  *   cf. 'Resume path for xxx mode' comments.
  */
+	.align	3
 ENTRY(omap34xx_cpu_suspend)
 	stmfd	sp!, {r0-r12, lr}	@ save registers on stack
 
arch/arm/mach-omap2/sram242x.S +3 -0
index 055310c..ff9b9db 100644
@@ -39,6 +39,7 @@
 
 	.text
 
+	.align	3
 ENTRY(omap242x_sram_ddr_init)
 	stmfd	sp!, {r0 - r12, lr}	@ save registers on stack
 
@@ -143,6 +144,7 @@ ENTRY(omap242x_sram_ddr_init_sz)
  * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
  * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
  */
+	.align	3
 ENTRY(omap242x_sram_reprogram_sdrc)
 	stmfd	sp!, {r0 - r10, lr}	@ save registers on stack
 	mov	r3, #0x0		@ clear for mrc call
@@ -238,6 +240,7 @@ ENTRY(omap242x_sram_reprogram_sdrc_sz)
 /*
  * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
  */
+	.align	3
 ENTRY(omap242x_sram_set_prcm)
 	stmfd	sp!, {r0-r12, lr}	@ regs to stack
 	adr	r4, pbegin		@ addr of preload start
arch/arm/mach-omap2/sram243x.S +3 -0
index f900758..7673020 100644
@@ -39,6 +39,7 @@
 
 	.text
 
+	.align	3
 ENTRY(omap243x_sram_ddr_init)
 	stmfd	sp!, {r0 - r12, lr}	@ save registers on stack
 
@@ -143,6 +144,7 @@ ENTRY(omap243x_sram_ddr_init_sz)
  * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
  * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
  */
+	.align	3
 ENTRY(omap243x_sram_reprogram_sdrc)
 	stmfd	sp!, {r0 - r10, lr}	@ save registers on stack
 	mov	r3, #0x0		@ clear for mrc call
@@ -238,6 +240,7 @@ ENTRY(omap243x_sram_reprogram_sdrc_sz)
 /*
  * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
  */
+	.align	3
 ENTRY(omap243x_sram_set_prcm)
 	stmfd	sp!, {r0-r12, lr}	@ regs to stack
 	adr	r4, pbegin		@ addr of preload start
arch/arm/mach-omap2/sram34xx.S +1 -0
index 7f893a2..25011ca 100644
@@ -111,6 +111,7 @@
  * since it will cause the ARM MMU to attempt to walk the page tables.
  * These crashes may be intermittent.
  */
+	.align	3
 ENTRY(omap3_sram_configure_core_dpll)
 	stmfd	sp!, {r1-r12, lr}	@ store regs to stack
 
arch/arm/plat-omap/include/plat/sram.h +13 -1
index 9967d5e..d673f2c 100644
@@ -12,7 +12,19 @@
 #define __ARCH_ARM_OMAP_SRAM_H
 
 #ifndef __ASSEMBLY__
-extern void * omap_sram_push(void * start, unsigned long size);
+#include <asm/fncpy.h>
+
+extern void *omap_sram_push_address(unsigned long size);
+
+/* Macro to push a function to the internal SRAM, using the fncpy API */
+#define omap_sram_push(funcp, size) ({				\
+	typeof(&funcp) _res = NULL;				\
+	void *_sram_address = omap_sram_push_address(size);	\
+	if (_sram_address)					\
+		_res = fncpy(_sram_address, &funcp, size);	\
+	_res;							\
+})
+
 extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
 
 extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
arch/arm/plat-omap/sram.c +9 -5
index e26e504..68fcc7d 100644
@@ -242,7 +242,14 @@ static void __init omap_map_sram(void)
 	       omap_sram_size - SRAM_BOOTLOADER_SZ);
 }
 
-void * omap_sram_push(void * start, unsigned long size)
+/*
+ * Memory allocator for SRAM: calculates the new ceiling address
+ * for pushing a function using the fncpy API.
+ *
+ * Note that fncpy requires the returned address to be aligned
+ * to an 8-byte boundary.
+ */
+void *omap_sram_push_address(unsigned long size)
 {
 	if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
 		printk(KERN_ERR "Not enough space in SRAM\n");
@@ -250,10 +257,7 @@ void * omap_sram_push(void * start, unsigned long size)
 	}
 
 	omap_sram_ceil -= size;
-	omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *));
-	memcpy((void *)omap_sram_ceil, start, size);
-	flush_icache_range((unsigned long)omap_sram_ceil,
-		(unsigned long)(omap_sram_ceil + size));
+	omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, FNCPY_ALIGN);
 
 	return (void *)omap_sram_ceil;
 }
Signature · 1 line
1.7.2.3
#1 lore raw

PATCH v2 1/1 OMAP: use fncpy to copy the PM code functions to SRAM

Quoted 11 lines · jean.pihet at newoldbits.com

From: Jean Pihet <[email protected]>

The new fncpy API is better suited for copying some code to SRAM at runtime. This patch changes the ad-hoc code to the more generic fncpy API.

Tested OK on OMAP3 in low power modes (RET/OFF) using omap2plus_defconfig with !CONFIG_THUMB2_KERNEL. Compile tested on OMAP1/2 using omap1_defconfig.

Boot tested on OMAP1 & OMAP2 as well. Note that neither OMAP1 or OMAP2 has had working suspend/resume for a long time now, so I did not test suspend/resume.

Kevin

Quoted 249 lines
---
 arch/arm/mach-omap1/pm.h               |    6 +++---
 arch/arm/mach-omap1/sleep.S            |    3 +++
 arch/arm/mach-omap1/sram.S             |    1 +
 arch/arm/mach-omap2/pm.h               |    2 +-
 arch/arm/mach-omap2/sleep24xx.S        |    2 ++
 arch/arm/mach-omap2/sleep34xx.S        |    2 ++
 arch/arm/mach-omap2/sram242x.S         |    3 +++
 arch/arm/mach-omap2/sram243x.S         |    3 +++
 arch/arm/mach-omap2/sram34xx.S         |    1 +
 arch/arm/plat-omap/include/plat/sram.h |   14 +++++++++++++-
 arch/arm/plat-omap/sram.c              |   14 +++++++++-----
 11 files changed, 41 insertions(+), 10 deletions(-)
arch/arm/mach-omap1/pm.h +3 -3
index 56a6479..cd926dc 100644
@@ -123,9 +123,9 @@ extern void allow_idle_sleep(void);
 extern void omap1_pm_idle(void);
 extern void omap1_pm_suspend(void);
 
-extern void omap7xx_cpu_suspend(unsigned short, unsigned short);
-extern void omap1510_cpu_suspend(unsigned short, unsigned short);
-extern void omap1610_cpu_suspend(unsigned short, unsigned short);
+extern void omap7xx_cpu_suspend(unsigned long, unsigned long);
+extern void omap1510_cpu_suspend(unsigned long, unsigned long);
+extern void omap1610_cpu_suspend(unsigned long, unsigned long);
 extern void omap7xx_idle_loop_suspend(void);
 extern void omap1510_idle_loop_suspend(void);
 extern void omap1610_idle_loop_suspend(void);
arch/arm/mach-omap1/sleep.S +3 -0
index ef771ce..c875bdc 100644
@@ -58,6 +58,7 @@
  */
 
 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	.align	3
 ENTRY(omap7xx_cpu_suspend)
 
 	@ save registers on stack
@@ -137,6 +138,7 @@ ENTRY(omap7xx_cpu_suspend_sz)
 #endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */
 
 #ifdef CONFIG_ARCH_OMAP15XX
+	.align	3
 ENTRY(omap1510_cpu_suspend)
 
 	@ save registers on stack
@@ -211,6 +213,7 @@ ENTRY(omap1510_cpu_suspend_sz)
 #endif /* CONFIG_ARCH_OMAP15XX */
 
 #if defined(CONFIG_ARCH_OMAP16XX)
+	.align	3
 ENTRY(omap1610_cpu_suspend)
 
 	@ save registers on stack
arch/arm/mach-omap1/sram.S +1 -0
index 7724e52..692587d 100644
@@ -18,6 +18,7 @@
 /*
  * Reprograms ULPD and CKCTL.
  */
+	.align	3
 ENTRY(omap1_sram_reprogram_clock)
 	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
 
arch/arm/mach-omap2/pm.h +1 -1
index 1c1b0ab..39580e6 100644
@@ -92,7 +92,7 @@ extern void omap24xx_idle_loop_suspend(void);
 extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
 					void __iomem *sdrc_power);
 extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
-extern void save_secure_ram_context(u32 *addr);
+extern int save_secure_ram_context(u32 *addr);
 extern void omap3_save_scratchpad_contents(void);
 
 extern unsigned int omap24xx_idle_loop_suspend_sz;
arch/arm/mach-omap2/sleep24xx.S +2 -0
index c7780cc..b5071a4 100644
@@ -47,6 +47,7 @@
  * Note: This code get's copied to internal SRAM at boot. When the OMAP
  *	 wakes up it continues execution at the point it went to sleep.
  */
+	.align	3
 ENTRY(omap24xx_idle_loop_suspend)
 	stmfd	sp!, {r0, lr}		@ save registers on stack
 	mov	r0, #0			@ clear for mcr setup
@@ -82,6 +83,7 @@ ENTRY(omap24xx_idle_loop_suspend_sz)
  * The DLL load value is not kept in RETENTION or OFF.	It needs to be restored
  * at wake
  */
+	.align	3
 ENTRY(omap24xx_cpu_suspend)
 	stmfd	sp!, {r0 - r12, lr}	@ save registers on stack
 	mov	r3, #0x0		@ clear for mcr call
arch/arm/mach-omap2/sleep34xx.S +2 -0
index 98d8232..951a0be 100644
@@ -118,6 +118,7 @@ ENTRY(enable_omap3630_toggle_l2_on_restore)
 
 	.text
 /* Function to call rom code to save secure ram context */
+	.align	3
 ENTRY(save_secure_ram_context)
 	stmfd	sp!, {r1-r12, lr}	@ save registers on stack
 	adr	r3, api_params		@ r3 points to parameters
@@ -169,6 +170,7 @@ ENTRY(save_secure_ram_context_sz)
  *   depending on the low power mode (non-OFF vs OFF modes),
  *   cf. 'Resume path for xxx mode' comments.
  */
+	.align	3
 ENTRY(omap34xx_cpu_suspend)
 	stmfd	sp!, {r0-r12, lr}	@ save registers on stack
 
arch/arm/mach-omap2/sram242x.S +3 -0
index 055310c..ff9b9db 100644
@@ -39,6 +39,7 @@
 
 	.text
 
+	.align	3
 ENTRY(omap242x_sram_ddr_init)
 	stmfd	sp!, {r0 - r12, lr}	@ save registers on stack
 
@@ -143,6 +144,7 @@ ENTRY(omap242x_sram_ddr_init_sz)
  * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
  * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
  */
+	.align	3
 ENTRY(omap242x_sram_reprogram_sdrc)
 	stmfd	sp!, {r0 - r10, lr}	@ save registers on stack
 	mov	r3, #0x0		@ clear for mrc call
@@ -238,6 +240,7 @@ ENTRY(omap242x_sram_reprogram_sdrc_sz)
 /*
  * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
  */
+	.align	3
 ENTRY(omap242x_sram_set_prcm)
 	stmfd	sp!, {r0-r12, lr}	@ regs to stack
 	adr	r4, pbegin		@ addr of preload start
arch/arm/mach-omap2/sram243x.S +3 -0
index f900758..7673020 100644
@@ -39,6 +39,7 @@
 
 	.text
 
+	.align	3
 ENTRY(omap243x_sram_ddr_init)
 	stmfd	sp!, {r0 - r12, lr}	@ save registers on stack
 
@@ -143,6 +144,7 @@ ENTRY(omap243x_sram_ddr_init_sz)
  * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
  * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
  */
+	.align	3
 ENTRY(omap243x_sram_reprogram_sdrc)
 	stmfd	sp!, {r0 - r10, lr}	@ save registers on stack
 	mov	r3, #0x0		@ clear for mrc call
@@ -238,6 +240,7 @@ ENTRY(omap243x_sram_reprogram_sdrc_sz)
 /*
  * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
  */
+	.align	3
 ENTRY(omap243x_sram_set_prcm)
 	stmfd	sp!, {r0-r12, lr}	@ regs to stack
 	adr	r4, pbegin		@ addr of preload start
arch/arm/mach-omap2/sram34xx.S +1 -0
index 7f893a2..25011ca 100644
@@ -111,6 +111,7 @@
  * since it will cause the ARM MMU to attempt to walk the page tables.
  * These crashes may be intermittent.
  */
+	.align	3
 ENTRY(omap3_sram_configure_core_dpll)
 	stmfd	sp!, {r1-r12, lr}	@ store regs to stack
 
arch/arm/plat-omap/include/plat/sram.h +13 -1
index 9967d5e..d673f2c 100644
@@ -12,7 +12,19 @@
 #define __ARCH_ARM_OMAP_SRAM_H
 
 #ifndef __ASSEMBLY__
-extern void * omap_sram_push(void * start, unsigned long size);
+#include <asm/fncpy.h>
+
+extern void *omap_sram_push_address(unsigned long size);
+
+/* Macro to push a function to the internal SRAM, using the fncpy API */
+#define omap_sram_push(funcp, size) ({				\
+	typeof(&funcp) _res = NULL;				\
+	void *_sram_address = omap_sram_push_address(size);	\
+	if (_sram_address)					\
+		_res = fncpy(_sram_address, &funcp, size);	\
+	_res;							\
+})
+
 extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
 
 extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
arch/arm/plat-omap/sram.c +9 -5
index e26e504..68fcc7d 100644
@@ -242,7 +242,14 @@ static void __init omap_map_sram(void)
 	       omap_sram_size - SRAM_BOOTLOADER_SZ);
 }
 
-void * omap_sram_push(void * start, unsigned long size)
+/*
+ * Memory allocator for SRAM: calculates the new ceiling address
+ * for pushing a function using the fncpy API.
+ *
+ * Note that fncpy requires the returned address to be aligned
+ * to an 8-byte boundary.
+ */
+void *omap_sram_push_address(unsigned long size)
 {
 	if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
 		printk(KERN_ERR "Not enough space in SRAM\n");
@@ -250,10 +257,7 @@ void * omap_sram_push(void * start, unsigned long size)
 	}
 
 	omap_sram_ceil -= size;
-	omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *));
-	memcpy((void *)omap_sram_ceil, start, size);
-	flush_icache_range((unsigned long)omap_sram_ceil,
-		(unsigned long)(omap_sram_ceil + size));
+	omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, FNCPY_ALIGN);
 
 	return (void *)omap_sram_ceil;
 }
#2 lore raw

PATCH v2 1/1 OMAP: use fncpy to copy the PM code functions to SRAM

Quoted 12 lines · Kevin Hilman
Quoted 10 lines · jean.pihet at newoldbits.com

From: Jean Pihet <[email protected]>

The new fncpy API is better suited for copying some code to SRAM at runtime. This patch changes the ad-hoc code to the more generic fncpy API.

Tested OK on OMAP3 in low power modes (RET/OFF) using omap2plus_defconfig with !CONFIG_THUMB2_KERNEL. Compile tested on OMAP1/2 using omap1_defconfig.

Quoted 7 lines
Quoted 1 line

Boot tested on OMAP1 & OMAP2 as well. Note that neither OMAP1 or OMAP2 has had working suspend/resume for a long time now, so I did not test suspend/resume.

For OMAP2:

to test a little more on OMAP2, I just removed the WFI from the low-level code and tested suspend that way. That's enough to be sure the copied code is copied and executed.

Worked fine on OMAP2420/n810.

For OMAP1, this didn't work and would require more serious hacking on the OMAP1 suspend path, which I currently have no plans to do.

Kevin

maintainer
#3 lore raw

PATCH v2 1/1 OMAP: use fncpy to copy the PM code functions to SRAM

Quoted 26 lines · Kevin Hilman
Quoted 12 lines · Kevin Hilman
Quoted 10 lines · jean.pihet at newoldbits.com

From: Jean Pihet <[email protected]>

The new fncpy API is better suited for copying some code to SRAM at runtime. This patch changes the ad-hoc code to the more generic fncpy API.

Tested OK on OMAP3 in low power modes (RET/OFF) using omap2plus_defconfig with !CONFIG_THUMB2_KERNEL. Compile tested on OMAP1/2 using omap1_defconfig.

Quoted 7 lines
Quoted 1 line

Boot tested on OMAP1 & OMAP2 as well. Note that neither OMAP1 or OMAP2 has had working suspend/resume for a long time now, so I did not test suspend/resume.

For OMAP2:

Quoted 8 lines

to test a little more on OMAP2, I just removed the WFI from the low-level code and tested suspend that way. That's enough to be sure the copied code is copied and executed.

Worked fine on OMAP2420/n810.

For OMAP1, this didn't work and would require more serious hacking on the OMAP1 suspend path, which I currently have no plans to do.

Boots fine on osk5912 and n800 too:

author
#4 lore raw

PATCH v2 1/1 OMAP: use fncpy to copy the PM code functions to SRAM

Quoted 31 lines · Tony Lindgren
Quoted 30 lines · Kevin Hilman
Quoted 12 lines · Kevin Hilman
Quoted 10 lines · jean.pihet at newoldbits.com

From: Jean Pihet <[email protected]>

The new fncpy API is better suited for copying some code to SRAM at runtime. This patch changes the ad-hoc code to the more generic fncpy API.

Tested OK on OMAP3 in low power modes (RET/OFF) using omap2plus_defconfig with !CONFIG_THUMB2_KERNEL. Compile tested on OMAP1/2 using omap1_defconfig.

Quoted 7 lines
Quoted 1 line

Boot tested on OMAP1 & OMAP2 as well. ?Note that neither OMAP1 or OMAP2 has had working suspend/resume for a long time now, so I did not test suspend/resume.

For OMAP2:

to test a little more on OMAP2, I just removed the WFI from the low-level code and tested suspend that way. ?That's enough to be sure the copied code is copied and executed.

Quoted 9 lines
Quoted 4 lines

Worked fine on OMAP2420/n810.

For OMAP1, this didn't work and would require more serious hacking on the OMAP1 suspend path, which I currently have no plans to do.

Boots fine on osk5912 and n800 too:

Thanks for testing!

Regards,
Jean

#5 lore raw

PATCH v2 1/1 OMAP: use fncpy to copy the PM code functions to SRAM

In reply to jean.pihet at newoldbits.com

Hi there, I just spotted a couple of things merging your patch...

Quoted 211 lines · On Tue, Jan 18, 2011 at 12:02 PM, <[email protected]> wrote:

From: Jean Pihet <[email protected]>

The new fncpy API is better suited for copying some code to SRAM at runtime. This patch changes the ad-hoc code to the more generic fncpy API.

Tested OK on OMAP3 in low power modes (RET/OFF) using omap2plus_defconfig with !CONFIG_THUMB2_KERNEL. Compile tested on OMAP1/2 using omap1_defconfig.

---

?arch/arm/mach-omap1/pm.h ? ? ? ? ? ? ? | ? ?6 +++---
?arch/arm/mach-omap1/sleep.S ? ? ? ? ? ?| ? ?3 +++
?arch/arm/mach-omap1/sram.S ? ? ? ? ? ? | ? ?1 +
?arch/arm/mach-omap2/pm.h ? ? ? ? ? ? ? | ? ?2 +-
?arch/arm/mach-omap2/sleep24xx.S ? ? ? ?| ? ?2 ++
?arch/arm/mach-omap2/sleep34xx.S ? ? ? ?| ? ?2 ++
?arch/arm/mach-omap2/sram242x.S ? ? ? ? | ? ?3 +++
?arch/arm/mach-omap2/sram243x.S ? ? ? ? | ? ?3 +++
?arch/arm/mach-omap2/sram34xx.S ? ? ? ? | ? ?1 +
?arch/arm/plat-omap/include/plat/sram.h | ? 14 +++++++++++++-
?arch/arm/plat-omap/sram.c ? ? ? ? ? ? ?| ? 14 +++++++++-----

?11 files changed, 41 insertions(+), 10 deletions(-)

arch/arm/mach-omap1/pm.h +3 -3
index 56a6479..cd926dc 100644
@@ -123,9 +123,9 @@ extern void allow_idle_sleep(void);
 ?extern void omap1_pm_idle(void);
 ?extern void omap1_pm_suspend(void);
 
-extern void omap7xx_cpu_suspend(unsigned short, unsigned short);
-extern void omap1510_cpu_suspend(unsigned short, unsigned short);
-extern void omap1610_cpu_suspend(unsigned short, unsigned short);
+extern void omap7xx_cpu_suspend(unsigned long, unsigned long);
+extern void omap1510_cpu_suspend(unsigned long, unsigned long);
+extern void omap1610_cpu_suspend(unsigned long, unsigned long);
 ?extern void omap7xx_idle_loop_suspend(void);
 ?extern void omap1510_idle_loop_suspend(void);
 ?extern void omap1610_idle_loop_suspend(void);
arch/arm/mach-omap1/sleep.S +0 -0
index ef771ce..c875bdc 100644
@@ -58,6 +58,7 @@

?*/

?#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ ? ? ? .align ?3
?ENTRY(omap7xx_cpu_suspend)

? ? ? ?@ save registers on stack

arch/arm/mach-omap1/sleep.S +0 -0
@@ -137,6 +138,7 @@ ENTRY(omap7xx_cpu_suspend_sz)

?#endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */

?#ifdef CONFIG_ARCH_OMAP15XX
+ ? ? ? .align ?3
?ENTRY(omap1510_cpu_suspend)

? ? ? ?@ save registers on stack

arch/arm/mach-omap1/sleep.S +0 -0
@@ -211,6 +213,7 @@ ENTRY(omap1510_cpu_suspend_sz)

?#endif /* CONFIG_ARCH_OMAP15XX */

?#if defined(CONFIG_ARCH_OMAP16XX)
+ ? ? ? .align ?3
?ENTRY(omap1610_cpu_suspend)

? ? ? ?@ save registers on stack

arch/arm/mach-omap1/sram.S +0 -0
index 7724e52..692587d 100644
@@ -18,6 +18,7 @@

?/*
?* Reprograms ULPD and CKCTL.
?*/
+ ? ? ? .align ?3
?ENTRY(omap1_sram_reprogram_clock)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? ? ? ? ? @ save registers on stack

arch/arm/mach-omap2/pm.h +1 -1
index 1c1b0ab..39580e6 100644
@@ -92,7 +92,7 @@ extern void omap24xx_idle_loop_suspend(void);
 ?extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?void __iomem *sdrc_power);
 ?extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
-extern void save_secure_ram_context(u32 *addr);
+extern int save_secure_ram_context(u32 *addr);
 ?extern void omap3_save_scratchpad_contents(void);
 
 ?extern unsigned int omap24xx_idle_loop_suspend_sz;
arch/arm/mach-omap2/sleep24xx.S +0 -0
index c7780cc..b5071a4 100644
@@ -47,6 +47,7 @@

?* Note: This code get's copied to internal SRAM at boot. When the OMAP ?* ? ? ?wakes up it continues execution at the point it went to sleep. ?*/
+ ? ? ? .align ?3
?ENTRY(omap24xx_idle_loop_suspend)
? ? ? ?stmfd ? sp!, {r0, lr} ? ? ? ? ? @ save registers on stack ? ? ? ?mov ? ? r0, #0 ? ? ? ? ? ? ? ? ?@ clear for mcr setup

arch/arm/mach-omap2/sleep24xx.S +0 -0
@@ -82,6 +83,7 @@ ENTRY(omap24xx_idle_loop_suspend_sz)

?* The DLL load value is not kept in RETENTION or OFF. It needs to be restored ?* at wake
?*/
+ ? ? ? .align ?3
?ENTRY(omap24xx_cpu_suspend)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? @ save registers on stack ? ? ? ?mov ? ? r3, #0x0 ? ? ? ? ? ? ? ?@ clear for mcr call

arch/arm/mach-omap2/sleep34xx.S +0 -0
index 98d8232..951a0be 100644
@@ -118,6 +118,7 @@ ENTRY(enable_omap3630_toggle_l2_on_restore)
 

? ? ? ?.text
?/* Function to call rom code to save secure ram context */
+ ? ? ? .align ?3
?ENTRY(save_secure_ram_context)
? ? ? ?stmfd ? sp!, {r1-r12, lr} ? ? ? @ save registers on stack ? ? ? ?adr ? ? r3, api_params ? ? ? ? ?@ r3 points to parameters

arch/arm/mach-omap2/sleep34xx.S +0 -0
@@ -169,6 +170,7 @@ ENTRY(save_secure_ram_context_sz)
 ?* ? depending on the low power mode (non-OFF vs OFF modes),

?* ? cf. 'Resume path for xxx mode' comments.
?*/
+ ? ? ? .align ?3
?ENTRY(omap34xx_cpu_suspend)
? ? ? ?stmfd ? sp!, {r0-r12, lr} ? ? ? @ save registers on stack

arch/arm/mach-omap2/sram242x.S +0 -0
index 055310c..ff9b9db 100644
@@ -39,6 +39,7 @@
 

? ? ? ?.text

+ ? ? ? .align ?3
?ENTRY(omap242x_sram_ddr_init)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? @ save registers on stack

arch/arm/mach-omap2/sram242x.S +0 -0
@@ -143,6 +144,7 @@ ENTRY(omap242x_sram_ddr_init_sz)

?* r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] ?* PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
?*/
+ ? ? ? .align ?3
?ENTRY(omap242x_sram_reprogram_sdrc)
? ? ? ?stmfd ? sp!, {r0 - r10, lr} ? ? @ save registers on stack ? ? ? ?mov ? ? r3, #0x0 ? ? ? ? ? ? ? ?@ clear for mrc call

arch/arm/mach-omap2/sram242x.S +0 -0
@@ -238,6 +240,7 @@ ENTRY(omap242x_sram_reprogram_sdrc_sz)

?/*
?* Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. ?*/
+ ? ? ? .align ?3
?ENTRY(omap242x_sram_set_prcm)
? ? ? ?stmfd ? sp!, {r0-r12, lr} ? ? ? @ regs to stack
? ? ? ?adr ? ? r4, pbegin ? ? ? ? ? ? ?@ addr of preload start

arch/arm/mach-omap2/sram243x.S +0 -0
index f900758..7673020 100644
@@ -39,6 +39,7 @@
 

? ? ? ?.text

+ ? ? ? .align ?3
?ENTRY(omap243x_sram_ddr_init)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? @ save registers on stack

arch/arm/mach-omap2/sram243x.S +0 -0
@@ -143,6 +144,7 @@ ENTRY(omap243x_sram_ddr_init_sz)

?* r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] ?* PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
?*/
+ ? ? ? .align ?3
?ENTRY(omap243x_sram_reprogram_sdrc)
? ? ? ?stmfd ? sp!, {r0 - r10, lr} ? ? @ save registers on stack ? ? ? ?mov ? ? r3, #0x0 ? ? ? ? ? ? ? ?@ clear for mrc call

arch/arm/mach-omap2/sram243x.S +0 -0
@@ -238,6 +240,7 @@ ENTRY(omap243x_sram_reprogram_sdrc_sz)

?/*
?* Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. ?*/
+ ? ? ? .align ?3
?ENTRY(omap243x_sram_set_prcm)
? ? ? ?stmfd ? sp!, {r0-r12, lr} ? ? ? @ regs to stack
? ? ? ?adr ? ? r4, pbegin ? ? ? ? ? ? ?@ addr of preload start

arch/arm/mach-omap2/sram34xx.S +0 -0
index 7f893a2..25011ca 100644
@@ -111,6 +111,7 @@

?* since it will cause the ARM MMU to attempt to walk the page tables. ?* These crashes may be intermittent.
?*/
+ ? ? ? .align ?3
?ENTRY(omap3_sram_configure_core_dpll)
? ? ? ?stmfd ? sp!, {r1-r12, lr} ? ? ? @ store regs to stack

arch/arm/plat-omap/include/plat/sram.h +0 -0
index 9967d5e..d673f2c 100644
@@ -12,7 +12,19 @@

?#define __ARCH_ARM_OMAP_SRAM_H

?#ifndef __ASSEMBLY__

arch/arm/plat-omap/include/plat/sram.h

Quoted 8 lines
arch/arm/plat-omap/include/plat/sram.h +7 -1
-extern void * omap_sram_push(void * start, unsigned long size);
+#include <asm/fncpy.h>
+
+extern void *omap_sram_push_address(unsigned long size);
+
+/* Macro to push a function to the internal SRAM, using the fncpy API */
+#define omap_sram_push(funcp, size) ({ ? ? ? ? ? ? ? ? ? ? ? ? \
+ ? ? ? typeof(&funcp) _res = NULL; ? ? ? ? ? ? ? ? ? ? ? ? ? ? \

1) For fncpy() itself, I decided not to take the address of funcp inside the macro: the reason for this was that if you do this, the macro will silently do something silly if called with a function pointer instead of the function itself -- i.e., some memory starting at the stored function pointer itself will be copied instead of the function body.

Forcing the caller to supply the '&' is a bit ugly, but I decided it was preferable from a safety standpoint.

This doesn't necessarily mean that omap_sram_push can't add the '&', but if you do, you need to be careful how the macro is called. It will work for all existing uses of omap_sram_push, IIUC.

2) Should this be &(funcp)? This will only matter for pretty weird uses though. Currently most weird uses won't work properly anyway, because of (1). So this might not be much of a concern.

Quoted 3 lines

+ ? ? ? void *_sram_address = omap_sram_push_address(size); ? ? \
+ ? ? ? if (_sram_address) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
+ ? ? ? ? ? ? ? _res = fncpy(_sram_address, &funcp, size); ? ? ?\

&(funcp)

(see (2))

Cheers
---Dave

author
#6 lore raw

PATCH v2 1/1 OMAP: use fncpy to copy the PM code functions to SRAM

Hi,

Quoted 230 lines · Dave Martin

Hi there, I just spotted a couple of things merging your patch...

Quoted 211 lines · On Tue, Jan 18, 2011 at 12:02 PM, ?<[email protected]> wrote:

From: Jean Pihet <[email protected]>

The new fncpy API is better suited for copying some code to SRAM at runtime. This patch changes the ad-hoc code to the more generic fncpy API.

Tested OK on OMAP3 in low power modes (RET/OFF) using omap2plus_defconfig with !CONFIG_THUMB2_KERNEL. Compile tested on OMAP1/2 using omap1_defconfig.

---

?arch/arm/mach-omap1/pm.h ? ? ? ? ? ? ? | ? ?6 +++---
?arch/arm/mach-omap1/sleep.S ? ? ? ? ? ?| ? ?3 +++
?arch/arm/mach-omap1/sram.S ? ? ? ? ? ? | ? ?1 +
?arch/arm/mach-omap2/pm.h ? ? ? ? ? ? ? | ? ?2 +-
?arch/arm/mach-omap2/sleep24xx.S ? ? ? ?| ? ?2 ++
?arch/arm/mach-omap2/sleep34xx.S ? ? ? ?| ? ?2 ++
?arch/arm/mach-omap2/sram242x.S ? ? ? ? | ? ?3 +++
?arch/arm/mach-omap2/sram243x.S ? ? ? ? | ? ?3 +++
?arch/arm/mach-omap2/sram34xx.S ? ? ? ? | ? ?1 +
?arch/arm/plat-omap/include/plat/sram.h | ? 14 +++++++++++++-
?arch/arm/plat-omap/sram.c ? ? ? ? ? ? ?| ? 14 +++++++++-----

?11 files changed, 41 insertions(+), 10 deletions(-)

arch/arm/mach-omap1/pm.h +3 -3
index 56a6479..cd926dc 100644
@@ -123,9 +123,9 @@ extern void allow_idle_sleep(void);
 ?extern void omap1_pm_idle(void);
 ?extern void omap1_pm_suspend(void);
 
-extern void omap7xx_cpu_suspend(unsigned short, unsigned short);
-extern void omap1510_cpu_suspend(unsigned short, unsigned short);
-extern void omap1610_cpu_suspend(unsigned short, unsigned short);
+extern void omap7xx_cpu_suspend(unsigned long, unsigned long);
+extern void omap1510_cpu_suspend(unsigned long, unsigned long);
+extern void omap1610_cpu_suspend(unsigned long, unsigned long);
 ?extern void omap7xx_idle_loop_suspend(void);
 ?extern void omap1510_idle_loop_suspend(void);
 ?extern void omap1610_idle_loop_suspend(void);
arch/arm/mach-omap1/sleep.S +0 -0
index ef771ce..c875bdc 100644
@@ -58,6 +58,7 @@

?*/

?#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ ? ? ? .align ?3
?ENTRY(omap7xx_cpu_suspend)

? ? ? ?@ save registers on stack

arch/arm/mach-omap1/sleep.S +0 -0
@@ -137,6 +138,7 @@ ENTRY(omap7xx_cpu_suspend_sz)

?#endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */

?#ifdef CONFIG_ARCH_OMAP15XX
+ ? ? ? .align ?3
?ENTRY(omap1510_cpu_suspend)

? ? ? ?@ save registers on stack

arch/arm/mach-omap1/sleep.S +0 -0
@@ -211,6 +213,7 @@ ENTRY(omap1510_cpu_suspend_sz)

?#endif /* CONFIG_ARCH_OMAP15XX */

?#if defined(CONFIG_ARCH_OMAP16XX)
+ ? ? ? .align ?3
?ENTRY(omap1610_cpu_suspend)

? ? ? ?@ save registers on stack

arch/arm/mach-omap1/sram.S +0 -0
index 7724e52..692587d 100644
@@ -18,6 +18,7 @@

?/*
?* Reprograms ULPD and CKCTL.
?*/
+ ? ? ? .align ?3
?ENTRY(omap1_sram_reprogram_clock)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? ? ? ? ? @ save registers on stack

arch/arm/mach-omap2/pm.h +1 -1
index 1c1b0ab..39580e6 100644
@@ -92,7 +92,7 @@ extern void omap24xx_idle_loop_suspend(void);
 ?extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?void __iomem *sdrc_power);
 ?extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
-extern void save_secure_ram_context(u32 *addr);
+extern int save_secure_ram_context(u32 *addr);
 ?extern void omap3_save_scratchpad_contents(void);
 
 ?extern unsigned int omap24xx_idle_loop_suspend_sz;
arch/arm/mach-omap2/sleep24xx.S +0 -0
index c7780cc..b5071a4 100644
@@ -47,6 +47,7 @@

?* Note: This code get's copied to internal SRAM at boot. When the OMAP ?* ? ? ?wakes up it continues execution at the point it went to sleep. ?*/
+ ? ? ? .align ?3
?ENTRY(omap24xx_idle_loop_suspend)
? ? ? ?stmfd ? sp!, {r0, lr} ? ? ? ? ? @ save registers on stack ? ? ? ?mov ? ? r0, #0 ? ? ? ? ? ? ? ? ?@ clear for mcr setup

arch/arm/mach-omap2/sleep24xx.S +0 -0
@@ -82,6 +83,7 @@ ENTRY(omap24xx_idle_loop_suspend_sz)

?* The DLL load value is not kept in RETENTION or OFF. It needs to be restored ?* at wake
?*/
+ ? ? ? .align ?3
?ENTRY(omap24xx_cpu_suspend)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? @ save registers on stack ? ? ? ?mov ? ? r3, #0x0 ? ? ? ? ? ? ? ?@ clear for mcr call

arch/arm/mach-omap2/sleep34xx.S +0 -0
index 98d8232..951a0be 100644
@@ -118,6 +118,7 @@ ENTRY(enable_omap3630_toggle_l2_on_restore)
 

? ? ? ?.text
?/* Function to call rom code to save secure ram context */
+ ? ? ? .align ?3
?ENTRY(save_secure_ram_context)
? ? ? ?stmfd ? sp!, {r1-r12, lr} ? ? ? @ save registers on stack ? ? ? ?adr ? ? r3, api_params ? ? ? ? ?@ r3 points to parameters

arch/arm/mach-omap2/sleep34xx.S +0 -0
@@ -169,6 +170,7 @@ ENTRY(save_secure_ram_context_sz)
 ?* ? depending on the low power mode (non-OFF vs OFF modes),

?* ? cf. 'Resume path for xxx mode' comments.
?*/
+ ? ? ? .align ?3
?ENTRY(omap34xx_cpu_suspend)
? ? ? ?stmfd ? sp!, {r0-r12, lr} ? ? ? @ save registers on stack

arch/arm/mach-omap2/sram242x.S +0 -0
index 055310c..ff9b9db 100644
@@ -39,6 +39,7 @@
 

? ? ? ?.text

+ ? ? ? .align ?3
?ENTRY(omap242x_sram_ddr_init)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? @ save registers on stack

arch/arm/mach-omap2/sram242x.S +0 -0
@@ -143,6 +144,7 @@ ENTRY(omap242x_sram_ddr_init_sz)

?* r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] ?* PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
?*/
+ ? ? ? .align ?3
?ENTRY(omap242x_sram_reprogram_sdrc)
? ? ? ?stmfd ? sp!, {r0 - r10, lr} ? ? @ save registers on stack ? ? ? ?mov ? ? r3, #0x0 ? ? ? ? ? ? ? ?@ clear for mrc call

arch/arm/mach-omap2/sram242x.S +0 -0
@@ -238,6 +240,7 @@ ENTRY(omap242x_sram_reprogram_sdrc_sz)

?/*
?* Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. ?*/
+ ? ? ? .align ?3
?ENTRY(omap242x_sram_set_prcm)
? ? ? ?stmfd ? sp!, {r0-r12, lr} ? ? ? @ regs to stack
? ? ? ?adr ? ? r4, pbegin ? ? ? ? ? ? ?@ addr of preload start

arch/arm/mach-omap2/sram243x.S +0 -0
index f900758..7673020 100644
@@ -39,6 +39,7 @@
 

? ? ? ?.text

+ ? ? ? .align ?3
?ENTRY(omap243x_sram_ddr_init)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? @ save registers on stack

arch/arm/mach-omap2/sram243x.S +0 -0
@@ -143,6 +144,7 @@ ENTRY(omap243x_sram_ddr_init_sz)

?* r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] ?* PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
?*/
+ ? ? ? .align ?3
?ENTRY(omap243x_sram_reprogram_sdrc)
? ? ? ?stmfd ? sp!, {r0 - r10, lr} ? ? @ save registers on stack ? ? ? ?mov ? ? r3, #0x0 ? ? ? ? ? ? ? ?@ clear for mrc call

arch/arm/mach-omap2/sram243x.S +0 -0
@@ -238,6 +240,7 @@ ENTRY(omap243x_sram_reprogram_sdrc_sz)

?/*
?* Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. ?*/
+ ? ? ? .align ?3
?ENTRY(omap243x_sram_set_prcm)
? ? ? ?stmfd ? sp!, {r0-r12, lr} ? ? ? @ regs to stack
? ? ? ?adr ? ? r4, pbegin ? ? ? ? ? ? ?@ addr of preload start

arch/arm/mach-omap2/sram34xx.S +0 -0
index 7f893a2..25011ca 100644
@@ -111,6 +111,7 @@

?* since it will cause the ARM MMU to attempt to walk the page tables. ?* These crashes may be intermittent.
?*/
+ ? ? ? .align ?3
?ENTRY(omap3_sram_configure_core_dpll)
? ? ? ?stmfd ? sp!, {r1-r12, lr} ? ? ? @ store regs to stack

arch/arm/plat-omap/include/plat/sram.h +0 -0
index 9967d5e..d673f2c 100644
@@ -12,7 +12,19 @@

?#define __ARCH_ARM_OMAP_SRAM_H

?#ifndef __ASSEMBLY__

arch/arm/plat-omap/include/plat/sram.h

Quoted 8 lines
arch/arm/plat-omap/include/plat/sram.h +7 -1
-extern void * omap_sram_push(void * start, unsigned long size);
+#include <asm/fncpy.h>
+
+extern void *omap_sram_push_address(unsigned long size);
+
+/* Macro to push a function to the internal SRAM, using the fncpy API */
+#define omap_sram_push(funcp, size) ({ ? ? ? ? ? ? ? ? ? ? ? ? \
+ ? ? ? typeof(&funcp) _res = NULL; ? ? ? ? ? ? ? ? ? ? ? ? ? ? \

1) For fncpy() itself, I decided not to take the address of funcp inside the macro: the reason for this was that if you do this, the macro will silently do something silly if called with a function pointer instead of the function itself -- i.e., some memory starting at the stored function pointer itself will be copied instead of the function body.

Quoted 6 lines

Forcing the caller to supply the '&' is a bit ugly, but I decided it was preferable from a safety standpoint.

This doesn't necessarily mean that omap_sram_push can't add the '&', but if you do, you need to be careful how the macro is called. ?It will work for all existing uses of omap_sram_push, IIUC.

I am OK with that.
In the first place it was not obvious that the '&' was needed but the compiler quickly reminded me about it. The type checking is one of the advantages of the new API.

Quoted 10 lines

2) Should this be &(funcp)? ?This will only matter for pretty weird uses though. ?Currently most weird uses won't work properly anyway, because of (1). ?So this might not be much of a concern.

Quoted 3 lines

+ ? ? ? void *_sram_address = omap_sram_push_address(size); ? ? \
+ ? ? ? if (_sram_address) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
+ ? ? ? ? ? ? ? _res = fncpy(_sram_address, &funcp, size); ? ? ?\

&(funcp)

Yes that is correct but the current code does not have problem since the functions to push have 'non-weird' types.
If needed I can change that.

Quoted 6 lines

(see (2))

Cheers
---Dave

Thanks,
Jean

#7 lore raw

PATCH v2 1/1 OMAP: use fncpy to copy the PM code functions to SRAM

Quoted 249 lines · Jean Pihet

Hi,

Quoted 230 lines · Dave Martin

Hi there, I just spotted a couple of things merging your patch...

Quoted 211 lines · On Tue, Jan 18, 2011 at 12:02 PM, ?<[email protected]> wrote:

From: Jean Pihet <[email protected]>

The new fncpy API is better suited for copying some code to SRAM at runtime. This patch changes the ad-hoc code to the more generic fncpy API.

Tested OK on OMAP3 in low power modes (RET/OFF) using omap2plus_defconfig with !CONFIG_THUMB2_KERNEL. Compile tested on OMAP1/2 using omap1_defconfig.

---

?arch/arm/mach-omap1/pm.h ? ? ? ? ? ? ? | ? ?6 +++---
?arch/arm/mach-omap1/sleep.S ? ? ? ? ? ?| ? ?3 +++
?arch/arm/mach-omap1/sram.S ? ? ? ? ? ? | ? ?1 +
?arch/arm/mach-omap2/pm.h ? ? ? ? ? ? ? | ? ?2 +-
?arch/arm/mach-omap2/sleep24xx.S ? ? ? ?| ? ?2 ++
?arch/arm/mach-omap2/sleep34xx.S ? ? ? ?| ? ?2 ++
?arch/arm/mach-omap2/sram242x.S ? ? ? ? | ? ?3 +++
?arch/arm/mach-omap2/sram243x.S ? ? ? ? | ? ?3 +++
?arch/arm/mach-omap2/sram34xx.S ? ? ? ? | ? ?1 +
?arch/arm/plat-omap/include/plat/sram.h | ? 14 +++++++++++++-
?arch/arm/plat-omap/sram.c ? ? ? ? ? ? ?| ? 14 +++++++++-----

?11 files changed, 41 insertions(+), 10 deletions(-)

arch/arm/mach-omap1/pm.h +3 -3
index 56a6479..cd926dc 100644
@@ -123,9 +123,9 @@ extern void allow_idle_sleep(void);
 ?extern void omap1_pm_idle(void);
 ?extern void omap1_pm_suspend(void);
 
-extern void omap7xx_cpu_suspend(unsigned short, unsigned short);
-extern void omap1510_cpu_suspend(unsigned short, unsigned short);
-extern void omap1610_cpu_suspend(unsigned short, unsigned short);
+extern void omap7xx_cpu_suspend(unsigned long, unsigned long);
+extern void omap1510_cpu_suspend(unsigned long, unsigned long);
+extern void omap1610_cpu_suspend(unsigned long, unsigned long);
 ?extern void omap7xx_idle_loop_suspend(void);
 ?extern void omap1510_idle_loop_suspend(void);
 ?extern void omap1610_idle_loop_suspend(void);
arch/arm/mach-omap1/sleep.S +0 -0
index ef771ce..c875bdc 100644
@@ -58,6 +58,7 @@

?*/

?#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ ? ? ? .align ?3
?ENTRY(omap7xx_cpu_suspend)

? ? ? ?@ save registers on stack

arch/arm/mach-omap1/sleep.S +0 -0
@@ -137,6 +138,7 @@ ENTRY(omap7xx_cpu_suspend_sz)

?#endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */

?#ifdef CONFIG_ARCH_OMAP15XX
+ ? ? ? .align ?3
?ENTRY(omap1510_cpu_suspend)

? ? ? ?@ save registers on stack

arch/arm/mach-omap1/sleep.S +0 -0
@@ -211,6 +213,7 @@ ENTRY(omap1510_cpu_suspend_sz)

?#endif /* CONFIG_ARCH_OMAP15XX */

?#if defined(CONFIG_ARCH_OMAP16XX)
+ ? ? ? .align ?3
?ENTRY(omap1610_cpu_suspend)

? ? ? ?@ save registers on stack

arch/arm/mach-omap1/sram.S +0 -0
index 7724e52..692587d 100644
@@ -18,6 +18,7 @@

?/*
?* Reprograms ULPD and CKCTL.
?*/
+ ? ? ? .align ?3
?ENTRY(omap1_sram_reprogram_clock)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? ? ? ? ? @ save registers on stack

arch/arm/mach-omap2/pm.h +1 -1
index 1c1b0ab..39580e6 100644
@@ -92,7 +92,7 @@ extern void omap24xx_idle_loop_suspend(void);
 ?extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?void __iomem *sdrc_power);
 ?extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
-extern void save_secure_ram_context(u32 *addr);
+extern int save_secure_ram_context(u32 *addr);
 ?extern void omap3_save_scratchpad_contents(void);
 
 ?extern unsigned int omap24xx_idle_loop_suspend_sz;
arch/arm/mach-omap2/sleep24xx.S +0 -0
index c7780cc..b5071a4 100644
@@ -47,6 +47,7 @@

?* Note: This code get's copied to internal SRAM at boot. When the OMAP ?* ? ? ?wakes up it continues execution at the point it went to sleep. ?*/
+ ? ? ? .align ?3
?ENTRY(omap24xx_idle_loop_suspend)
? ? ? ?stmfd ? sp!, {r0, lr} ? ? ? ? ? @ save registers on stack ? ? ? ?mov ? ? r0, #0 ? ? ? ? ? ? ? ? ?@ clear for mcr setup

arch/arm/mach-omap2/sleep24xx.S +0 -0
@@ -82,6 +83,7 @@ ENTRY(omap24xx_idle_loop_suspend_sz)

?* The DLL load value is not kept in RETENTION or OFF. It needs to be restored ?* at wake
?*/
+ ? ? ? .align ?3
?ENTRY(omap24xx_cpu_suspend)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? @ save registers on stack ? ? ? ?mov ? ? r3, #0x0 ? ? ? ? ? ? ? ?@ clear for mcr call

arch/arm/mach-omap2/sleep34xx.S +0 -0
index 98d8232..951a0be 100644
@@ -118,6 +118,7 @@ ENTRY(enable_omap3630_toggle_l2_on_restore)
 

? ? ? ?.text
?/* Function to call rom code to save secure ram context */
+ ? ? ? .align ?3
?ENTRY(save_secure_ram_context)
? ? ? ?stmfd ? sp!, {r1-r12, lr} ? ? ? @ save registers on stack ? ? ? ?adr ? ? r3, api_params ? ? ? ? ?@ r3 points to parameters

arch/arm/mach-omap2/sleep34xx.S +0 -0
@@ -169,6 +170,7 @@ ENTRY(save_secure_ram_context_sz)
 ?* ? depending on the low power mode (non-OFF vs OFF modes),

?* ? cf. 'Resume path for xxx mode' comments.
?*/
+ ? ? ? .align ?3
?ENTRY(omap34xx_cpu_suspend)
? ? ? ?stmfd ? sp!, {r0-r12, lr} ? ? ? @ save registers on stack

arch/arm/mach-omap2/sram242x.S +0 -0
index 055310c..ff9b9db 100644
@@ -39,6 +39,7 @@
 

? ? ? ?.text

+ ? ? ? .align ?3
?ENTRY(omap242x_sram_ddr_init)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? @ save registers on stack

arch/arm/mach-omap2/sram242x.S +0 -0
@@ -143,6 +144,7 @@ ENTRY(omap242x_sram_ddr_init_sz)

?* r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] ?* PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
?*/
+ ? ? ? .align ?3
?ENTRY(omap242x_sram_reprogram_sdrc)
? ? ? ?stmfd ? sp!, {r0 - r10, lr} ? ? @ save registers on stack ? ? ? ?mov ? ? r3, #0x0 ? ? ? ? ? ? ? ?@ clear for mrc call

arch/arm/mach-omap2/sram242x.S +0 -0
@@ -238,6 +240,7 @@ ENTRY(omap242x_sram_reprogram_sdrc_sz)

?/*
?* Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. ?*/
+ ? ? ? .align ?3
?ENTRY(omap242x_sram_set_prcm)
? ? ? ?stmfd ? sp!, {r0-r12, lr} ? ? ? @ regs to stack
? ? ? ?adr ? ? r4, pbegin ? ? ? ? ? ? ?@ addr of preload start

arch/arm/mach-omap2/sram243x.S +0 -0
index f900758..7673020 100644
@@ -39,6 +39,7 @@
 

? ? ? ?.text

+ ? ? ? .align ?3
?ENTRY(omap243x_sram_ddr_init)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? @ save registers on stack

arch/arm/mach-omap2/sram243x.S +0 -0
@@ -143,6 +144,7 @@ ENTRY(omap243x_sram_ddr_init_sz)

?* r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] ?* PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
?*/
+ ? ? ? .align ?3
?ENTRY(omap243x_sram_reprogram_sdrc)
? ? ? ?stmfd ? sp!, {r0 - r10, lr} ? ? @ save registers on stack ? ? ? ?mov ? ? r3, #0x0 ? ? ? ? ? ? ? ?@ clear for mrc call

arch/arm/mach-omap2/sram243x.S +0 -0
@@ -238,6 +240,7 @@ ENTRY(omap243x_sram_reprogram_sdrc_sz)

?/*
?* Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. ?*/
+ ? ? ? .align ?3
?ENTRY(omap243x_sram_set_prcm)
? ? ? ?stmfd ? sp!, {r0-r12, lr} ? ? ? @ regs to stack
? ? ? ?adr ? ? r4, pbegin ? ? ? ? ? ? ?@ addr of preload start

arch/arm/mach-omap2/sram34xx.S +0 -0
index 7f893a2..25011ca 100644
@@ -111,6 +111,7 @@

?* since it will cause the ARM MMU to attempt to walk the page tables. ?* These crashes may be intermittent.
?*/
+ ? ? ? .align ?3
?ENTRY(omap3_sram_configure_core_dpll)
? ? ? ?stmfd ? sp!, {r1-r12, lr} ? ? ? @ store regs to stack

arch/arm/plat-omap/include/plat/sram.h +0 -0
index 9967d5e..d673f2c 100644
@@ -12,7 +12,19 @@

?#define __ARCH_ARM_OMAP_SRAM_H

?#ifndef __ASSEMBLY__

arch/arm/plat-omap/include/plat/sram.h

Quoted 8 lines
arch/arm/plat-omap/include/plat/sram.h +7 -1
-extern void * omap_sram_push(void * start, unsigned long size);
+#include <asm/fncpy.h>
+
+extern void *omap_sram_push_address(unsigned long size);
+
+/* Macro to push a function to the internal SRAM, using the fncpy API */
+#define omap_sram_push(funcp, size) ({ ? ? ? ? ? ? ? ? ? ? ? ? \
+ ? ? ? typeof(&funcp) _res = NULL; ? ? ? ? ? ? ? ? ? ? ? ? ? ? \

1) For fncpy() itself, I decided not to take the address of funcp inside the macro: the reason for this was that if you do this, the macro will silently do something silly if called with a function pointer instead of the function itself -- i.e., some memory starting at the stored function pointer itself will be copied instead of the function body.

Quoted 6 lines

Forcing the caller to supply the '&' is a bit ugly, but I decided it was preferable from a safety standpoint.

This doesn't necessarily mean that omap_sram_push can't add the '&', but if you do, you need to be careful how the macro is called. ?It will work for all existing uses of omap_sram_push, IIUC.

I am OK with that.
In the first place it was not obvious that the '&' was needed but the compiler quickly reminded me about it. The type checking is one of the advantages of the new API.

Quoted 5 lines

2) Should this be &(funcp)? ?This will only matter for pretty weird uses though. ?Currently most weird uses won't work properly anyway, because of (1). ?So this might not be much of a concern.

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

+ ? ? ? void *_sram_address = omap_sram_push_address(size); ? ? \
+ ? ? ? if (_sram_address) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
+ ? ? ? ? ? ? ? _res = fncpy(_sram_address, &funcp, size); ? ? ?\

&(funcp)

Yes that is correct but the current code does not have problem since the functions to push have 'non-weird' types.
If needed I can change that.

Fair enough. Because of the way omap_sram_push is used I think this isn't a significant risk -- just thought it was worth pointing out.

Cheers
---Dave

author
#8 lore raw

PATCH v2 1/1 OMAP: use fncpy to copy the PM code functions to SRAM

Quoted 254 lines · Dave Martin
Quoted 253 lines · Jean Pihet

Hi,

Quoted 230 lines · Dave Martin

Hi there, I just spotted a couple of things merging your patch...

Quoted 211 lines · On Tue, Jan 18, 2011 at 12:02 PM, ?<[email protected]> wrote:

From: Jean Pihet <[email protected]>

The new fncpy API is better suited for copying some code to SRAM at runtime. This patch changes the ad-hoc code to the more generic fncpy API.

Tested OK on OMAP3 in low power modes (RET/OFF) using omap2plus_defconfig with !CONFIG_THUMB2_KERNEL. Compile tested on OMAP1/2 using omap1_defconfig.

---

?arch/arm/mach-omap1/pm.h ? ? ? ? ? ? ? | ? ?6 +++---
?arch/arm/mach-omap1/sleep.S ? ? ? ? ? ?| ? ?3 +++
?arch/arm/mach-omap1/sram.S ? ? ? ? ? ? | ? ?1 +
?arch/arm/mach-omap2/pm.h ? ? ? ? ? ? ? | ? ?2 +-
?arch/arm/mach-omap2/sleep24xx.S ? ? ? ?| ? ?2 ++
?arch/arm/mach-omap2/sleep34xx.S ? ? ? ?| ? ?2 ++
?arch/arm/mach-omap2/sram242x.S ? ? ? ? | ? ?3 +++
?arch/arm/mach-omap2/sram243x.S ? ? ? ? | ? ?3 +++
?arch/arm/mach-omap2/sram34xx.S ? ? ? ? | ? ?1 +
?arch/arm/plat-omap/include/plat/sram.h | ? 14 +++++++++++++-
?arch/arm/plat-omap/sram.c ? ? ? ? ? ? ?| ? 14 +++++++++-----

?11 files changed, 41 insertions(+), 10 deletions(-)

arch/arm/mach-omap1/pm.h +3 -3
index 56a6479..cd926dc 100644
@@ -123,9 +123,9 @@ extern void allow_idle_sleep(void);
 ?extern void omap1_pm_idle(void);
 ?extern void omap1_pm_suspend(void);
 
-extern void omap7xx_cpu_suspend(unsigned short, unsigned short);
-extern void omap1510_cpu_suspend(unsigned short, unsigned short);
-extern void omap1610_cpu_suspend(unsigned short, unsigned short);
+extern void omap7xx_cpu_suspend(unsigned long, unsigned long);
+extern void omap1510_cpu_suspend(unsigned long, unsigned long);
+extern void omap1610_cpu_suspend(unsigned long, unsigned long);
 ?extern void omap7xx_idle_loop_suspend(void);
 ?extern void omap1510_idle_loop_suspend(void);
 ?extern void omap1610_idle_loop_suspend(void);
arch/arm/mach-omap1/sleep.S +0 -0
index ef771ce..c875bdc 100644
@@ -58,6 +58,7 @@

?*/

?#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ ? ? ? .align ?3
?ENTRY(omap7xx_cpu_suspend)

? ? ? ?@ save registers on stack

arch/arm/mach-omap1/sleep.S +0 -0
@@ -137,6 +138,7 @@ ENTRY(omap7xx_cpu_suspend_sz)

?#endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */

?#ifdef CONFIG_ARCH_OMAP15XX
+ ? ? ? .align ?3
?ENTRY(omap1510_cpu_suspend)

? ? ? ?@ save registers on stack

arch/arm/mach-omap1/sleep.S +0 -0
@@ -211,6 +213,7 @@ ENTRY(omap1510_cpu_suspend_sz)

?#endif /* CONFIG_ARCH_OMAP15XX */

?#if defined(CONFIG_ARCH_OMAP16XX)
+ ? ? ? .align ?3
?ENTRY(omap1610_cpu_suspend)

? ? ? ?@ save registers on stack

arch/arm/mach-omap1/sram.S +0 -0
index 7724e52..692587d 100644
@@ -18,6 +18,7 @@

?/*
?* Reprograms ULPD and CKCTL.
?*/
+ ? ? ? .align ?3
?ENTRY(omap1_sram_reprogram_clock)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? ? ? ? ? @ save registers on stack

arch/arm/mach-omap2/pm.h +1 -1
index 1c1b0ab..39580e6 100644
@@ -92,7 +92,7 @@ extern void omap24xx_idle_loop_suspend(void);
 ?extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?void __iomem *sdrc_power);
 ?extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
-extern void save_secure_ram_context(u32 *addr);
+extern int save_secure_ram_context(u32 *addr);
 ?extern void omap3_save_scratchpad_contents(void);
 
 ?extern unsigned int omap24xx_idle_loop_suspend_sz;
arch/arm/mach-omap2/sleep24xx.S +0 -0
index c7780cc..b5071a4 100644
@@ -47,6 +47,7 @@

?* Note: This code get's copied to internal SRAM at boot. When the OMAP ?* ? ? ?wakes up it continues execution at the point it went to sleep. ?*/
+ ? ? ? .align ?3
?ENTRY(omap24xx_idle_loop_suspend)
? ? ? ?stmfd ? sp!, {r0, lr} ? ? ? ? ? @ save registers on stack ? ? ? ?mov ? ? r0, #0 ? ? ? ? ? ? ? ? ?@ clear for mcr setup

arch/arm/mach-omap2/sleep24xx.S +0 -0
@@ -82,6 +83,7 @@ ENTRY(omap24xx_idle_loop_suspend_sz)

?* The DLL load value is not kept in RETENTION or OFF. It needs to be restored ?* at wake
?*/
+ ? ? ? .align ?3
?ENTRY(omap24xx_cpu_suspend)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? @ save registers on stack ? ? ? ?mov ? ? r3, #0x0 ? ? ? ? ? ? ? ?@ clear for mcr call

arch/arm/mach-omap2/sleep34xx.S +0 -0
index 98d8232..951a0be 100644
@@ -118,6 +118,7 @@ ENTRY(enable_omap3630_toggle_l2_on_restore)
 

? ? ? ?.text
?/* Function to call rom code to save secure ram context */
+ ? ? ? .align ?3
?ENTRY(save_secure_ram_context)
? ? ? ?stmfd ? sp!, {r1-r12, lr} ? ? ? @ save registers on stack ? ? ? ?adr ? ? r3, api_params ? ? ? ? ?@ r3 points to parameters

arch/arm/mach-omap2/sleep34xx.S +0 -0
@@ -169,6 +170,7 @@ ENTRY(save_secure_ram_context_sz)
 ?* ? depending on the low power mode (non-OFF vs OFF modes),

?* ? cf. 'Resume path for xxx mode' comments.
?*/
+ ? ? ? .align ?3
?ENTRY(omap34xx_cpu_suspend)
? ? ? ?stmfd ? sp!, {r0-r12, lr} ? ? ? @ save registers on stack

arch/arm/mach-omap2/sram242x.S +0 -0
index 055310c..ff9b9db 100644
@@ -39,6 +39,7 @@
 

? ? ? ?.text

+ ? ? ? .align ?3
?ENTRY(omap242x_sram_ddr_init)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? @ save registers on stack

arch/arm/mach-omap2/sram242x.S +0 -0
@@ -143,6 +144,7 @@ ENTRY(omap242x_sram_ddr_init_sz)

?* r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] ?* PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
?*/
+ ? ? ? .align ?3
?ENTRY(omap242x_sram_reprogram_sdrc)
? ? ? ?stmfd ? sp!, {r0 - r10, lr} ? ? @ save registers on stack ? ? ? ?mov ? ? r3, #0x0 ? ? ? ? ? ? ? ?@ clear for mrc call

arch/arm/mach-omap2/sram242x.S +0 -0
@@ -238,6 +240,7 @@ ENTRY(omap242x_sram_reprogram_sdrc_sz)

?/*
?* Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. ?*/
+ ? ? ? .align ?3
?ENTRY(omap242x_sram_set_prcm)
? ? ? ?stmfd ? sp!, {r0-r12, lr} ? ? ? @ regs to stack
? ? ? ?adr ? ? r4, pbegin ? ? ? ? ? ? ?@ addr of preload start

arch/arm/mach-omap2/sram243x.S +0 -0
index f900758..7673020 100644
@@ -39,6 +39,7 @@
 

? ? ? ?.text

+ ? ? ? .align ?3
?ENTRY(omap243x_sram_ddr_init)
? ? ? ?stmfd ? sp!, {r0 - r12, lr} ? ? @ save registers on stack

arch/arm/mach-omap2/sram243x.S +0 -0
@@ -143,6 +144,7 @@ ENTRY(omap243x_sram_ddr_init_sz)

?* r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] ?* PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
?*/
+ ? ? ? .align ?3
?ENTRY(omap243x_sram_reprogram_sdrc)
? ? ? ?stmfd ? sp!, {r0 - r10, lr} ? ? @ save registers on stack ? ? ? ?mov ? ? r3, #0x0 ? ? ? ? ? ? ? ?@ clear for mrc call

arch/arm/mach-omap2/sram243x.S +0 -0
@@ -238,6 +240,7 @@ ENTRY(omap243x_sram_reprogram_sdrc_sz)

?/*
?* Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. ?*/
+ ? ? ? .align ?3
?ENTRY(omap243x_sram_set_prcm)
? ? ? ?stmfd ? sp!, {r0-r12, lr} ? ? ? @ regs to stack
? ? ? ?adr ? ? r4, pbegin ? ? ? ? ? ? ?@ addr of preload start

arch/arm/mach-omap2/sram34xx.S +0 -0
index 7f893a2..25011ca 100644
@@ -111,6 +111,7 @@

?* since it will cause the ARM MMU to attempt to walk the page tables. ?* These crashes may be intermittent.
?*/
+ ? ? ? .align ?3
?ENTRY(omap3_sram_configure_core_dpll)
? ? ? ?stmfd ? sp!, {r1-r12, lr} ? ? ? @ store regs to stack

arch/arm/plat-omap/include/plat/sram.h +0 -0
index 9967d5e..d673f2c 100644
@@ -12,7 +12,19 @@

?#define __ARCH_ARM_OMAP_SRAM_H

?#ifndef __ASSEMBLY__

arch/arm/plat-omap/include/plat/sram.h

Quoted 8 lines
arch/arm/plat-omap/include/plat/sram.h +7 -1
-extern void * omap_sram_push(void * start, unsigned long size);
+#include <asm/fncpy.h>
+
+extern void *omap_sram_push_address(unsigned long size);
+
+/* Macro to push a function to the internal SRAM, using the fncpy API */
+#define omap_sram_push(funcp, size) ({ ? ? ? ? ? ? ? ? ? ? ? ? \
+ ? ? ? typeof(&funcp) _res = NULL; ? ? ? ? ? ? ? ? ? ? ? ? ? ? \

1) For fncpy() itself, I decided not to take the address of funcp inside the macro: the reason for this was that if you do this, the macro will silently do something silly if called with a function pointer instead of the function itself -- i.e., some memory starting at the stored function pointer itself will be copied instead of the function body.

Quoted 6 lines

Forcing the caller to supply the '&' is a bit ugly, but I decided it was preferable from a safety standpoint.

This doesn't necessarily mean that omap_sram_push can't add the '&', but if you do, you need to be careful how the macro is called. ?It will work for all existing uses of omap_sram_push, IIUC.

I am OK with that.
In the first place it was not obvious that the '&' was needed but the compiler quickly reminded me about it. The type checking is one of the advantages of the new API.

Quoted 9 lines

2) Should this be &(funcp)? ?This will only matter for pretty weird uses though. ?Currently most weird uses won't work properly anyway, because of (1). ?So this might not be much of a concern.

Quoted 3 lines

+ ? ? ? void *_sram_address = omap_sram_push_address(size); ? ? \
+ ? ? ? if (_sram_address) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
+ ? ? ? ? ? ? ? _res = fncpy(_sram_address, &funcp, size); ? ? ?\

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

&(funcp)

Yes that is correct but the current code does not have problem since the functions to push have 'non-weird' types.
If needed I can change that.

Fair enough. Because of the way omap_sram_push is used I think this isn't a significant risk -- just thought it was worth pointing out.

OK!
Just sent an extra patch '[PATCH] OMAP: fix fncpy API call' for completeness.

Quoted 3 lines

Cheers
---Dave

Cheers,
Jean