Home | History | Annotate | Download | only in aarch64
      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 	 */
     70 func 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
     92 1:
     93 	isb
     94 	ret
     95 endfunc 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 	 */
    113 func 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 
    121 A57:
    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
    130 endfunc 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 	 */
    147 func 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 
    155 A72:
    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
    165 endfunc 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 	 */
    174 func 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 
    188 endfunc plat_reset_handler
    189 
    190 	/* -----------------------------------------------------
    191 	 *  void juno_do_reset_to_aarch32_state(void);
    192 	 *
    193 	 *  Request warm reset to AArch32 mode.
    194 	 * -----------------------------------------------------
    195 	 */
    196 func 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
    203 endfunc 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 	 */
    210 func plat_arm_calc_core_pos
    211 	b	css_calc_core_pos_swap_cluster
    212 endfunc 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 	 */
    232 func 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
    237 return:
    238 	ret
    239 endfunc 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  */
    267 func 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
    290 endfunc juno_reset_to_aarch32_state
    291 
    292 #endif /* JUNO_AARCH32_EL3_RUNTIME */
    293