blob: 05a80f2d4acb3e76a44ecf459a71eeb1b5d88ffa [file] [log] [blame]
Soby Mathew991d42c2015-06-29 16:30:12 +01001/*
2 * Copyright (c) 2014, 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 <arch.h>
32#include <asm_macros.S>
33#include <assert_macros.S>
34#include <platform_def.h>
35#include <psci.h>
36
37 .globl psci_do_pwrdown_cache_maintenance
38 .globl psci_do_pwrup_cache_maintenance
39
40/* -----------------------------------------------------------------------
41 * void psci_do_pwrdown_cache_maintenance(uint32_t affinity level);
42 *
43 * This function performs cache maintenance if the specified affinity
44 * level is the equal to the level of the highest affinity instance which
45 * will be/is physically powered off. The levels of cache affected are
46 * determined by the affinity level which is passed as the argument i.e.
47 * level 0 results in a flush of the L1 cache. Both the L1 and L2 caches
48 * are flushed for a higher affinity level.
49 *
50 * Additionally, this function also ensures that stack memory is correctly
51 * flushed out to avoid coherency issues due to a change in its memory
52 * attributes after the data cache is disabled.
53 * -----------------------------------------------------------------------
54 */
55func psci_do_pwrdown_cache_maintenance
56 stp x29, x30, [sp,#-16]!
57 stp x19, x20, [sp,#-16]!
58
Soby Mathew991d42c2015-06-29 16:30:12 +010059 /* ---------------------------------------------
60 * Determine to how many levels of cache will be
61 * subject to cache maintenance. Affinity level
62 * 0 implies that only the cpu is being powered
63 * down. Only the L1 data cache needs to be
64 * flushed to the PoU in this case. For a higher
65 * affinity level we are assuming that a flush
66 * of L1 data and L2 unified cache is enough.
67 * This information should be provided by the
68 * platform.
69 * ---------------------------------------------
70 */
71 cmp x0, #MPIDR_AFFLVL0
72 b.eq do_core_pwr_dwn
73 bl prepare_cluster_pwr_dwn
74 b do_stack_maintenance
75
76do_core_pwr_dwn:
77 bl prepare_core_pwr_dwn
78
79 /* ---------------------------------------------
80 * Do stack maintenance by flushing the used
81 * stack to the main memory and invalidating the
82 * remainder.
83 * ---------------------------------------------
84 */
85do_stack_maintenance:
86 mrs x0, mpidr_el1
87 bl platform_get_stack
88
89 /* ---------------------------------------------
90 * Calculate and store the size of the used
91 * stack memory in x1.
92 * ---------------------------------------------
93 */
94 mov x19, x0
95 mov x1, sp
96 sub x1, x0, x1
97 mov x0, sp
98 bl flush_dcache_range
99
100 /* ---------------------------------------------
101 * Calculate and store the size of the unused
102 * stack memory in x1. Calculate and store the
103 * stack base address in x0.
104 * ---------------------------------------------
105 */
106 sub x0, x19, #PLATFORM_STACK_SIZE
107 sub x1, sp, x0
108 bl inv_dcache_range
109
Soby Mathew991d42c2015-06-29 16:30:12 +0100110 ldp x19, x20, [sp], #16
111 ldp x29, x30, [sp], #16
112 ret
113endfunc psci_do_pwrdown_cache_maintenance
114
115
116/* -----------------------------------------------------------------------
117 * void psci_do_pwrup_cache_maintenance(void);
118 *
119 * This function performs cache maintenance after this cpu is powered up.
120 * Currently, this involves managing the used stack memory before turning
121 * on the data cache.
122 * -----------------------------------------------------------------------
123 */
124func psci_do_pwrup_cache_maintenance
125 stp x29, x30, [sp,#-16]!
126
127 /* ---------------------------------------------
128 * Ensure any inflight stack writes have made it
129 * to main memory.
130 * ---------------------------------------------
131 */
132 dmb st
133
134 /* ---------------------------------------------
135 * Calculate and store the size of the used
136 * stack memory in x1. Calculate and store the
137 * stack base address in x0.
138 * ---------------------------------------------
139 */
140 mrs x0, mpidr_el1
141 bl platform_get_stack
142 mov x1, sp
143 sub x1, x0, x1
144 mov x0, sp
145 bl inv_dcache_range
146
147 /* ---------------------------------------------
148 * Enable the data cache.
149 * ---------------------------------------------
150 */
151 mrs x0, sctlr_el3
152 orr x0, x0, #SCTLR_C_BIT
153 msr sctlr_el3, x0
154 isb
155
156 ldp x29, x30, [sp], #16
157 ret
158endfunc psci_do_pwrup_cache_maintenance