1/* 2 * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include <arch.h> 32#include <asm_macros.S> 33#include <bl_common.h> 34#include <cortex_a53.h> 35#include <cortex_a57.h> 36#include <cortex_a72.h> 37#include <cpu_macros.S> 38#include <css_def.h> 39#include <v2m_def.h> 40#include "../juno_def.h" 41 42 43 .globl plat_reset_handler 44 .globl plat_arm_calc_core_pos 45#if JUNO_AARCH32_EL3_RUNTIME 46 .globl plat_get_my_entrypoint 47 .globl juno_reset_to_aarch32_state 48#endif 49 50#define JUNO_REVISION(rev) REV_JUNO_R##rev 51#define JUNO_HANDLER(rev) plat_reset_handler_juno_r##rev 52#define JUMP_TO_HANDLER_IF_JUNO_R(revision) \ 53 jump_to_handler JUNO_REVISION(revision), JUNO_HANDLER(revision) 54 55 /* -------------------------------------------------------------------- 56 * Helper macro to jump to the given handler if the board revision 57 * matches. 58 * Expects the Juno board revision in x0. 59 * -------------------------------------------------------------------- 60 */ 61 .macro jump_to_handler _revision, _handler 62 cmp x0, #\_revision 63 b.eq \_handler 64 .endm 65 66 /* -------------------------------------------------------------------- 67 * Helper macro that reads the part number of the current CPU and jumps 68 * to the given label if it matches the CPU MIDR provided. 69 * 70 * Clobbers x0. 71 * -------------------------------------------------------------------- 72 */ 73 .macro jump_if_cpu_midr _cpu_midr, _label 74 mrs x0, midr_el1 75 ubfx x0, x0, MIDR_PN_SHIFT, #12 76 cmp w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK) 77 b.eq \_label 78 .endm 79 80 /* -------------------------------------------------------------------- 81 * Platform reset handler for Juno R0. 82 * 83 * Juno R0 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 * - Implement workaround for defect id 831273 by enabling an event 89 * stream every 65536 cycles. 90 * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57 91 * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57 92 * -------------------------------------------------------------------- 93 */ 94func JUNO_HANDLER(0) 95 /* -------------------------------------------------------------------- 96 * Enable the event stream every 65536 cycles 97 * -------------------------------------------------------------------- 98 */ 99 mov x0, #(0xf << EVNTI_SHIFT) 100 orr x0, x0, #EVNTEN_BIT 101 msr CNTKCTL_EL1, x0 102 103 /* -------------------------------------------------------------------- 104 * Nothing else to do on Cortex-A53. 105 * -------------------------------------------------------------------- 106 */ 107 jump_if_cpu_midr CORTEX_A53_MIDR, 1f 108 109 /* -------------------------------------------------------------------- 110 * Cortex-A57 specific settings 111 * -------------------------------------------------------------------- 112 */ 113 mov x0, #((L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ 114 (L2_TAG_RAM_LATENCY_3_CYCLES << L2CTLR_TAG_RAM_LATENCY_SHIFT)) 115 msr L2CTLR_EL1, x0 1161: 117 isb 118 ret 119endfunc JUNO_HANDLER(0) 120 121 /* -------------------------------------------------------------------- 122 * Platform reset handler for Juno R1. 123 * 124 * Juno R1 has the following topology: 125 * - Quad core Cortex-A53 processor cluster; 126 * - Dual core Cortex-A57 processor cluster. 127 * 128 * This handler does the following: 129 * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57 130 * 131 * Note that: 132 * - The default value for the L2 Tag RAM latency for Cortex-A57 is 133 * suitable. 134 * - Defect #831273 doesn't affect Juno R1. 135 * -------------------------------------------------------------------- 136 */ 137func JUNO_HANDLER(1) 138 /* -------------------------------------------------------------------- 139 * Nothing to do on Cortex-A53. 140 * -------------------------------------------------------------------- 141 */ 142 jump_if_cpu_midr CORTEX_A57_MIDR, A57 143 ret 144 145A57: 146 /* -------------------------------------------------------------------- 147 * Cortex-A57 specific settings 148 * -------------------------------------------------------------------- 149 */ 150 mov x0, #(L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) 151 msr L2CTLR_EL1, x0 152 isb 153 ret 154endfunc JUNO_HANDLER(1) 155 156 /* -------------------------------------------------------------------- 157 * Platform reset handler for Juno R2. 158 * 159 * Juno R2 has the following topology: 160 * - Quad core Cortex-A53 processor cluster; 161 * - Dual core Cortex-A72 processor cluster. 162 * 163 * This handler does the following: 164 * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A72 165 * - Set the L2 Tag RAM latency to 1 (i.e. 2 cycles) for Cortex-A72 166 * 167 * Note that: 168 * - Defect #831273 doesn't affect Juno R2. 169 * -------------------------------------------------------------------- 170 */ 171func JUNO_HANDLER(2) 172 /* -------------------------------------------------------------------- 173 * Nothing to do on Cortex-A53. 174 * -------------------------------------------------------------------- 175 */ 176 jump_if_cpu_midr CORTEX_A72_MIDR, A72 177 ret 178 179A72: 180 /* -------------------------------------------------------------------- 181 * Cortex-A72 specific settings 182 * -------------------------------------------------------------------- 183 */ 184 mov x0, #((L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ 185 (L2_TAG_RAM_LATENCY_2_CYCLES << L2CTLR_TAG_RAM_LATENCY_SHIFT)) 186 msr L2CTLR_EL1, x0 187 isb 188 ret 189endfunc JUNO_HANDLER(2) 190 191 /* -------------------------------------------------------------------- 192 * void plat_reset_handler(void); 193 * 194 * Determine the Juno board revision and call the appropriate reset 195 * handler. 196 * -------------------------------------------------------------------- 197 */ 198func plat_reset_handler 199 /* Read the V2M SYS_ID register */ 200 mov_imm x0, (V2M_SYSREGS_BASE + V2M_SYS_ID) 201 ldr w1, [x0] 202 /* Extract board revision from the SYS_ID */ 203 ubfx x0, x1, #V2M_SYS_ID_REV_SHIFT, #4 204 205 JUMP_TO_HANDLER_IF_JUNO_R(0) 206 JUMP_TO_HANDLER_IF_JUNO_R(1) 207 JUMP_TO_HANDLER_IF_JUNO_R(2) 208 209 /* Board revision is not supported */ 210 no_ret plat_panic_handler 211 212endfunc plat_reset_handler 213 214 /* ----------------------------------------------------- 215 * void juno_do_reset_to_aarch32_state(void); 216 * 217 * Request warm reset to AArch32 mode. 218 * ----------------------------------------------------- 219 */ 220func juno_do_reset_to_aarch32_state 221 mov x0, #RMR_EL3_RR_BIT 222 dsb sy 223 msr rmr_el3, x0 224 isb 225 wfi 226endfunc juno_do_reset_to_aarch32_state 227 228 /* ----------------------------------------------------- 229 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) 230 * Helper function to calculate the core position. 231 * ----------------------------------------------------- 232 */ 233func plat_arm_calc_core_pos 234 b css_calc_core_pos_swap_cluster 235endfunc plat_arm_calc_core_pos 236 237#if JUNO_AARCH32_EL3_RUNTIME 238 /* --------------------------------------------------------------------- 239 * uintptr_t plat_get_my_entrypoint (void); 240 * 241 * Main job of this routine is to distinguish between a cold and a warm 242 * boot. On JUNO platform, this distinction is based on the contents of 243 * the Trusted Mailbox. It is initialised to zero by the SCP before the 244 * AP cores are released from reset. Therefore, a zero mailbox means 245 * it's a cold reset. If it is a warm boot then a request to reset to 246 * AArch32 state is issued. This is the only way to reset to AArch32 247 * in EL3 on Juno. A trampoline located at the high vector address 248 * has already been prepared by BL1. 249 * 250 * This functions returns the contents of the mailbox, i.e.: 251 * - 0 for a cold boot; 252 * - request warm reset in AArch32 state for warm boot case; 253 * --------------------------------------------------------------------- 254 */ 255func plat_get_my_entrypoint 256 mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE 257 ldr x0, [x0] 258 cbz x0, return 259 b juno_do_reset_to_aarch32_state 2601: 261 b 1b 262return: 263 ret 264endfunc plat_get_my_entrypoint 265 266/* 267 * Emit a "movw r0, #imm16" which moves the lower 268 * 16 bits of `_val` into r0. 269 */ 270.macro emit_movw _reg_d, _val 271 mov_imm \_reg_d, (0xe3000000 | \ 272 ((\_val & 0xfff) | \ 273 ((\_val & 0xf000) << 4))) 274.endm 275 276/* 277 * Emit a "movt r0, #imm16" which moves the upper 278 * 16 bits of `_val` into r0. 279 */ 280.macro emit_movt _reg_d, _val 281 mov_imm \_reg_d, (0xe3400000 | \ 282 (((\_val & 0x0fff0000) >> 16) | \ 283 ((\_val & 0xf0000000) >> 12))) 284.endm 285 286/* 287 * This function writes the trampoline code at HI-VEC (0xFFFF0000) 288 * address which loads r0 with the entrypoint address for 289 * BL32 (a.k.a SP_MIN) when EL3 is in AArch32 mode. A warm reset 290 * to AArch32 mode is then requested by writing into RMR_EL3. 291 */ 292func juno_reset_to_aarch32_state 293 emit_movw w0, BL32_BASE 294 emit_movt w1, BL32_BASE 295 /* opcode "bx r0" to branch using r0 in AArch32 mode */ 296 mov_imm w2, 0xe12fff10 297 298 /* Write the above opcodes at HI-VECTOR location */ 299 mov_imm x3, HI_VECTOR_BASE 300 str w0, [x3], #4 301 str w1, [x3], #4 302 str w2, [x3] 303 304 bl juno_do_reset_to_aarch32_state 3051: 306 b 1b 307endfunc juno_reset_to_aarch32_state 308 309#endif /* JUNO_AARCH32_EL3_RUNTIME */ 310