xref: /arm-trusted-firmware/lib/psci/aarch64/psci_helpers.S (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu/*
2*91f16700Schasinglulu * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu *
4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu */
6*91f16700Schasinglulu
7*91f16700Schasinglulu#include <asm_macros.S>
8*91f16700Schasinglulu#include <assert_macros.S>
9*91f16700Schasinglulu#include <lib/psci/psci.h>
10*91f16700Schasinglulu#include <platform_def.h>
11*91f16700Schasinglulu
12*91f16700Schasinglulu	.globl	psci_do_pwrdown_cache_maintenance
13*91f16700Schasinglulu	.globl	psci_do_pwrup_cache_maintenance
14*91f16700Schasinglulu	.globl	psci_power_down_wfi
15*91f16700Schasinglulu
16*91f16700Schasinglulu/* -----------------------------------------------------------------------
17*91f16700Schasinglulu * void psci_do_pwrdown_cache_maintenance(unsigned int power level);
18*91f16700Schasinglulu *
19*91f16700Schasinglulu * This function performs cache maintenance for the specified power
20*91f16700Schasinglulu * level. The levels of cache affected are determined by the power
21*91f16700Schasinglulu * level which is passed as the argument i.e. level 0 results
22*91f16700Schasinglulu * in a flush of the L1 cache. Both the L1 and L2 caches are flushed
23*91f16700Schasinglulu * for a higher power level.
24*91f16700Schasinglulu *
25*91f16700Schasinglulu * Additionally, this function also ensures that stack memory is correctly
26*91f16700Schasinglulu * flushed out to avoid coherency issues due to a change in its memory
27*91f16700Schasinglulu * attributes after the data cache is disabled.
28*91f16700Schasinglulu * -----------------------------------------------------------------------
29*91f16700Schasinglulu */
30*91f16700Schasinglulufunc psci_do_pwrdown_cache_maintenance
31*91f16700Schasinglulu	stp     x29, x30, [sp,#-16]!
32*91f16700Schasinglulu	stp     x19, x20, [sp,#-16]!
33*91f16700Schasinglulu
34*91f16700Schasinglulu	/* ---------------------------------------------
35*91f16700Schasinglulu	 * Invoke CPU-specific power down operations for
36*91f16700Schasinglulu	 * the appropriate level
37*91f16700Schasinglulu	 * ---------------------------------------------
38*91f16700Schasinglulu	 */
39*91f16700Schasinglulu	bl	prepare_cpu_pwr_dwn
40*91f16700Schasinglulu
41*91f16700Schasinglulu	/* ---------------------------------------------
42*91f16700Schasinglulu	 * Do stack maintenance by flushing the used
43*91f16700Schasinglulu	 * stack to the main memory and invalidating the
44*91f16700Schasinglulu	 * remainder.
45*91f16700Schasinglulu	 * ---------------------------------------------
46*91f16700Schasinglulu	 */
47*91f16700Schasinglulu	bl	plat_get_my_stack
48*91f16700Schasinglulu
49*91f16700Schasinglulu	/* ---------------------------------------------
50*91f16700Schasinglulu	 * Calculate and store the size of the used
51*91f16700Schasinglulu	 * stack memory in x1.
52*91f16700Schasinglulu	 * ---------------------------------------------
53*91f16700Schasinglulu	 */
54*91f16700Schasinglulu	mov	x19, x0
55*91f16700Schasinglulu	mov	x1, sp
56*91f16700Schasinglulu	sub	x1, x0, x1
57*91f16700Schasinglulu	mov	x0, sp
58*91f16700Schasinglulu	bl	flush_dcache_range
59*91f16700Schasinglulu
60*91f16700Schasinglulu	/* ---------------------------------------------
61*91f16700Schasinglulu	 * Calculate and store the size of the unused
62*91f16700Schasinglulu	 * stack memory in x1. Calculate and store the
63*91f16700Schasinglulu	 * stack base address in x0.
64*91f16700Schasinglulu	 * ---------------------------------------------
65*91f16700Schasinglulu	 */
66*91f16700Schasinglulu	sub	x0, x19, #PLATFORM_STACK_SIZE
67*91f16700Schasinglulu	sub	x1, sp, x0
68*91f16700Schasinglulu	bl	inv_dcache_range
69*91f16700Schasinglulu
70*91f16700Schasinglulu	ldp	x19, x20, [sp], #16
71*91f16700Schasinglulu	ldp	x29, x30, [sp], #16
72*91f16700Schasinglulu	ret
73*91f16700Schasingluluendfunc psci_do_pwrdown_cache_maintenance
74*91f16700Schasinglulu
75*91f16700Schasinglulu
76*91f16700Schasinglulu/* -----------------------------------------------------------------------
77*91f16700Schasinglulu * void psci_do_pwrup_cache_maintenance(void);
78*91f16700Schasinglulu *
79*91f16700Schasinglulu * This function performs cache maintenance after this cpu is powered up.
80*91f16700Schasinglulu * Currently, this involves managing the used stack memory before turning
81*91f16700Schasinglulu * on the data cache.
82*91f16700Schasinglulu * -----------------------------------------------------------------------
83*91f16700Schasinglulu */
84*91f16700Schasinglulufunc psci_do_pwrup_cache_maintenance
85*91f16700Schasinglulu	stp	x29, x30, [sp,#-16]!
86*91f16700Schasinglulu
87*91f16700Schasinglulu	/* ---------------------------------------------
88*91f16700Schasinglulu	 * Ensure any inflight stack writes have made it
89*91f16700Schasinglulu	 * to main memory.
90*91f16700Schasinglulu	 * ---------------------------------------------
91*91f16700Schasinglulu	 */
92*91f16700Schasinglulu	dmb	st
93*91f16700Schasinglulu
94*91f16700Schasinglulu	/* ---------------------------------------------
95*91f16700Schasinglulu	 * Calculate and store the size of the used
96*91f16700Schasinglulu	 * stack memory in x1. Calculate and store the
97*91f16700Schasinglulu	 * stack base address in x0.
98*91f16700Schasinglulu	 * ---------------------------------------------
99*91f16700Schasinglulu	 */
100*91f16700Schasinglulu	bl	plat_get_my_stack
101*91f16700Schasinglulu	mov	x1, sp
102*91f16700Schasinglulu	sub	x1, x0, x1
103*91f16700Schasinglulu	mov	x0, sp
104*91f16700Schasinglulu	bl	inv_dcache_range
105*91f16700Schasinglulu
106*91f16700Schasinglulu	/* ---------------------------------------------
107*91f16700Schasinglulu	 * Enable the data cache.
108*91f16700Schasinglulu	 * ---------------------------------------------
109*91f16700Schasinglulu	 */
110*91f16700Schasinglulu	mrs	x0, sctlr_el3
111*91f16700Schasinglulu	orr	x0, x0, #SCTLR_C_BIT
112*91f16700Schasinglulu	msr	sctlr_el3, x0
113*91f16700Schasinglulu	isb
114*91f16700Schasinglulu
115*91f16700Schasinglulu	ldp	x29, x30, [sp], #16
116*91f16700Schasinglulu	ret
117*91f16700Schasingluluendfunc psci_do_pwrup_cache_maintenance
118*91f16700Schasinglulu
119*91f16700Schasinglulu/* -----------------------------------------------------------------------
120*91f16700Schasinglulu * void psci_power_down_wfi(void);
121*91f16700Schasinglulu * This function is called to indicate to the power controller that it
122*91f16700Schasinglulu * is safe to power down this cpu. It should not exit the wfi and will
123*91f16700Schasinglulu * be released from reset upon power up.
124*91f16700Schasinglulu * -----------------------------------------------------------------------
125*91f16700Schasinglulu */
126*91f16700Schasinglulufunc psci_power_down_wfi
127*91f16700Schasinglulu#if ERRATA_A510_2684597
128*91f16700Schasinglulu	bl apply_cpu_pwr_dwn_errata
129*91f16700Schasinglulu#endif
130*91f16700Schasinglulu	dsb	sy		// ensure write buffer empty
131*91f16700Schasinglulu1:
132*91f16700Schasinglulu	wfi
133*91f16700Schasinglulu	b	1b
134*91f16700Schasingluluendfunc psci_power_down_wfi
135