psci_helpers.S 4.25 KB
Newer Older
1
/*
2
 * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
3
 *
dp-arm's avatar
dp-arm committed
4
 * SPDX-License-Identifier: BSD-3-Clause
5
6
7
 */

#include <asm_macros.S>
8
#include <assert_macros.S>
9
#include <platform_def.h>
10
#include <psci.h>
11
12
13

	.globl	psci_do_pwrdown_cache_maintenance
	.globl	psci_do_pwrup_cache_maintenance
Soby Mathew's avatar
Soby Mathew committed
14
15
16
17
	.globl	psci_power_down_wfi
#if !ERROR_DEPRECATED
	.globl psci_entrypoint
#endif
18
19

/* -----------------------------------------------------------------------
20
 * void psci_do_pwrdown_cache_maintenance(unsigned int power level);
21
 *
22
23
24
25
26
 * This function performs cache maintenance for the specified power
 * level. The levels of cache affected are determined by the power
 * level which is passed as the argument i.e. level 0 results
 * in a flush of the L1 cache. Both the L1 and L2 caches are flushed
 * for a higher power level.
27
28
29
30
 *
 * Additionally, this function also ensures that stack memory is correctly
 * flushed out to avoid coherency issues due to a change in its memory
 * attributes after the data cache is disabled.
31
32
33
34
35
36
37
 * -----------------------------------------------------------------------
 */
func psci_do_pwrdown_cache_maintenance
	stp     x29, x30, [sp,#-16]!
	stp     x19, x20, [sp,#-16]!

	/* ---------------------------------------------
38
39
	 * Invoke CPU-specific power down operations for
	 * the appropriate level
40
41
	 * ---------------------------------------------
	 */
42
	bl	prepare_cpu_pwr_dwn
43
44
45
46
47
48
49

	/* ---------------------------------------------
	 * Do stack maintenance by flushing the used
	 * stack to the main memory and invalidating the
	 * remainder.
	 * ---------------------------------------------
	 */
50
	bl	plat_get_my_stack
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

	/* ---------------------------------------------
	 * Calculate and store the size of the used
	 * stack memory in x1.
	 * ---------------------------------------------
	 */
	mov	x19, x0
	mov	x1, sp
	sub	x1, x0, x1
	mov	x0, sp
	bl	flush_dcache_range

	/* ---------------------------------------------
	 * Calculate and store the size of the unused
	 * stack memory in x1. Calculate and store the
	 * stack base address in x0.
	 * ---------------------------------------------
	 */
	sub	x0, x19, #PLATFORM_STACK_SIZE
	sub	x1, sp, x0
	bl	inv_dcache_range

	ldp	x19, x20, [sp], #16
	ldp	x29, x30, [sp], #16
	ret
76
endfunc psci_do_pwrdown_cache_maintenance
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102


/* -----------------------------------------------------------------------
 * void psci_do_pwrup_cache_maintenance(void);
 *
 * This function performs cache maintenance after this cpu is powered up.
 * Currently, this involves managing the used stack memory before turning
 * on the data cache.
 * -----------------------------------------------------------------------
 */
func psci_do_pwrup_cache_maintenance
	stp	x29, x30, [sp,#-16]!

	/* ---------------------------------------------
	 * Ensure any inflight stack writes have made it
	 * to main memory.
	 * ---------------------------------------------
	 */
	dmb	st

	/* ---------------------------------------------
	 * Calculate and store the size of the used
	 * stack memory in x1. Calculate and store the
	 * stack base address in x0.
	 * ---------------------------------------------
	 */
103
	bl	plat_get_my_stack
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
	mov	x1, sp
	sub	x1, x0, x1
	mov	x0, sp
	bl	inv_dcache_range

	/* ---------------------------------------------
	 * Enable the data cache.
	 * ---------------------------------------------
	 */
	mrs	x0, sctlr_el3
	orr	x0, x0, #SCTLR_C_BIT
	msr	sctlr_el3, x0
	isb

	ldp	x29, x30, [sp], #16
	ret
120
endfunc psci_do_pwrup_cache_maintenance
Soby Mathew's avatar
Soby Mathew committed
121
122
123
124
125
126
127
128
129
130
131

/* -----------------------------------------------------------------------
 * void psci_power_down_wfi(void);
 * This function is called to indicate to the power controller that it
 * is safe to power down this cpu. It should not exit the wfi and will
 * be released from reset upon power up.
 * -----------------------------------------------------------------------
 */
func psci_power_down_wfi
	dsb	sy		// ensure write buffer empty
	wfi
132
	no_ret	plat_panic_handler
Soby Mathew's avatar
Soby Mathew committed
133
134
135
136
137
138
139
140
141
142
endfunc psci_power_down_wfi

/* -----------------------------------------------------------------------
 * void psci_entrypoint(void);
 * The deprecated entry point for PSCI on warm boot for AArch64.
 * -----------------------------------------------------------------------
 */
func_deprecated psci_entrypoint
	b	bl31_warm_entrypoint
endfunc_deprecated psci_entrypoint