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