1/* 2 * Copyright (c) 2013-2016, 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, #((L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ 90 (L2_TAG_RAM_LATENCY_3_CYCLES << L2CTLR_TAG_RAM_LATENCY_SHIFT)) 91 msr 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, #(L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) 127 msr 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, #((L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ 161 (L2_TAG_RAM_LATENCY_2_CYCLES << L2CTLR_TAG_RAM_LATENCY_SHIFT)) 162 msr 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 202endfunc juno_do_reset_to_aarch32_state 203 204 /* ----------------------------------------------------- 205 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) 206 * Helper function to calculate the core position. 207 * ----------------------------------------------------- 208 */ 209func plat_arm_calc_core_pos 210 b css_calc_core_pos_swap_cluster 211endfunc plat_arm_calc_core_pos 212 213#if JUNO_AARCH32_EL3_RUNTIME 214 /* --------------------------------------------------------------------- 215 * uintptr_t plat_get_my_entrypoint (void); 216 * 217 * Main job of this routine is to distinguish between a cold and a warm 218 * boot. On JUNO platform, this distinction is based on the contents of 219 * the Trusted Mailbox. It is initialised to zero by the SCP before the 220 * AP cores are released from reset. Therefore, a zero mailbox means 221 * it's a cold reset. If it is a warm boot then a request to reset to 222 * AArch32 state is issued. This is the only way to reset to AArch32 223 * in EL3 on Juno. A trampoline located at the high vector address 224 * has already been prepared by BL1. 225 * 226 * This functions returns the contents of the mailbox, i.e.: 227 * - 0 for a cold boot; 228 * - request warm reset in AArch32 state for warm boot case; 229 * --------------------------------------------------------------------- 230 */ 231func plat_get_my_entrypoint 232 mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE 233 ldr x0, [x0] 234 cbz x0, return 235 b juno_do_reset_to_aarch32_state 2361: 237 b 1b 238return: 239 ret 240endfunc plat_get_my_entrypoint 241 242/* 243 * Emit a "movw r0, #imm16" which moves the lower 244 * 16 bits of `_val` into r0. 245 */ 246.macro emit_movw _reg_d, _val 247 mov_imm \_reg_d, (0xe3000000 | \ 248 ((\_val & 0xfff) | \ 249 ((\_val & 0xf000) << 4))) 250.endm 251 252/* 253 * Emit a "movt r0, #imm16" which moves the upper 254 * 16 bits of `_val` into r0. 255 */ 256.macro emit_movt _reg_d, _val 257 mov_imm \_reg_d, (0xe3400000 | \ 258 (((\_val & 0x0fff0000) >> 16) | \ 259 ((\_val & 0xf0000000) >> 12))) 260.endm 261 262/* 263 * This function writes the trampoline code at HI-VEC (0xFFFF0000) 264 * address which loads r0 with the entrypoint address for 265 * BL32 (a.k.a SP_MIN) when EL3 is in AArch32 mode. A warm reset 266 * to AArch32 mode is then requested by writing into RMR_EL3. 267 */ 268func juno_reset_to_aarch32_state 269 emit_movw w0, BL32_BASE 270 emit_movt w1, BL32_BASE 271 /* opcode "bx r0" to branch using r0 in AArch32 mode */ 272 mov_imm w2, 0xe12fff10 273 274 /* Write the above opcodes at HI-VECTOR location */ 275 mov_imm x3, HI_VECTOR_BASE 276 str w0, [x3], #4 277 str w1, [x3], #4 278 str w2, [x3] 279 280 bl juno_do_reset_to_aarch32_state 2811: 282 b 1b 283endfunc juno_reset_to_aarch32_state 284 285#endif /* JUNO_AARCH32_EL3_RUNTIME */ 286