xref: /rk3399_ARM-atf/lib/psci/aarch64/psci_helpers.S (revision a806dad58c4cf752238d7bbffbc9a1ce17f63cea)
1/*
2 * Copyright (c) 2014-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 <assert_macros.S>
33#include <platform_def.h>
34#include <psci.h>
35
36	.globl	psci_do_pwrdown_cache_maintenance
37	.globl	psci_do_pwrup_cache_maintenance
38	.globl	psci_power_down_wfi
39#if !ERROR_DEPRECATED
40	.globl psci_entrypoint
41#endif
42
43/* -----------------------------------------------------------------------
44 * void psci_do_pwrdown_cache_maintenance(unsigned int power level);
45 *
46 * This function performs cache maintenance for the specified power
47 * level. The levels of cache affected are determined by the power
48 * level which is passed as the argument i.e. level 0 results
49 * in a flush of the L1 cache. Both the L1 and L2 caches are flushed
50 * for a higher power level.
51 *
52 * Additionally, this function also ensures that stack memory is correctly
53 * flushed out to avoid coherency issues due to a change in its memory
54 * attributes after the data cache is disabled.
55 * -----------------------------------------------------------------------
56 */
57func psci_do_pwrdown_cache_maintenance
58	stp     x29, x30, [sp,#-16]!
59	stp     x19, x20, [sp,#-16]!
60
61	/* ---------------------------------------------
62	 * Determine to how many levels of cache will be
63	 * subject to cache maintenance. Power level
64	 * 0 implies that only the cpu is being powered
65	 * down. Only the L1 data cache needs to be
66	 * flushed to the PoU in this case. For a higher
67	 * power level we are assuming that a flush
68	 * of L1 data and L2 unified cache is enough.
69	 * This information should be provided by the
70	 * platform.
71	 * ---------------------------------------------
72	 */
73	cmp	w0, #PSCI_CPU_PWR_LVL
74	b.eq	do_core_pwr_dwn
75	bl	prepare_cluster_pwr_dwn
76	b	do_stack_maintenance
77
78do_core_pwr_dwn:
79	bl	prepare_core_pwr_dwn
80
81	/* ---------------------------------------------
82	 * Do stack maintenance by flushing the used
83	 * stack to the main memory and invalidating the
84	 * remainder.
85	 * ---------------------------------------------
86	 */
87do_stack_maintenance:
88	bl	plat_get_my_stack
89
90	/* ---------------------------------------------
91	 * Calculate and store the size of the used
92	 * stack memory in x1.
93	 * ---------------------------------------------
94	 */
95	mov	x19, x0
96	mov	x1, sp
97	sub	x1, x0, x1
98	mov	x0, sp
99	bl	flush_dcache_range
100
101	/* ---------------------------------------------
102	 * Calculate and store the size of the unused
103	 * stack memory in x1. Calculate and store the
104	 * stack base address in x0.
105	 * ---------------------------------------------
106	 */
107	sub	x0, x19, #PLATFORM_STACK_SIZE
108	sub	x1, sp, x0
109	bl	inv_dcache_range
110
111	ldp	x19, x20, [sp], #16
112	ldp	x29, x30, [sp], #16
113	ret
114endfunc psci_do_pwrdown_cache_maintenance
115
116
117/* -----------------------------------------------------------------------
118 * void psci_do_pwrup_cache_maintenance(void);
119 *
120 * This function performs cache maintenance after this cpu is powered up.
121 * Currently, this involves managing the used stack memory before turning
122 * on the data cache.
123 * -----------------------------------------------------------------------
124 */
125func psci_do_pwrup_cache_maintenance
126	stp	x29, x30, [sp,#-16]!
127
128	/* ---------------------------------------------
129	 * Ensure any inflight stack writes have made it
130	 * to main memory.
131	 * ---------------------------------------------
132	 */
133	dmb	st
134
135	/* ---------------------------------------------
136	 * Calculate and store the size of the used
137	 * stack memory in x1. Calculate and store the
138	 * stack base address in x0.
139	 * ---------------------------------------------
140	 */
141	bl	plat_get_my_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
159
160/* -----------------------------------------------------------------------
161 * void psci_power_down_wfi(void);
162 * This function is called to indicate to the power controller that it
163 * is safe to power down this cpu. It should not exit the wfi and will
164 * be released from reset upon power up.
165 * -----------------------------------------------------------------------
166 */
167func psci_power_down_wfi
168	dsb	sy		// ensure write buffer empty
169	wfi
170	no_ret	plat_panic_handler
171endfunc psci_power_down_wfi
172
173/* -----------------------------------------------------------------------
174 * void psci_entrypoint(void);
175 * The deprecated entry point for PSCI on warm boot for AArch64.
176 * -----------------------------------------------------------------------
177 */
178func_deprecated psci_entrypoint
179	b	bl31_warm_entrypoint
180endfunc_deprecated psci_entrypoint
181