blob: a29a29c4937bb9e544df156c212066641d5778d4 [file] [log] [blame]
Soby Mathew89d90dc2016-05-05 14:11:23 +01001/*
Antonio Nino Diaz9f2f8ef2018-02-19 16:27:06 +00002 * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
Soby Mathew89d90dc2016-05-05 14:11:23 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Soby Mathew89d90dc2016-05-05 14:11:23 +01005 */
6
7#include <asm_macros.S>
8#include <platform_def.h>
9#include <psci.h>
10
11 .globl psci_do_pwrdown_cache_maintenance
12 .globl psci_do_pwrup_cache_maintenance
13 .globl psci_power_down_wfi
14
15/* -----------------------------------------------------------------------
16 * void psci_do_pwrdown_cache_maintenance(unsigned int power level);
17 *
18 * This function performs cache maintenance for the specified power
19 * level. The levels of cache affected are determined by the power
20 * level which is passed as the argument i.e. level 0 results
21 * in a flush of the L1 cache. Both the L1 and L2 caches are flushed
22 * for a higher power level.
23 *
24 * Additionally, this function also ensures that stack memory is correctly
25 * flushed out to avoid coherency issues due to a change in its memory
26 * attributes after the data cache is disabled.
27 * -----------------------------------------------------------------------
28 */
29func psci_do_pwrdown_cache_maintenance
30 push {r4, lr}
31
32 /* ----------------------------------------------
33 * Turn OFF cache and do stack maintenance
34 * prior to cpu operations . This sequence is
35 * different from AArch64 because in AArch32 the
36 * assembler routines for cpu operations utilize
37 * the stack whereas in AArch64 it doesn't.
38 * ----------------------------------------------
39 */
40 mov r4, r0
41 bl do_stack_maintenance
42
43 /* ---------------------------------------------
Jeenu Viswambharanee5eb802016-11-18 12:58:28 +000044 * Invoke CPU-specifc power down operations for
45 * the appropriate level
Soby Mathew89d90dc2016-05-05 14:11:23 +010046 * ---------------------------------------------
47 */
Jeenu Viswambharanee5eb802016-11-18 12:58:28 +000048 mov r0, r4
49 pop {r4, lr}
50 b prepare_cpu_pwr_dwn
Soby Mathew89d90dc2016-05-05 14:11:23 +010051endfunc psci_do_pwrdown_cache_maintenance
52
53
54/* -----------------------------------------------------------------------
55 * void psci_do_pwrup_cache_maintenance(void);
56 *
57 * This function performs cache maintenance after this cpu is powered up.
58 * Currently, this involves managing the used stack memory before turning
59 * on the data cache.
60 * -----------------------------------------------------------------------
61 */
62func psci_do_pwrup_cache_maintenance
Soby Mathewadb70272016-12-06 12:10:51 +000063 /* r12 is pushed to meet the 8 byte stack alignment requirement */
64 push {r12, lr}
Soby Mathew89d90dc2016-05-05 14:11:23 +010065
66 /* ---------------------------------------------
67 * Ensure any inflight stack writes have made it
68 * to main memory.
69 * ---------------------------------------------
70 */
71 dmb st
72
73 /* ---------------------------------------------
74 * Calculate and store the size of the used
75 * stack memory in r1. Calculate and store the
76 * stack base address in r0.
77 * ---------------------------------------------
78 */
79 bl plat_get_my_stack
80 mov r1, sp
81 sub r1, r0, r1
82 mov r0, sp
83 bl inv_dcache_range
84
85 /* ---------------------------------------------
86 * Enable the data cache.
87 * ---------------------------------------------
88 */
89 ldcopr r0, SCTLR
90 orr r0, r0, #SCTLR_C_BIT
91 stcopr r0, SCTLR
92 isb
93
Antonio Nino Diaz9f2f8ef2018-02-19 16:27:06 +000094#if PLAT_XLAT_TABLES_DYNAMIC
95 /* ---------------------------------------------
96 * During warm boot the MMU is enabled with data
97 * cache disabled, then the interconnect is set
98 * up and finally the data cache is enabled.
99 *
100 * During this period, if another CPU modifies
101 * the translation tables, the MMU table walker
102 * may read the old entries. This is only a
103 * problem for dynamic regions, the warm boot
104 * code isn't affected because it is static.
105 *
106 * Invalidate all TLB entries loaded while the
107 * CPU wasn't coherent with the rest of the
108 * system.
109 * ---------------------------------------------
110 */
111 stcopr r0, TLBIALL
112 dsb ish
113 isb
114#endif
115
Soby Mathewadb70272016-12-06 12:10:51 +0000116 pop {r12, pc}
Soby Mathew89d90dc2016-05-05 14:11:23 +0100117endfunc psci_do_pwrup_cache_maintenance
118
119 /* ---------------------------------------------
120 * void do_stack_maintenance(void)
121 * Do stack maintenance by flushing the used
122 * stack to the main memory and invalidating the
123 * remainder.
124 * ---------------------------------------------
125 */
126func do_stack_maintenance
127 push {r4, lr}
128 bl plat_get_my_stack
129
130 /* Turn off the D-cache */
131 ldcopr r1, SCTLR
132 bic r1, #SCTLR_C_BIT
133 stcopr r1, SCTLR
134 isb
135
136 /* ---------------------------------------------
137 * Calculate and store the size of the used
138 * stack memory in r1.
139 * ---------------------------------------------
140 */
141 mov r4, r0
142 mov r1, sp
143 sub r1, r0, r1
144 mov r0, sp
145 bl flush_dcache_range
146
147 /* ---------------------------------------------
148 * Calculate and store the size of the unused
149 * stack memory in r1. Calculate and store the
150 * stack base address in r0.
151 * ---------------------------------------------
152 */
153 sub r0, r4, #PLATFORM_STACK_SIZE
154 sub r1, sp, r0
155 bl inv_dcache_range
156
157 pop {r4, pc}
158endfunc do_stack_maintenance
159
160/* -----------------------------------------------------------------------
161 * This function is called to indicate to the power controller that it
162 * is safe to power down this cpu. It should not exit the wfi and will
163 * be released from reset upon power up.
164 * -----------------------------------------------------------------------
165 */
166func psci_power_down_wfi
167 dsb sy // ensure write buffer empty
168 wfi
Jeenu Viswambharan68aef102016-11-30 15:21:11 +0000169 no_ret plat_panic_handler
Soby Mathew89d90dc2016-05-05 14:11:23 +0100170endfunc psci_power_down_wfi