[PATCHv3 04/20] ARM: OMAP4: PM: update ROM return address for OSWR and OFF

Tero Kristo t-kristo at ti.com
Tue Jun 12 11:31:19 EDT 2012


From: Carlos Leija <cileija at ti.com>

At wakeup from OFF/OSWR CPU1 will call secure HAL service through a local
secure dispatcher with MMU off (from omap-headsmp.S), thus ROM will save
a PA return address. Later in the wakeup, when SMC driver calls an RPC through
omap4_secure_dispatcher (MMU is on now), ROM code won't log the new return
address as RPCs are handled different. Thus ROM will attempt to return to
a PA address when the MMU is on and the system will hang.

We need to do this for OSWR state and OFF state of mpu power domain,
not just for device off(mpu pd OFF).

Original workaround was written by:
  Carlos Leija <cileija at ti.com>
  Praneeth Bajjuri <praneeth at ti.com>
  Bryan Buckley <bryan.buckley at ti.com>

Signed-off-by: Tero Kristo <t-kristo at ti.com>
---
 arch/arm/mach-omap2/include/mach/omap-secure.h |    1 +
 arch/arm/mach-omap2/omap-secure.c              |   36 ++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/include/mach/omap-secure.h b/arch/arm/mach-omap2/include/mach/omap-secure.h
index c90a435..d9bde61 100644
--- a/arch/arm/mach-omap2/include/mach/omap-secure.h
+++ b/arch/arm/mach-omap2/include/mach/omap-secure.h
@@ -43,6 +43,7 @@
 #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
 
 /* Secure PPA(Primary Protected Application) APIs */
+#define OMAP4_PPA_SERVICE_0		0x21
 #define OMAP4_PPA_L2_POR_INDEX		0x23
 #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX	0x25
 
diff --git a/arch/arm/mach-omap2/omap-secure.c b/arch/arm/mach-omap2/omap-secure.c
index d9ae4a5..36ec5a5 100644
--- a/arch/arm/mach-omap2/omap-secure.c
+++ b/arch/arm/mach-omap2/omap-secure.c
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/memblock.h>
+#include <linux/cpu_pm.h>
 
 #include <asm/cacheflush.h>
 #include <asm/memblock.h>
@@ -21,6 +22,8 @@
 #include <plat/omap-secure.h>
 #include <mach/omap-secure.h>
 
+#include "common.h"
+
 static phys_addr_t omap_secure_memblock_base;
 
 /**
@@ -71,3 +74,36 @@ phys_addr_t omap_secure_ram_mempool_base(void)
 {
 	return omap_secure_memblock_base;
 }
+
+#ifdef CONFIG_CPU_PM
+static int secure_notifier(struct notifier_block *self, unsigned long cmd,
+			   void *v)
+{
+	switch (cmd) {
+	case CPU_CLUSTER_PM_EXIT:
+		/*
+		 * Dummy dispatcher call after OSWR and OFF
+		 * Restore the right return Kernel address (with MMU on) for
+		 * subsequent calls to secure ROM. Otherwise the return address
+		 * will be to a PA return address and the system will hang.
+		 */
+		omap_secure_dispatcher(OMAP4_PPA_SERVICE_0,
+				       FLAG_START_CRITICAL,
+				       0, 0, 0, 0, 0);
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block secure_notifier_block = {
+	.notifier_call = secure_notifier,
+};
+
+static int __init secure_pm_init(void)
+{
+	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
+		cpu_pm_register_notifier(&secure_notifier_block);
+	return 0;
+}
+early_initcall(secure_pm_init);
+#endif
-- 
1.7.4.1




More information about the linux-arm-kernel mailing list