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