xref: /rk3399_ARM-atf/lib/psci/aarch32/psci_helpers.S (revision 264410306381d4edceeb03b3a0e8db66605427be)
1727e5238SSoby Mathew/*
2*26441030SAntonio Nino Diaz * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
3727e5238SSoby Mathew *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
5727e5238SSoby Mathew */
6727e5238SSoby Mathew
7727e5238SSoby Mathew#include <asm_macros.S>
8727e5238SSoby Mathew#include <platform_def.h>
9727e5238SSoby Mathew#include <psci.h>
10727e5238SSoby Mathew
11727e5238SSoby Mathew	.globl	psci_do_pwrdown_cache_maintenance
12727e5238SSoby Mathew	.globl	psci_do_pwrup_cache_maintenance
13727e5238SSoby Mathew	.globl	psci_power_down_wfi
14727e5238SSoby Mathew
15727e5238SSoby Mathew/* -----------------------------------------------------------------------
16727e5238SSoby Mathew * void psci_do_pwrdown_cache_maintenance(unsigned int power level);
17727e5238SSoby Mathew *
18727e5238SSoby Mathew * This function performs cache maintenance for the specified power
19727e5238SSoby Mathew * level. The levels of cache affected are determined by the power
20727e5238SSoby Mathew * level which is passed as the argument i.e. level 0 results
21727e5238SSoby Mathew * in a flush of the L1 cache. Both the L1 and L2 caches are flushed
22727e5238SSoby Mathew * for a higher power level.
23727e5238SSoby Mathew *
24727e5238SSoby Mathew * Additionally, this function also ensures that stack memory is correctly
25727e5238SSoby Mathew * flushed out to avoid coherency issues due to a change in its memory
26727e5238SSoby Mathew * attributes after the data cache is disabled.
27727e5238SSoby Mathew * -----------------------------------------------------------------------
28727e5238SSoby Mathew */
29727e5238SSoby Mathewfunc psci_do_pwrdown_cache_maintenance
30727e5238SSoby Mathew	push	{r4, lr}
31727e5238SSoby Mathew
32727e5238SSoby Mathew	/* ----------------------------------------------
33727e5238SSoby Mathew	 * Turn OFF cache and do stack maintenance
34727e5238SSoby Mathew	 * prior to cpu operations . This sequence is
35727e5238SSoby Mathew	 * different from AArch64 because in AArch32 the
36727e5238SSoby Mathew	 * assembler routines for cpu operations utilize
37727e5238SSoby Mathew	 * the stack whereas in AArch64 it doesn't.
38727e5238SSoby Mathew	 * ----------------------------------------------
39727e5238SSoby Mathew	 */
40727e5238SSoby Mathew	mov	r4, r0
41727e5238SSoby Mathew	bl	do_stack_maintenance
42727e5238SSoby Mathew
43727e5238SSoby Mathew	/* ---------------------------------------------
445dd9dbb5SJeenu Viswambharan	 * Invoke CPU-specifc power down operations for
455dd9dbb5SJeenu Viswambharan	 * the appropriate level
46727e5238SSoby Mathew	 * ---------------------------------------------
47727e5238SSoby Mathew	 */
485dd9dbb5SJeenu Viswambharan	mov	r0, r4
49727e5238SSoby Mathew	pop	{r4, lr}
505dd9dbb5SJeenu Viswambharan	b	prepare_cpu_pwr_dwn
51727e5238SSoby Mathewendfunc psci_do_pwrdown_cache_maintenance
52727e5238SSoby Mathew
53727e5238SSoby Mathew
54727e5238SSoby Mathew/* -----------------------------------------------------------------------
55727e5238SSoby Mathew * void psci_do_pwrup_cache_maintenance(void);
56727e5238SSoby Mathew *
57727e5238SSoby Mathew * This function performs cache maintenance after this cpu is powered up.
58727e5238SSoby Mathew * Currently, this involves managing the used stack memory before turning
59727e5238SSoby Mathew * on the data cache.
60727e5238SSoby Mathew * -----------------------------------------------------------------------
61727e5238SSoby Mathew */
62727e5238SSoby Mathewfunc psci_do_pwrup_cache_maintenance
639f3ee61cSSoby Mathew	/* r12 is pushed to meet the 8 byte stack alignment requirement */
649f3ee61cSSoby Mathew	push	{r12, lr}
65727e5238SSoby Mathew
66727e5238SSoby Mathew	/* ---------------------------------------------
67727e5238SSoby Mathew	 * Ensure any inflight stack writes have made it
68727e5238SSoby Mathew	 * to main memory.
69727e5238SSoby Mathew	 * ---------------------------------------------
70727e5238SSoby Mathew	 */
71727e5238SSoby Mathew	dmb	st
72727e5238SSoby Mathew
73727e5238SSoby Mathew	/* ---------------------------------------------
74727e5238SSoby Mathew	 * Calculate and store the size of the used
75727e5238SSoby Mathew	 * stack memory in r1. Calculate and store the
76727e5238SSoby Mathew	 * stack base address in r0.
77727e5238SSoby Mathew	 * ---------------------------------------------
78727e5238SSoby Mathew	 */
79727e5238SSoby Mathew	bl	plat_get_my_stack
80727e5238SSoby Mathew	mov	r1, sp
81727e5238SSoby Mathew	sub	r1, r0, r1
82727e5238SSoby Mathew	mov	r0, sp
83727e5238SSoby Mathew	bl	inv_dcache_range
84727e5238SSoby Mathew
85727e5238SSoby Mathew	/* ---------------------------------------------
86727e5238SSoby Mathew	 * Enable the data cache.
87727e5238SSoby Mathew	 * ---------------------------------------------
88727e5238SSoby Mathew	 */
89727e5238SSoby Mathew	ldcopr	r0, SCTLR
90727e5238SSoby Mathew	orr	r0, r0, #SCTLR_C_BIT
91727e5238SSoby Mathew	stcopr	r0, SCTLR
92727e5238SSoby Mathew	isb
93727e5238SSoby Mathew
94*26441030SAntonio Nino Diaz#if PLAT_XLAT_TABLES_DYNAMIC
95*26441030SAntonio Nino Diaz	/* ---------------------------------------------
96*26441030SAntonio Nino Diaz	 * During warm boot the MMU is enabled with data
97*26441030SAntonio Nino Diaz	 * cache disabled, then the interconnect is set
98*26441030SAntonio Nino Diaz	 * up and finally the data cache is enabled.
99*26441030SAntonio Nino Diaz	 *
100*26441030SAntonio Nino Diaz	 * During this period, if another CPU modifies
101*26441030SAntonio Nino Diaz	 * the translation tables, the MMU table walker
102*26441030SAntonio Nino Diaz	 * may read the old entries. This is only a
103*26441030SAntonio Nino Diaz	 * problem for dynamic regions, the warm boot
104*26441030SAntonio Nino Diaz	 * code isn't affected because it is static.
105*26441030SAntonio Nino Diaz	 *
106*26441030SAntonio Nino Diaz	 * Invalidate all TLB entries loaded while the
107*26441030SAntonio Nino Diaz	 * CPU wasn't coherent with the rest of the
108*26441030SAntonio Nino Diaz	 * system.
109*26441030SAntonio Nino Diaz	 * ---------------------------------------------
110*26441030SAntonio Nino Diaz	 */
111*26441030SAntonio Nino Diaz	stcopr	r0, TLBIALL
112*26441030SAntonio Nino Diaz	dsb	ish
113*26441030SAntonio Nino Diaz	isb
114*26441030SAntonio Nino Diaz#endif
115*26441030SAntonio Nino Diaz
1169f3ee61cSSoby Mathew	pop	{r12, pc}
117727e5238SSoby Mathewendfunc psci_do_pwrup_cache_maintenance
118727e5238SSoby Mathew
119727e5238SSoby Mathew	/* ---------------------------------------------
120727e5238SSoby Mathew	 * void do_stack_maintenance(void)
121727e5238SSoby Mathew	 * Do stack maintenance by flushing the used
122727e5238SSoby Mathew	 * stack to the main memory and invalidating the
123727e5238SSoby Mathew	 * remainder.
124727e5238SSoby Mathew	 * ---------------------------------------------
125727e5238SSoby Mathew	 */
126727e5238SSoby Mathewfunc do_stack_maintenance
127727e5238SSoby Mathew	push	{r4, lr}
128727e5238SSoby Mathew	bl	plat_get_my_stack
129727e5238SSoby Mathew
130727e5238SSoby Mathew	/* Turn off the D-cache */
131727e5238SSoby Mathew	ldcopr	r1, SCTLR
132727e5238SSoby Mathew	bic	r1, #SCTLR_C_BIT
133727e5238SSoby Mathew	stcopr	r1, SCTLR
134727e5238SSoby Mathew	isb
135727e5238SSoby Mathew
136727e5238SSoby Mathew	/* ---------------------------------------------
137727e5238SSoby Mathew	 * Calculate and store the size of the used
138727e5238SSoby Mathew	 * stack memory in r1.
139727e5238SSoby Mathew	 * ---------------------------------------------
140727e5238SSoby Mathew	 */
141727e5238SSoby Mathew	mov	r4, r0
142727e5238SSoby Mathew	mov	r1, sp
143727e5238SSoby Mathew	sub	r1, r0, r1
144727e5238SSoby Mathew	mov	r0, sp
145727e5238SSoby Mathew	bl	flush_dcache_range
146727e5238SSoby Mathew
147727e5238SSoby Mathew	/* ---------------------------------------------
148727e5238SSoby Mathew	 * Calculate and store the size of the unused
149727e5238SSoby Mathew	 * stack memory in r1. Calculate and store the
150727e5238SSoby Mathew	 * stack base address in r0.
151727e5238SSoby Mathew	 * ---------------------------------------------
152727e5238SSoby Mathew	 */
153727e5238SSoby Mathew	sub	r0, r4, #PLATFORM_STACK_SIZE
154727e5238SSoby Mathew	sub	r1, sp, r0
155727e5238SSoby Mathew	bl	inv_dcache_range
156727e5238SSoby Mathew
157727e5238SSoby Mathew	pop	{r4, pc}
158727e5238SSoby Mathewendfunc do_stack_maintenance
159727e5238SSoby Mathew
160727e5238SSoby Mathew/* -----------------------------------------------------------------------
161727e5238SSoby Mathew * This function is called to indicate to the power controller that it
162727e5238SSoby Mathew * is safe to power down this cpu. It should not exit the wfi and will
163727e5238SSoby Mathew * be released from reset upon power up.
164727e5238SSoby Mathew * -----------------------------------------------------------------------
165727e5238SSoby Mathew */
166727e5238SSoby Mathewfunc psci_power_down_wfi
167727e5238SSoby Mathew	dsb	sy		// ensure write buffer empty
168727e5238SSoby Mathew	wfi
169a806dad5SJeenu Viswambharan	no_ret	plat_panic_handler
170727e5238SSoby Mathewendfunc psci_power_down_wfi
171