blob: 9f991dfe4b7b94fb2b45a037a42884a908983d3d [file] [log] [blame]
Soby Mathew89d90dc2016-05-05 14:11:23 +01001/*
2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <asm_macros.S>
32#include <platform_def.h>
33#include <psci.h>
34
35 .globl psci_do_pwrdown_cache_maintenance
36 .globl psci_do_pwrup_cache_maintenance
37 .globl psci_power_down_wfi
38
39/* -----------------------------------------------------------------------
40 * void psci_do_pwrdown_cache_maintenance(unsigned int power level);
41 *
42 * This function performs cache maintenance for the specified power
43 * level. The levels of cache affected are determined by the power
44 * level which is passed as the argument i.e. level 0 results
45 * in a flush of the L1 cache. Both the L1 and L2 caches are flushed
46 * for a higher power level.
47 *
48 * Additionally, this function also ensures that stack memory is correctly
49 * flushed out to avoid coherency issues due to a change in its memory
50 * attributes after the data cache is disabled.
51 * -----------------------------------------------------------------------
52 */
53func psci_do_pwrdown_cache_maintenance
54 push {r4, lr}
55
56 /* ----------------------------------------------
57 * Turn OFF cache and do stack maintenance
58 * prior to cpu operations . This sequence is
59 * different from AArch64 because in AArch32 the
60 * assembler routines for cpu operations utilize
61 * the stack whereas in AArch64 it doesn't.
62 * ----------------------------------------------
63 */
64 mov r4, r0
65 bl do_stack_maintenance
66
67 /* ---------------------------------------------
Jeenu Viswambharanee5eb802016-11-18 12:58:28 +000068 * Invoke CPU-specifc power down operations for
69 * the appropriate level
Soby Mathew89d90dc2016-05-05 14:11:23 +010070 * ---------------------------------------------
71 */
Jeenu Viswambharanee5eb802016-11-18 12:58:28 +000072 mov r0, r4
73 pop {r4, lr}
74 b prepare_cpu_pwr_dwn
Soby Mathew89d90dc2016-05-05 14:11:23 +010075endfunc psci_do_pwrdown_cache_maintenance
76
77
78/* -----------------------------------------------------------------------
79 * void psci_do_pwrup_cache_maintenance(void);
80 *
81 * This function performs cache maintenance after this cpu is powered up.
82 * Currently, this involves managing the used stack memory before turning
83 * on the data cache.
84 * -----------------------------------------------------------------------
85 */
86func psci_do_pwrup_cache_maintenance
Soby Mathewadb70272016-12-06 12:10:51 +000087 /* r12 is pushed to meet the 8 byte stack alignment requirement */
88 push {r12, lr}
Soby Mathew89d90dc2016-05-05 14:11:23 +010089
90 /* ---------------------------------------------
91 * Ensure any inflight stack writes have made it
92 * to main memory.
93 * ---------------------------------------------
94 */
95 dmb st
96
97 /* ---------------------------------------------
98 * Calculate and store the size of the used
99 * stack memory in r1. Calculate and store the
100 * stack base address in r0.
101 * ---------------------------------------------
102 */
103 bl plat_get_my_stack
104 mov r1, sp
105 sub r1, r0, r1
106 mov r0, sp
107 bl inv_dcache_range
108
109 /* ---------------------------------------------
110 * Enable the data cache.
111 * ---------------------------------------------
112 */
113 ldcopr r0, SCTLR
114 orr r0, r0, #SCTLR_C_BIT
115 stcopr r0, SCTLR
116 isb
117
Soby Mathewadb70272016-12-06 12:10:51 +0000118 pop {r12, pc}
Soby Mathew89d90dc2016-05-05 14:11:23 +0100119endfunc psci_do_pwrup_cache_maintenance
120
121 /* ---------------------------------------------
122 * void do_stack_maintenance(void)
123 * Do stack maintenance by flushing the used
124 * stack to the main memory and invalidating the
125 * remainder.
126 * ---------------------------------------------
127 */
128func do_stack_maintenance
129 push {r4, lr}
130 bl plat_get_my_stack
131
132 /* Turn off the D-cache */
133 ldcopr r1, SCTLR
134 bic r1, #SCTLR_C_BIT
135 stcopr r1, SCTLR
136 isb
137
138 /* ---------------------------------------------
139 * Calculate and store the size of the used
140 * stack memory in r1.
141 * ---------------------------------------------
142 */
143 mov r4, r0
144 mov r1, sp
145 sub r1, r0, r1
146 mov r0, sp
147 bl flush_dcache_range
148
149 /* ---------------------------------------------
150 * Calculate and store the size of the unused
151 * stack memory in r1. Calculate and store the
152 * stack base address in r0.
153 * ---------------------------------------------
154 */
155 sub r0, r4, #PLATFORM_STACK_SIZE
156 sub r1, sp, r0
157 bl inv_dcache_range
158
159 pop {r4, pc}
160endfunc do_stack_maintenance
161
162/* -----------------------------------------------------------------------
163 * This function is called to indicate to the power controller that it
164 * is safe to power down this cpu. It should not exit the wfi and will
165 * be released from reset upon power up.
166 * -----------------------------------------------------------------------
167 */
168func psci_power_down_wfi
169 dsb sy // ensure write buffer empty
170 wfi
Jeenu Viswambharan68aef102016-11-30 15:21:11 +0000171 no_ret plat_panic_handler
Soby Mathew89d90dc2016-05-05 14:11:23 +0100172endfunc psci_power_down_wfi