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