summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/sleep.S
diff options
context:
space:
mode:
authorHyung Taek Ryoo <hryoo@nvidia.com>2012-07-31 15:43:34 -0700
committerSimone Willett <swillett@nvidia.com>2012-08-06 12:12:31 -0700
commit9bf22a62cd071336282e3fa5d999f898e77119d1 (patch)
tree123fcf5de57343f49ff6d07639235d82e04e0a87 /arch/arm/mach-tegra/sleep.S
parent76fd6572b00e780a2a00cc2ee21b9f30d968cb5e (diff)
arm: tegra: optimize L2 enable/disable paths for secureos
For the CONFIG_TRUSTED_FOUNDATION code paths, differentiate L2 enable vs. reenable, which are different SMCs (won't trigger an invalidate in the case of a reenable). On an L2 disable SMC, optionally pass a 0 for the L2 ways arg, which skips the full clean/invalidate (and simply just disabled the L2). In order to safely skip flushing the L2 on the disable, we have to be careful what we dirty from the type we flush the L1 and disable the L2. Bug 939415 Signed-off-by: Chris Johnson<cwj@nvidia.com> Change-Id: I756d2ceda83d5d8d6bc5670218e9d874d5e5f62a Reviewed-on: http://git-master/r/119786 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/sleep.S')
-rw-r--r--arch/arm/mach-tegra/sleep.S79
1 files changed, 67 insertions, 12 deletions
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
index 973c8677bafe..e86795c5c46a 100644
--- a/arch/arm/mach-tegra/sleep.S
+++ b/arch/arm/mach-tegra/sleep.S
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/sleep.S
*
- * Copyright (c) 2010-2011, NVIDIA Corporation.
+ * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
* Copyright (c) 2011, Google, Inc.
*
* Author: Colin Cross <ccross@android.com>
@@ -440,28 +440,83 @@ ENDPROC(tegra_cpu_pllp)
#endif
#ifdef CONFIG_TRUSTED_FOUNDATIONS
+
/*
- * tegra_generic_smc
+ * Confirm we're issuing this SMC from CPU0 (only one
+ * currently supported) and issue the instruction.
*
* r0 = smc type
* r1 = smc subtype
* r2 = argument passed to smc
- *
- * issues SMC (secure monitor call) instruction with
- * the specified parameters.
*/
-ENTRY(tegra_generic_smc)
- adr r3, __tegra_smc_stack
- stmia r3, {r4-r12, lr}
+.macro smc_issue_smc tmp
+ cpu_id \tmp
+ cmp \tmp, #0
+ bne .
mov r3, #0
mov r4, #0
dsb
smc #0
- adr r3, __tegra_smc_stack
- ldmia r3, {r4-r12, pc}
+.endm
+
+/*
+ * Issue SMC with ctx kept on an uncached stack
+ */
+ENTRY(tegra_generic_smc_uncached)
+#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_CACHE_L2X0)
+ mov32 r3, tegra_cpu_context @ borrow CPU0's non-cached
+ ldr r3, [r3] @ context grows up
+ stmia r3, {r4-r12, sp, lr}
+
+ smc_issue_smc r5
+
+ mov32 r3, tegra_cpu_context @ borrow CPU0's non-cached
+ ldr r3, [r3] @ context grows up
+ ldmia r3, {r4-r12, sp, pc}
+#else
+ mov pc, lr
+#endif
+ENDPROC(tegra_generic_smc_uncached)
+
+/*
+ * Issue SMC with ctx kept on a cacheable stack
+ * (args in R0, R1, R2 and R3 holds save/restore ptr)
+ */
+ENTRY(tegra_generic_smc_cached)
+ stmia r3, {r4-r12, sp, lr}
+ adr r4, __tegra_smc_current_ctx @ save current ptr
+ str r3, [r4]
+
+ smc_issue_smc r5
+
+ adr r4, __tegra_smc_current_ctx @ restore from saved ptr
+ ldr r3, [r4]
+ ldmia r3, {r4-r12, sp, pc}
+ENDPROC(tegra_generic_smc_cached)
+ .type __tegra_smc_current_ctx, %object
+__tegra_smc_current_ctx:
+ .long 0
+ .size __tegra_smc_current_ctx, . - __tegra_smc_current_ctx
+
+#define TEGRA_SMC_SAVED_WORDS 11
+
+/* SMC issued using the current cacheable SP stack */
+ENTRY(tegra_generic_smc)
+ mov r3, sp @ use current stack
+ sub r3, #(TEGRA_SMC_SAVED_WORDS << 2) @ context grows up
+ b tegra_generic_smc_cached
ENDPROC(tegra_generic_smc)
- .type __tegra_smc_stack, %object
+
+/* SMC issued using a local cacheable stack */
+ENTRY(tegra_generic_smc_local)
+ adr r3, __tegra_smc_stack @ use local stack
+ b tegra_generic_smc_cached
+ENDPROC(tegra_generic_smc_local)
+ .align L1_CACHE_SHIFT
+ .type __tegra_smc_stack, %object
__tegra_smc_stack:
- .long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ .rept TEGRA_SMC_SAVED_WORDS
+ .long 0
+ .endr
.size __tegra_smc_stack, . - __tegra_smc_stack
#endif