blob: 4e1013cfb848bad5b1e582a4fa5f64395af0ba71 [file] [log] [blame]
Soby Mathew89d90dc2016-05-05 14:11:23 +01001/*
Govindraj Rajaeee28e72023-08-01 15:52:40 -05002 * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
Soby Mathew89d90dc2016-05-05 14:11:23 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Soby Mathew89d90dc2016-05-05 14:11:23 +01005 */
6
7#include <asm_macros.S>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008#include <lib/psci/psci.h>
Soby Mathew89d90dc2016-05-05 14:11:23 +01009#include <platform_def.h>
Soby Mathew89d90dc2016-05-05 14:11:23 +010010
11 .globl psci_do_pwrdown_cache_maintenance
12 .globl psci_do_pwrup_cache_maintenance
13 .globl psci_power_down_wfi
14
15/* -----------------------------------------------------------------------
16 * void psci_do_pwrdown_cache_maintenance(unsigned int power level);
17 *
18 * This function performs cache maintenance for the specified power
19 * level. The levels of cache affected are determined by the power
20 * level which is passed as the argument i.e. level 0 results
21 * in a flush of the L1 cache. Both the L1 and L2 caches are flushed
22 * for a higher power level.
23 *
24 * Additionally, this function also ensures that stack memory is correctly
25 * flushed out to avoid coherency issues due to a change in its memory
26 * attributes after the data cache is disabled.
27 * -----------------------------------------------------------------------
28 */
29func psci_do_pwrdown_cache_maintenance
30 push {r4, lr}
31
32 /* ----------------------------------------------
33 * Turn OFF cache and do stack maintenance
34 * prior to cpu operations . This sequence is
35 * different from AArch64 because in AArch32 the
36 * assembler routines for cpu operations utilize
37 * the stack whereas in AArch64 it doesn't.
38 * ----------------------------------------------
39 */
40 mov r4, r0
41 bl do_stack_maintenance
42
43 /* ---------------------------------------------
Jeenu Viswambharanee5eb802016-11-18 12:58:28 +000044 * Invoke CPU-specifc power down operations for
45 * the appropriate level
Soby Mathew89d90dc2016-05-05 14:11:23 +010046 * ---------------------------------------------
47 */
Jeenu Viswambharanee5eb802016-11-18 12:58:28 +000048 mov r0, r4
49 pop {r4, lr}
50 b prepare_cpu_pwr_dwn
Soby Mathew89d90dc2016-05-05 14:11:23 +010051endfunc psci_do_pwrdown_cache_maintenance
52
53
54/* -----------------------------------------------------------------------
55 * void psci_do_pwrup_cache_maintenance(void);
56 *
57 * This function performs cache maintenance after this cpu is powered up.
58 * Currently, this involves managing the used stack memory before turning
59 * on the data cache.
60 * -----------------------------------------------------------------------
61 */
62func psci_do_pwrup_cache_maintenance
Soby Mathewadb70272016-12-06 12:10:51 +000063 /* r12 is pushed to meet the 8 byte stack alignment requirement */
64 push {r12, lr}
Soby Mathew89d90dc2016-05-05 14:11:23 +010065
66 /* ---------------------------------------------
67 * Ensure any inflight stack writes have made it
68 * to main memory.
69 * ---------------------------------------------
70 */
71 dmb st
72
73 /* ---------------------------------------------
74 * Calculate and store the size of the used
75 * stack memory in r1. Calculate and store the
76 * stack base address in r0.
77 * ---------------------------------------------
78 */
79 bl plat_get_my_stack
80 mov r1, sp
81 sub r1, r0, r1
82 mov r0, sp
83 bl inv_dcache_range
84
85 /* ---------------------------------------------
86 * Enable the data cache.
87 * ---------------------------------------------
88 */
89 ldcopr r0, SCTLR
90 orr r0, r0, #SCTLR_C_BIT
91 stcopr r0, SCTLR
92 isb
93
Soby Mathewadb70272016-12-06 12:10:51 +000094 pop {r12, pc}
Soby Mathew89d90dc2016-05-05 14:11:23 +010095endfunc psci_do_pwrup_cache_maintenance
96
97 /* ---------------------------------------------
98 * void do_stack_maintenance(void)
99 * Do stack maintenance by flushing the used
100 * stack to the main memory and invalidating the
101 * remainder.
102 * ---------------------------------------------
103 */
104func do_stack_maintenance
105 push {r4, lr}
106 bl plat_get_my_stack
107
108 /* Turn off the D-cache */
109 ldcopr r1, SCTLR
110 bic r1, #SCTLR_C_BIT
111 stcopr r1, SCTLR
112 isb
113
114 /* ---------------------------------------------
115 * Calculate and store the size of the used
116 * stack memory in r1.
117 * ---------------------------------------------
118 */
119 mov r4, r0
120 mov r1, sp
121 sub r1, r0, r1
122 mov r0, sp
123 bl flush_dcache_range
124
125 /* ---------------------------------------------
126 * Calculate and store the size of the unused
127 * stack memory in r1. Calculate and store the
128 * stack base address in r0.
129 * ---------------------------------------------
130 */
131 sub r0, r4, #PLATFORM_STACK_SIZE
132 sub r1, sp, r0
133 bl inv_dcache_range
134
135 pop {r4, pc}
136endfunc do_stack_maintenance
137
138/* -----------------------------------------------------------------------
139 * This function is called to indicate to the power controller that it
140 * is safe to power down this cpu. It should not exit the wfi and will
141 * be released from reset upon power up.
142 * -----------------------------------------------------------------------
143 */
144func psci_power_down_wfi
145 dsb sy // ensure write buffer empty
Harrison Mutai263c6472023-01-11 17:01:04 +00001461:
Soby Mathew89d90dc2016-05-05 14:11:23 +0100147 wfi
Harrison Mutai263c6472023-01-11 17:01:04 +0000148 b 1b
Soby Mathew89d90dc2016-05-05 14:11:23 +0100149endfunc psci_power_down_wfi