xref: /rk3399_ARM-atf/lib/psci/aarch32/psci_helpers.S (revision 232c18929936940ae1d237589872145bec851283)
1/*
2 * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <asm_macros.S>
8#include <lib/psci/psci.h>
9#include <platform_def.h>
10
11	.globl	psci_do_pwrdown_cache_maintenance
12	.globl	psci_do_pwrup_cache_maintenance
13
14/* -----------------------------------------------------------------------
15 * void psci_do_pwrdown_cache_maintenance(unsigned int power level);
16 *
17 * This function performs cache maintenance for the specified power
18 * level. The levels of cache affected are determined by the power
19 * level which is passed as the argument i.e. level 0 results
20 * in a flush of the L1 cache. Both the L1 and L2 caches are flushed
21 * for a higher power level.
22 *
23 * Additionally, this function also ensures that stack memory is correctly
24 * flushed out to avoid coherency issues due to a change in its memory
25 * attributes after the data cache is disabled.
26 * -----------------------------------------------------------------------
27 */
28func psci_do_pwrdown_cache_maintenance
29	push	{r4, lr}
30
31	/* ----------------------------------------------
32	 * Turn OFF cache and do stack maintenance
33	 * prior to cpu operations . This sequence is
34	 * different from AArch64 because in AArch32 the
35	 * assembler routines for cpu operations utilize
36	 * the stack whereas in AArch64 it doesn't.
37	 * ----------------------------------------------
38	 */
39	mov	r4, r0
40	bl	do_stack_maintenance
41
42	/* ---------------------------------------------
43	 * Invoke CPU-specifc power down operations for
44	 * the appropriate level
45	 * ---------------------------------------------
46	 */
47	mov	r0, r4
48	pop	{r4, lr}
49	b	prepare_cpu_pwr_dwn
50endfunc psci_do_pwrdown_cache_maintenance
51
52
53/* -----------------------------------------------------------------------
54 * void psci_do_pwrup_cache_maintenance(void);
55 *
56 * This function performs cache maintenance after this cpu is powered up.
57 * Currently, this involves managing the used stack memory before turning
58 * on the data cache.
59 * -----------------------------------------------------------------------
60 */
61func psci_do_pwrup_cache_maintenance
62	/* r12 is pushed to meet the 8 byte stack alignment requirement */
63	push	{r12, lr}
64
65	/* ---------------------------------------------
66	 * Ensure any inflight stack writes have made it
67	 * to main memory.
68	 * ---------------------------------------------
69	 */
70	dmb	st
71
72	/* ---------------------------------------------
73	 * Calculate and store the size of the used
74	 * stack memory in r1. Calculate and store the
75	 * stack base address in r0.
76	 * ---------------------------------------------
77	 */
78	bl	plat_get_my_stack
79	mov	r1, sp
80	sub	r1, r0, r1
81	mov	r0, sp
82	bl	inv_dcache_range
83
84	/* ---------------------------------------------
85	 * Enable the data cache.
86	 * ---------------------------------------------
87	 */
88	ldcopr	r0, SCTLR
89	orr	r0, r0, #SCTLR_C_BIT
90	stcopr	r0, SCTLR
91	isb
92
93	pop	{r12, pc}
94endfunc psci_do_pwrup_cache_maintenance
95
96	/* ---------------------------------------------
97	 * void do_stack_maintenance(void)
98	 * Do stack maintenance by flushing the used
99	 * stack to the main memory and invalidating the
100	 * remainder.
101	 * ---------------------------------------------
102	 */
103func do_stack_maintenance
104	push	{r4, lr}
105	bl	plat_get_my_stack
106
107	/* Turn off the D-cache */
108	ldcopr	r1, SCTLR
109	bic	r1, #SCTLR_C_BIT
110	stcopr	r1, SCTLR
111	isb
112
113	/* ---------------------------------------------
114	 * Calculate and store the size of the used
115	 * stack memory in r1.
116	 * ---------------------------------------------
117	 */
118	mov	r4, r0
119	mov	r1, sp
120	sub	r1, r0, r1
121	mov	r0, sp
122	bl	flush_dcache_range
123
124	/* ---------------------------------------------
125	 * Calculate and store the size of the unused
126	 * stack memory in r1. Calculate and store the
127	 * stack base address in r0.
128	 * ---------------------------------------------
129	 */
130	sub	r0, r4, #PLATFORM_STACK_SIZE
131	sub	r1, sp, r0
132	bl	inv_dcache_range
133
134	pop	{r4, pc}
135endfunc do_stack_maintenance
136