xref: /rk3399_ARM-atf/plat/arm/board/juno/aarch64/juno_helpers.S (revision 09d40e0e08283a249e7dce0e106c07c5141f9b7e)
1/*
2 * Copyright (c) 2013-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 <common/bl_common.h>
10#include <cortex_a53.h>
11#include <cortex_a57.h>
12#include <cortex_a72.h>
13#include <cpu_macros.S>
14#include <css_def.h>
15#include <v2m_def.h>
16#include "../juno_def.h"
17
18
19	.globl	plat_reset_handler
20	.globl	plat_arm_calc_core_pos
21#if JUNO_AARCH32_EL3_RUNTIME
22	.globl	plat_get_my_entrypoint
23	.globl	juno_reset_to_aarch32_state
24#endif
25
26#define JUNO_REVISION(rev)	REV_JUNO_R##rev
27#define JUNO_HANDLER(rev)	plat_reset_handler_juno_r##rev
28#define JUMP_TO_HANDLER_IF_JUNO_R(revision)	\
29	jump_to_handler JUNO_REVISION(revision), JUNO_HANDLER(revision)
30
31	/* --------------------------------------------------------------------
32	 * Helper macro to jump to the given handler if the board revision
33	 * matches.
34	 * Expects the Juno board revision in x0.
35	 * --------------------------------------------------------------------
36	 */
37	.macro jump_to_handler _revision, _handler
38	cmp	x0, #\_revision
39	b.eq	\_handler
40	.endm
41
42	/* --------------------------------------------------------------------
43	 * Platform reset handler for Juno R0.
44	 *
45	 * Juno R0 has the following topology:
46	 * - Quad core Cortex-A53 processor cluster;
47	 * - Dual core Cortex-A57 processor cluster.
48	 *
49	 * This handler does the following:
50	 * - Implement workaround for defect id 831273 by enabling an event
51	 *   stream every 65536 cycles.
52	 * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
53	 * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
54	 * --------------------------------------------------------------------
55	 */
56func JUNO_HANDLER(0)
57	/* --------------------------------------------------------------------
58	 * Enable the event stream every 65536 cycles
59	 * --------------------------------------------------------------------
60	 */
61	mov     x0, #(0xf << EVNTI_SHIFT)
62	orr     x0, x0, #EVNTEN_BIT
63	msr     CNTKCTL_EL1, x0
64
65	/* --------------------------------------------------------------------
66	 * Nothing else to do on Cortex-A53.
67	 * --------------------------------------------------------------------
68	 */
69	jump_if_cpu_midr CORTEX_A53_MIDR, 1f
70
71	/* --------------------------------------------------------------------
72	 * Cortex-A57 specific settings
73	 * --------------------------------------------------------------------
74	 */
75	mov	x0, #((CORTEX_A57_L2_DATA_RAM_LATENCY_3_CYCLES << CORTEX_A57_L2CTLR_DATA_RAM_LATENCY_SHIFT) |	\
76		      (CORTEX_A57_L2_TAG_RAM_LATENCY_3_CYCLES << CORTEX_A57_L2CTLR_TAG_RAM_LATENCY_SHIFT))
77	msr     CORTEX_A57_L2CTLR_EL1, x0
781:
79	isb
80	ret
81endfunc JUNO_HANDLER(0)
82
83	/* --------------------------------------------------------------------
84	 * Platform reset handler for Juno R1.
85	 *
86	 * Juno R1 has the following topology:
87	 * - Quad core Cortex-A53 processor cluster;
88	 * - Dual core Cortex-A57 processor cluster.
89	 *
90	 * This handler does the following:
91	 * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
92	 *
93	 * Note that:
94	 * - The default value for the L2 Tag RAM latency for Cortex-A57 is
95	 *   suitable.
96	 * - Defect #831273 doesn't affect Juno R1.
97	 * --------------------------------------------------------------------
98	 */
99func JUNO_HANDLER(1)
100	/* --------------------------------------------------------------------
101	 * Nothing to do on Cortex-A53.
102	 * --------------------------------------------------------------------
103	 */
104	jump_if_cpu_midr CORTEX_A57_MIDR, A57
105	ret
106
107A57:
108	/* --------------------------------------------------------------------
109	 * Cortex-A57 specific settings
110	 * --------------------------------------------------------------------
111	 */
112	mov	x0, #(CORTEX_A57_L2_DATA_RAM_LATENCY_3_CYCLES << CORTEX_A57_L2CTLR_DATA_RAM_LATENCY_SHIFT)
113	msr     CORTEX_A57_L2CTLR_EL1, x0
114	isb
115	ret
116endfunc JUNO_HANDLER(1)
117
118	/* --------------------------------------------------------------------
119	 * Platform reset handler for Juno R2.
120	 *
121	 * Juno R2 has the following topology:
122	 * - Quad core Cortex-A53 processor cluster;
123	 * - Dual core Cortex-A72 processor cluster.
124	 *
125	 * This handler does the following:
126	 * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A72
127	 * - Set the L2 Tag RAM latency to 1 (i.e. 2 cycles) for Cortex-A72
128	 *
129	 * Note that:
130	 * - Defect #831273 doesn't affect Juno R2.
131	 * --------------------------------------------------------------------
132	 */
133func JUNO_HANDLER(2)
134	/* --------------------------------------------------------------------
135	 * Nothing to do on Cortex-A53.
136	 * --------------------------------------------------------------------
137	 */
138	jump_if_cpu_midr CORTEX_A72_MIDR, A72
139	ret
140
141A72:
142	/* --------------------------------------------------------------------
143	 * Cortex-A72 specific settings
144	 * --------------------------------------------------------------------
145	 */
146	mov	x0, #((CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES << CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT) |	\
147		      (CORTEX_A72_L2_TAG_RAM_LATENCY_2_CYCLES << CORTEX_A72_L2CTLR_TAG_RAM_LATENCY_SHIFT))
148	msr     CORTEX_A57_L2CTLR_EL1, x0
149	isb
150	ret
151endfunc JUNO_HANDLER(2)
152
153	/* --------------------------------------------------------------------
154	 * void plat_reset_handler(void);
155	 *
156	 * Determine the Juno board revision and call the appropriate reset
157	 * handler.
158	 * --------------------------------------------------------------------
159	 */
160func plat_reset_handler
161	/* Read the V2M SYS_ID register */
162	mov_imm	x0, (V2M_SYSREGS_BASE + V2M_SYS_ID)
163	ldr	w1, [x0]
164	/* Extract board revision from the SYS_ID */
165	ubfx	x0, x1, #V2M_SYS_ID_REV_SHIFT, #4
166
167	JUMP_TO_HANDLER_IF_JUNO_R(0)
168	JUMP_TO_HANDLER_IF_JUNO_R(1)
169	JUMP_TO_HANDLER_IF_JUNO_R(2)
170
171	/* Board revision is not supported */
172	no_ret	plat_panic_handler
173
174endfunc plat_reset_handler
175
176	/* -----------------------------------------------------
177	 *  void juno_do_reset_to_aarch32_state(void);
178	 *
179	 *  Request warm reset to AArch32 mode.
180	 * -----------------------------------------------------
181	 */
182func juno_do_reset_to_aarch32_state
183	mov	x0, #RMR_EL3_RR_BIT
184	dsb	sy
185	msr	rmr_el3, x0
186	isb
187	wfi
188	b	plat_panic_handler
189endfunc juno_do_reset_to_aarch32_state
190
191	/* -----------------------------------------------------
192	 *  unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
193	 *  Helper function to calculate the core position.
194	 * -----------------------------------------------------
195	 */
196func plat_arm_calc_core_pos
197	b	css_calc_core_pos_swap_cluster
198endfunc plat_arm_calc_core_pos
199
200#if JUNO_AARCH32_EL3_RUNTIME
201	/* ---------------------------------------------------------------------
202	 * uintptr_t plat_get_my_entrypoint (void);
203	 *
204	 * Main job of this routine is to distinguish between a cold and a warm
205	 * boot. On JUNO platform, this distinction is based on the contents of
206	 * the Trusted Mailbox. It is initialised to zero by the SCP before the
207	 * AP cores are released from reset. Therefore, a zero mailbox means
208	 * it's a cold reset. If it is a warm boot then a request to reset to
209	 * AArch32 state is issued. This is the only way to reset to AArch32
210	 * in EL3 on Juno. A trampoline located at the high vector address
211	 * has already been prepared by BL1.
212	 *
213	 * This functions returns the contents of the mailbox, i.e.:
214	 *  - 0 for a cold boot;
215	 *  - request warm reset in AArch32 state for warm boot case;
216	 * ---------------------------------------------------------------------
217	 */
218func plat_get_my_entrypoint
219	mov_imm	x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
220	ldr	x0, [x0]
221	cbz	x0, return
222	b	juno_do_reset_to_aarch32_state
223return:
224	ret
225endfunc plat_get_my_entrypoint
226
227/*
228 * Emit a "movw r0, #imm16" which moves the lower
229 * 16 bits of `_val` into r0.
230 */
231.macro emit_movw _reg_d, _val
232	mov_imm	\_reg_d, (0xe3000000 | \
233			((\_val & 0xfff) | \
234			((\_val & 0xf000) << 4)))
235.endm
236
237/*
238 * Emit a "movt r0, #imm16" which moves the upper
239 * 16 bits of `_val` into r0.
240 */
241.macro emit_movt _reg_d, _val
242	mov_imm	\_reg_d, (0xe3400000 | \
243			(((\_val & 0x0fff0000) >> 16) | \
244			((\_val & 0xf0000000) >> 12)))
245.endm
246
247/*
248 * This function writes the trampoline code at HI-VEC (0xFFFF0000)
249 * address which loads r0 with the entrypoint address for
250 * BL32 (a.k.a SP_MIN) when EL3 is in AArch32 mode. A warm reset
251 * to AArch32 mode is then requested by writing into RMR_EL3.
252 */
253func juno_reset_to_aarch32_state
254	/*
255	 * Invalidate all caches before the warm reset to AArch32 state.
256	 * This is required on the Juno AArch32 boot flow because the L2
257	 * unified cache may contain code and data from when the processor
258	 * was still executing in AArch64 state.  This code only runs on
259	 * the primary core, all other cores are powered down.
260	 */
261	mov	x0, #DCISW
262	bl	dcsw_op_all
263
264	emit_movw	w0, BL32_BASE
265	emit_movt	w1, BL32_BASE
266	/* opcode "bx r0" to branch using r0 in AArch32 mode */
267	mov_imm	w2, 0xe12fff10
268
269	/* Write the above opcodes at HI-VECTOR location */
270	mov_imm	x3, HI_VECTOR_BASE
271	str	w0, [x3], #4
272	str	w1, [x3], #4
273	str	w2, [x3]
274
275	b	juno_do_reset_to_aarch32_state
276endfunc juno_reset_to_aarch32_state
277
278#endif /* JUNO_AARCH32_EL3_RUNTIME */
279