1/*
2 * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <assert_macros.S>
10#include <platform_def.h>
11
12	.local	platform_normal_stacks
13#if ENABLE_PLAT_COMPAT
14	.globl	plat_get_my_stack
15	.globl	plat_set_my_stack
16	.weak	platform_get_stack
17	.weak	platform_set_stack
18#else
19	.weak	plat_get_my_stack
20	.weak	plat_set_my_stack
21	.globl	platform_get_stack
22	.globl	platform_set_stack
23#endif /* __ENABLE_PLAT_COMPAT__ */
24
25#if ENABLE_PLAT_COMPAT
26	/* ---------------------------------------------------------------------
27	 * When the compatility layer is enabled, the new platform APIs
28	 * viz plat_get_my_stack() and plat_set_my_stack() need to be
29	 * defined using the previous APIs platform_get_stack() and
30	 * platform_set_stack(). Also we need to provide weak definitions
31	 * of platform_get_stack() and platform_set_stack() for the platforms
32	 * to reuse.
33	 * --------------------------------------------------------------------
34	 */
35
36	/* -----------------------------------------------------
37	 * unsigned long plat_get_my_stack ()
38	 *
39	 * For the current CPU, this function returns the stack
40	 * pointer for a stack allocated in device memory.
41	 * -----------------------------------------------------
42	 */
43func plat_get_my_stack
44	mrs	x0, mpidr_el1
45	b	platform_get_stack
46endfunc plat_get_my_stack
47
48	/* -----------------------------------------------------
49	 * void plat_set_my_stack ()
50	 *
51	 * For the current CPU, this function sets the stack
52	 * pointer to a stack allocated in normal memory.
53	 * -----------------------------------------------------
54	 */
55func plat_set_my_stack
56	mrs	x0, mpidr_el1
57	b	platform_set_stack
58endfunc plat_set_my_stack
59
60	/* -----------------------------------------------------
61	 * unsigned long platform_get_stack (unsigned long mpidr)
62	 *
63	 * For a given CPU, this function returns the stack
64	 * pointer for a stack allocated in device memory.
65	 * -----------------------------------------------------
66	 */
67func platform_get_stack
68	mov x10, x30 // lr
69	get_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE
70	ret x10
71endfunc platform_get_stack
72
73	/* -----------------------------------------------------
74	 * void platform_set_stack (unsigned long mpidr)
75	 *
76	 * For a given CPU, this function sets the stack pointer
77	 * to a stack allocated in normal memory.
78	 * -----------------------------------------------------
79	 */
80func platform_set_stack
81	mov x9, x30 // lr
82	bl  platform_get_stack
83	mov sp, x0
84	ret x9
85endfunc platform_set_stack
86
87#else
88	/* ---------------------------------------------------------------------
89	 * When the compatility layer is disabled, the new platform APIs
90	 * viz plat_get_my_stack() and plat_set_my_stack() are
91	 * supported by the platform and the previous APIs platform_get_stack()
92	 * and platform_set_stack() are defined in terms of new APIs making use
93	 * of the fact that they are only ever invoked for the current CPU.
94	 * This is to enable components of Trusted Firmware like SPDs using the
95	 * old platform APIs to continue to work.
96	 * --------------------------------------------------------------------
97	 */
98
99	/* -------------------------------------------------------
100	 * unsigned long platform_get_stack (unsigned long mpidr)
101	 *
102	 * For the current CPU, this function returns the stack
103	 * pointer for a stack allocated in device memory. The
104	 * 'mpidr' should correspond to that of the current CPU.
105	 * This function is deprecated and plat_get_my_stack()
106	 * should be used instead.
107	 * -------------------------------------------------------
108	 */
109func_deprecated platform_get_stack
110#if ENABLE_ASSERTIONS
111	mrs	x1, mpidr_el1
112	cmp	x0, x1
113	ASM_ASSERT(eq)
114#endif
115	b	plat_get_my_stack
116endfunc_deprecated platform_get_stack
117
118	/* -----------------------------------------------------
119	 * void platform_set_stack (unsigned long mpidr)
120	 *
121	 * For the current CPU, this function sets the stack pointer
122	 * to a stack allocated in normal memory. The
123	 * 'mpidr' should correspond to that of the current CPU.
124	 * This function is deprecated and plat_get_my_stack()
125	 * should be used instead.
126	 * -----------------------------------------------------
127	 */
128func_deprecated platform_set_stack
129#if ENABLE_ASSERTIONS
130	mrs	x1, mpidr_el1
131	cmp	x0, x1
132	ASM_ASSERT(eq)
133#endif
134	b	plat_set_my_stack
135endfunc_deprecated platform_set_stack
136
137	/* -----------------------------------------------------
138	 * uintptr_t plat_get_my_stack ()
139	 *
140	 * For the current CPU, this function returns the stack
141	 * pointer for a stack allocated in device memory.
142	 * -----------------------------------------------------
143	 */
144func plat_get_my_stack
145	mov	x10, x30 // lr
146	get_my_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE
147	ret	x10
148endfunc plat_get_my_stack
149
150	/* -----------------------------------------------------
151	 * void plat_set_my_stack ()
152	 *
153	 * For the current CPU, this function sets the stack
154	 * pointer to a stack allocated in normal memory.
155	 * -----------------------------------------------------
156	 */
157func plat_set_my_stack
158	mov	x9, x30 // lr
159	bl 	plat_get_my_stack
160	mov	sp, x0
161	ret	x9
162endfunc plat_set_my_stack
163
164#endif /*__ENABLE_PLAT_COMPAT__*/
165
166	/* -----------------------------------------------------
167	 * Per-cpu stacks in normal memory. Each cpu gets a
168	 * stack of PLATFORM_STACK_SIZE bytes.
169	 * -----------------------------------------------------
170	 */
171declare_stack platform_normal_stacks, tzfw_normal_stacks, \
172		PLATFORM_STACK_SIZE, PLATFORM_CORE_COUNT, \
173		CACHE_WRITEBACK_GRANULE
174