tsp_entrypoint.S revision 239b04fa31647100c537852b4a3fc8bd47e33aa6
1/* 2 * Copyright (c) 2013-2014, 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 <tsp.h> 34 35 36 .globl tsp_entrypoint 37 .globl tsp_cpu_on_entry 38 .globl tsp_cpu_off_entry 39 .globl tsp_cpu_suspend_entry 40 .globl tsp_cpu_resume_entry 41 .globl tsp_fast_smc_entry 42 .globl tsp_std_smc_entry 43 .globl tsp_fiq_entry 44 45 46 47 /* --------------------------------------------- 48 * Populate the params in x0-x7 from the pointer 49 * to the smc args structure in x0. 50 * --------------------------------------------- 51 */ 52 .macro restore_args_call_smc 53 ldp x6, x7, [x0, #TSP_ARG6] 54 ldp x4, x5, [x0, #TSP_ARG4] 55 ldp x2, x3, [x0, #TSP_ARG2] 56 ldp x0, x1, [x0, #TSP_ARG0] 57 smc #0 58 .endm 59 60 .macro save_eret_context reg1 reg2 61 mrs \reg1, elr_el1 62 mrs \reg2, spsr_el1 63 stp \reg1, \reg2, [sp, #-0x10]! 64 stp x30, x18, [sp, #-0x10]! 65 .endm 66 67 .macro restore_eret_context reg1 reg2 68 ldp x30, x18, [sp], #0x10 69 ldp \reg1, \reg2, [sp], #0x10 70 msr elr_el1, \reg1 71 msr spsr_el1, \reg2 72 .endm 73 74 .section .text, "ax" 75 .align 3 76 77func tsp_entrypoint 78 79 /* --------------------------------------------- 80 * The entrypoint is expected to be executed 81 * only by the primary cpu (at least for now). 82 * So, make sure no secondary has lost its way. 83 * --------------------------------------------- 84 */ 85 mrs x0, mpidr_el1 86 bl platform_is_primary_cpu 87 cbz x0, tsp_entrypoint_panic 88 89 /* --------------------------------------------- 90 * Set the exception vector to something sane. 91 * --------------------------------------------- 92 */ 93 adr x0, tsp_exceptions 94 msr vbar_el1, x0 95 96 /* --------------------------------------------- 97 * Enable the instruction cache. 98 * --------------------------------------------- 99 */ 100 mrs x0, sctlr_el1 101 orr x0, x0, #SCTLR_I_BIT 102 msr sctlr_el1, x0 103 isb 104 105 /* --------------------------------------------- 106 * Zero out NOBITS sections. There are 2 of them: 107 * - the .bss section; 108 * - the coherent memory section. 109 * --------------------------------------------- 110 */ 111 ldr x0, =__BSS_START__ 112 ldr x1, =__BSS_SIZE__ 113 bl zeromem16 114 115 ldr x0, =__COHERENT_RAM_START__ 116 ldr x1, =__COHERENT_RAM_UNALIGNED_SIZE__ 117 bl zeromem16 118 119 /* -------------------------------------------- 120 * Give ourselves a small coherent stack to 121 * ease the pain of initializing the MMU 122 * -------------------------------------------- 123 */ 124 mrs x0, mpidr_el1 125 bl platform_set_coherent_stack 126 127 /* --------------------------------------------- 128 * Perform early platform setup & platform 129 * specific early arch. setup e.g. mmu setup 130 * --------------------------------------------- 131 */ 132 bl bl32_early_platform_setup 133 bl bl32_plat_arch_setup 134 135 /* --------------------------------------------- 136 * Give ourselves a stack allocated in Normal 137 * -IS-WBWA memory 138 * --------------------------------------------- 139 */ 140 mrs x0, mpidr_el1 141 bl platform_set_stack 142 143 /* --------------------------------------------- 144 * Jump to main function. 145 * --------------------------------------------- 146 */ 147 bl tsp_main 148 149 /* --------------------------------------------- 150 * Tell TSPD that we are done initialising 151 * --------------------------------------------- 152 */ 153 mov x1, x0 154 mov x0, #TSP_ENTRY_DONE 155 smc #0 156 157tsp_entrypoint_panic: 158 b tsp_entrypoint_panic 159 160 /*--------------------------------------------- 161 * This entrypoint is used by the TSPD when this 162 * cpu is to be turned off through a CPU_OFF 163 * psci call to ask the TSP to perform any 164 * bookeeping necessary. In the current 165 * implementation, the TSPD expects the TSP to 166 * re-initialise its state so nothing is done 167 * here except for acknowledging the request. 168 * --------------------------------------------- 169 */ 170func tsp_cpu_off_entry 171 bl tsp_cpu_off_main 172 restore_args_call_smc 173 174 /*--------------------------------------------- 175 * This entrypoint is used by the TSPD when this 176 * cpu is turned on using a CPU_ON psci call to 177 * ask the TSP to initialise itself i.e. setup 178 * the mmu, stacks etc. Minimal architectural 179 * state will be initialised by the TSPD when 180 * this function is entered i.e. Caches and MMU 181 * will be turned off, the execution state 182 * will be aarch64 and exceptions masked. 183 * --------------------------------------------- 184 */ 185func tsp_cpu_on_entry 186 /* --------------------------------------------- 187 * Set the exception vector to something sane. 188 * --------------------------------------------- 189 */ 190 adr x0, tsp_exceptions 191 msr vbar_el1, x0 192 193 /* --------------------------------------------- 194 * Enable the instruction cache. 195 * --------------------------------------------- 196 */ 197 mrs x0, sctlr_el1 198 orr x0, x0, #SCTLR_I_BIT 199 msr sctlr_el1, x0 200 isb 201 202 /* -------------------------------------------- 203 * Give ourselves a small coherent stack to 204 * ease the pain of initializing the MMU 205 * -------------------------------------------- 206 */ 207 mrs x0, mpidr_el1 208 bl platform_set_coherent_stack 209 210 /* --------------------------------------------- 211 * Initialise the MMU 212 * --------------------------------------------- 213 */ 214 bl enable_mmu_el1 215 216 /* --------------------------------------------- 217 * Give ourselves a stack allocated in Normal 218 * -IS-WBWA memory 219 * --------------------------------------------- 220 */ 221 mrs x0, mpidr_el1 222 bl platform_set_stack 223 224 /* --------------------------------------------- 225 * Enter C runtime to perform any remaining 226 * book keeping 227 * --------------------------------------------- 228 */ 229 bl tsp_cpu_on_main 230 restore_args_call_smc 231 232 /* Should never reach here */ 233tsp_cpu_on_entry_panic: 234 b tsp_cpu_on_entry_panic 235 236 /*--------------------------------------------- 237 * This entrypoint is used by the TSPD when this 238 * cpu is to be suspended through a CPU_SUSPEND 239 * psci call to ask the TSP to perform any 240 * bookeeping necessary. In the current 241 * implementation, the TSPD saves and restores 242 * the EL1 state. 243 * --------------------------------------------- 244 */ 245func tsp_cpu_suspend_entry 246 bl tsp_cpu_suspend_main 247 restore_args_call_smc 248 249 /*--------------------------------------------- 250 * This entrypoint is used by the TSPD to pass 251 * control for handling a pending S-EL1 FIQ. 252 * 'x0' contains a magic number which indicates 253 * this. TSPD expects control to be handed back 254 * at the end of FIQ processing. This is done 255 * through an SMC. The handover agreement is: 256 * 257 * 1. PSTATE.DAIF are set upon entry. 'x1' has 258 * the ELR_EL3 from the non-secure state. 259 * 2. TSP has to preserve the callee saved 260 * general purpose registers, SP_EL1/EL0 and 261 * LR. 262 * 3. TSP has to preserve the system and vfp 263 * registers (if applicable). 264 * 4. TSP can use 'x0-x18' to enable its C 265 * runtime. 266 * 5. TSP returns to TSPD using an SMC with 267 * 'x0' = TSP_HANDLED_S_EL1_FIQ 268 * --------------------------------------------- 269 */ 270func tsp_fiq_entry 271#if DEBUG 272 mov x2, #(TSP_HANDLE_FIQ_AND_RETURN & ~0xffff) 273 movk x2, #(TSP_HANDLE_FIQ_AND_RETURN & 0xffff) 274 cmp x0, x2 275 b.ne tsp_fiq_entry_panic 276#endif 277 /*--------------------------------------------- 278 * Save any previous context needed to perform 279 * an exception return from S-EL1 e.g. context 280 * from a previous IRQ. Update statistics and 281 * handle the FIQ before returning to the TSPD. 282 * IRQ/FIQs are not enabled since that will 283 * complicate the implementation. Execution 284 * will be transferred back to the normal world 285 * in any case. A non-zero return value from the 286 * fiq handler is an error. 287 * --------------------------------------------- 288 */ 289 save_eret_context x2 x3 290 bl tsp_update_sync_fiq_stats 291 bl tsp_fiq_handler 292 cbnz x0, tsp_fiq_entry_panic 293 restore_eret_context x2 x3 294 mov x0, #(TSP_HANDLED_S_EL1_FIQ & ~0xffff) 295 movk x0, #(TSP_HANDLED_S_EL1_FIQ & 0xffff) 296 smc #0 297 298tsp_fiq_entry_panic: 299 b tsp_fiq_entry_panic 300 301 /*--------------------------------------------- 302 * This entrypoint is used by the TSPD when this 303 * cpu resumes execution after an earlier 304 * CPU_SUSPEND psci call to ask the TSP to 305 * restore its saved context. In the current 306 * implementation, the TSPD saves and restores 307 * EL1 state so nothing is done here apart from 308 * acknowledging the request. 309 * --------------------------------------------- 310 */ 311func tsp_cpu_resume_entry 312 bl tsp_cpu_resume_main 313 restore_args_call_smc 314tsp_cpu_resume_panic: 315 b tsp_cpu_resume_panic 316 317 /*--------------------------------------------- 318 * This entrypoint is used by the TSPD to ask 319 * the TSP to service a fast smc request. 320 * --------------------------------------------- 321 */ 322func tsp_fast_smc_entry 323 bl tsp_smc_handler 324 restore_args_call_smc 325tsp_fast_smc_entry_panic: 326 b tsp_fast_smc_entry_panic 327 328 /*--------------------------------------------- 329 * This entrypoint is used by the TSPD to ask 330 * the TSP to service a std smc request. 331 * We will enable preemption during execution 332 * of tsp_smc_handler. 333 * --------------------------------------------- 334 */ 335func tsp_std_smc_entry 336 msr daifclr, #DAIF_FIQ_BIT | DAIF_IRQ_BIT 337 bl tsp_smc_handler 338 msr daifset, #DAIF_FIQ_BIT | DAIF_IRQ_BIT 339 restore_args_call_smc 340tsp_std_smc_entry_panic: 341 b tsp_std_smc_entry_panic 342