1/* 2 * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <platform_def.h> 8 9#include <arch.h> 10#include <asm_macros.S> 11#include <bl32/tsp/tsp.h> 12#include <lib/xlat_tables/xlat_tables_defs.h> 13 14#include "../tsp_private.h" 15 16 17 .globl tsp_entrypoint 18 .globl tsp_vector_table 19 20 21 22 /* --------------------------------------------- 23 * Populate the params in x0-x7 from the pointer 24 * to the smc args structure in x0. 25 * --------------------------------------------- 26 */ 27 .macro restore_args_call_smc 28 ldp x6, x7, [x0, #TSP_ARG6] 29 ldp x4, x5, [x0, #TSP_ARG4] 30 ldp x2, x3, [x0, #TSP_ARG2] 31 ldp x0, x1, [x0, #TSP_ARG0] 32 smc #0 33 .endm 34 35 .macro save_eret_context reg1 reg2 36 mrs \reg1, elr_el1 37 mrs \reg2, spsr_el1 38 stp \reg1, \reg2, [sp, #-0x10]! 39 stp x30, x18, [sp, #-0x10]! 40 .endm 41 42 .macro restore_eret_context reg1 reg2 43 ldp x30, x18, [sp], #0x10 44 ldp \reg1, \reg2, [sp], #0x10 45 msr elr_el1, \reg1 46 msr spsr_el1, \reg2 47 .endm 48 49func tsp_entrypoint _align=3 50 51#if ENABLE_PIE 52 /* 53 * ------------------------------------------------------------ 54 * If PIE is enabled fixup the Global descriptor Table only 55 * once during primary core cold boot path. 56 * 57 * Compile time base address, required for fixup, is calculated 58 * using "pie_fixup" label present within first page. 59 * ------------------------------------------------------------ 60 */ 61 pie_fixup: 62 ldr x0, =pie_fixup 63 and x0, x0, #~(PAGE_SIZE_MASK) 64 mov_imm x1, (BL32_LIMIT - BL32_BASE) 65 add x1, x1, x0 66 bl fixup_gdt_reloc 67#endif /* ENABLE_PIE */ 68 69 /* --------------------------------------------- 70 * Set the exception vector to something sane. 71 * --------------------------------------------- 72 */ 73 adr x0, tsp_exceptions 74 msr vbar_el1, x0 75 isb 76 77 /* --------------------------------------------- 78 * Enable the SError interrupt now that the 79 * exception vectors have been setup. 80 * --------------------------------------------- 81 */ 82 msr daifclr, #DAIF_ABT_BIT 83 84 /* --------------------------------------------- 85 * Enable the instruction cache, stack pointer 86 * and data access alignment checks and disable 87 * speculative loads. 88 * --------------------------------------------- 89 */ 90 mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT) 91 mrs x0, sctlr_el1 92 orr x0, x0, x1 93 bic x0, x0, #SCTLR_DSSBS_BIT 94 msr sctlr_el1, x0 95 isb 96 97 /* --------------------------------------------- 98 * Invalidate the RW memory used by the BL32 99 * image. This includes the data and NOBITS 100 * sections. This is done to safeguard against 101 * possible corruption of this memory by dirty 102 * cache lines in a system cache as a result of 103 * use by an earlier boot loader stage. 104 * --------------------------------------------- 105 */ 106 adr x0, __RW_START__ 107 adr x1, __RW_END__ 108 sub x1, x1, x0 109 bl inv_dcache_range 110 111 /* --------------------------------------------- 112 * Zero out NOBITS sections. There are 2 of them: 113 * - the .bss section; 114 * - the coherent memory section. 115 * --------------------------------------------- 116 */ 117 ldr x0, =__BSS_START__ 118 ldr x1, =__BSS_SIZE__ 119 bl zeromem 120 121#if USE_COHERENT_MEM 122 ldr x0, =__COHERENT_RAM_START__ 123 ldr x1, =__COHERENT_RAM_UNALIGNED_SIZE__ 124 bl zeromem 125#endif 126 127 /* -------------------------------------------- 128 * Allocate a stack whose memory will be marked 129 * as Normal-IS-WBWA when the MMU is enabled. 130 * There is no risk of reading stale stack 131 * memory after enabling the MMU as only the 132 * primary cpu is running at the moment. 133 * -------------------------------------------- 134 */ 135 bl plat_set_my_stack 136 137 /* --------------------------------------------- 138 * Initialize the stack protector canary before 139 * any C code is called. 140 * --------------------------------------------- 141 */ 142#if STACK_PROTECTOR_ENABLED 143 bl update_stack_protector_canary 144#endif 145 146 /* --------------------------------------------- 147 * Perform TSP setup 148 * --------------------------------------------- 149 */ 150 bl tsp_setup 151 152#if ENABLE_PAUTH 153 /* --------------------------------------------- 154 * Program APIAKey_EL1 155 * and enable pointer authentication 156 * --------------------------------------------- 157 */ 158 bl pauth_init_enable_el1 159#endif /* ENABLE_PAUTH */ 160 161 /* --------------------------------------------- 162 * Jump to main function. 163 * --------------------------------------------- 164 */ 165 bl tsp_main 166 167 /* --------------------------------------------- 168 * Tell TSPD that we are done initialising 169 * --------------------------------------------- 170 */ 171 mov x1, x0 172 mov x0, #TSP_ENTRY_DONE 173 smc #0 174 175tsp_entrypoint_panic: 176 b tsp_entrypoint_panic 177endfunc tsp_entrypoint 178 179 180 /* ------------------------------------------- 181 * Table of entrypoint vectors provided to the 182 * TSPD for the various entrypoints 183 * ------------------------------------------- 184 */ 185vector_base tsp_vector_table 186 b tsp_yield_smc_entry 187 b tsp_fast_smc_entry 188 b tsp_cpu_on_entry 189 b tsp_cpu_off_entry 190 b tsp_cpu_resume_entry 191 b tsp_cpu_suspend_entry 192 b tsp_sel1_intr_entry 193 b tsp_system_off_entry 194 b tsp_system_reset_entry 195 b tsp_abort_yield_smc_entry 196 197 /*--------------------------------------------- 198 * This entrypoint is used by the TSPD when this 199 * cpu is to be turned off through a CPU_OFF 200 * psci call to ask the TSP to perform any 201 * bookeeping necessary. In the current 202 * implementation, the TSPD expects the TSP to 203 * re-initialise its state so nothing is done 204 * here except for acknowledging the request. 205 * --------------------------------------------- 206 */ 207func tsp_cpu_off_entry 208 bl tsp_cpu_off_main 209 restore_args_call_smc 210endfunc tsp_cpu_off_entry 211 212 /*--------------------------------------------- 213 * This entrypoint is used by the TSPD when the 214 * system is about to be switched off (through 215 * a SYSTEM_OFF psci call) to ask the TSP to 216 * perform any necessary bookkeeping. 217 * --------------------------------------------- 218 */ 219func tsp_system_off_entry 220 bl tsp_system_off_main 221 restore_args_call_smc 222endfunc tsp_system_off_entry 223 224 /*--------------------------------------------- 225 * This entrypoint is used by the TSPD when the 226 * system is about to be reset (through a 227 * SYSTEM_RESET psci call) to ask the TSP to 228 * perform any necessary bookkeeping. 229 * --------------------------------------------- 230 */ 231func tsp_system_reset_entry 232 bl tsp_system_reset_main 233 restore_args_call_smc 234endfunc tsp_system_reset_entry 235 236 /*--------------------------------------------- 237 * This entrypoint is used by the TSPD when this 238 * cpu is turned on using a CPU_ON psci call to 239 * ask the TSP to initialise itself i.e. setup 240 * the mmu, stacks etc. Minimal architectural 241 * state will be initialised by the TSPD when 242 * this function is entered i.e. Caches and MMU 243 * will be turned off, the execution state 244 * will be aarch64 and exceptions masked. 245 * --------------------------------------------- 246 */ 247func tsp_cpu_on_entry 248 /* --------------------------------------------- 249 * Set the exception vector to something sane. 250 * --------------------------------------------- 251 */ 252 adr x0, tsp_exceptions 253 msr vbar_el1, x0 254 isb 255 256 /* Enable the SError interrupt */ 257 msr daifclr, #DAIF_ABT_BIT 258 259 /* --------------------------------------------- 260 * Enable the instruction cache, stack pointer 261 * and data access alignment checks 262 * --------------------------------------------- 263 */ 264 mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT) 265 mrs x0, sctlr_el1 266 orr x0, x0, x1 267 msr sctlr_el1, x0 268 isb 269 270 /* -------------------------------------------- 271 * Give ourselves a stack whose memory will be 272 * marked as Normal-IS-WBWA when the MMU is 273 * enabled. 274 * -------------------------------------------- 275 */ 276 bl plat_set_my_stack 277 278 /* -------------------------------------------- 279 * Enable MMU and D-caches together. 280 * -------------------------------------------- 281 */ 282 mov x0, #0 283 bl bl32_plat_enable_mmu 284 285#if ENABLE_PAUTH 286 /* --------------------------------------------- 287 * Program APIAKey_EL1 288 * and enable pointer authentication 289 * --------------------------------------------- 290 */ 291 bl pauth_init_enable_el1 292#endif /* ENABLE_PAUTH */ 293 294 /* --------------------------------------------- 295 * Enter C runtime to perform any remaining 296 * book keeping 297 * --------------------------------------------- 298 */ 299 bl tsp_cpu_on_main 300 restore_args_call_smc 301 302 /* Should never reach here */ 303tsp_cpu_on_entry_panic: 304 b tsp_cpu_on_entry_panic 305endfunc tsp_cpu_on_entry 306 307 /*--------------------------------------------- 308 * This entrypoint is used by the TSPD when this 309 * cpu is to be suspended through a CPU_SUSPEND 310 * psci call to ask the TSP to perform any 311 * bookeeping necessary. In the current 312 * implementation, the TSPD saves and restores 313 * the EL1 state. 314 * --------------------------------------------- 315 */ 316func tsp_cpu_suspend_entry 317 bl tsp_cpu_suspend_main 318 restore_args_call_smc 319endfunc tsp_cpu_suspend_entry 320 321 /*------------------------------------------------- 322 * This entrypoint is used by the TSPD to pass 323 * control for `synchronously` handling a S-EL1 324 * Interrupt which was triggered while executing 325 * in normal world. 'x0' contains a magic number 326 * which indicates this. TSPD expects control to 327 * be handed back at the end of interrupt 328 * processing. This is done through an SMC. 329 * The handover agreement is: 330 * 331 * 1. PSTATE.DAIF are set upon entry. 'x1' has 332 * the ELR_EL3 from the non-secure state. 333 * 2. TSP has to preserve the callee saved 334 * general purpose registers, SP_EL1/EL0 and 335 * LR. 336 * 3. TSP has to preserve the system and vfp 337 * registers (if applicable). 338 * 4. TSP can use 'x0-x18' to enable its C 339 * runtime. 340 * 5. TSP returns to TSPD using an SMC with 341 * 'x0' = TSP_HANDLED_S_EL1_INTR 342 * ------------------------------------------------ 343 */ 344func tsp_sel1_intr_entry 345#if DEBUG 346 mov_imm x2, TSP_HANDLE_SEL1_INTR_AND_RETURN 347 cmp x0, x2 348 b.ne tsp_sel1_int_entry_panic 349#endif 350 /*------------------------------------------------- 351 * Save any previous context needed to perform 352 * an exception return from S-EL1 e.g. context 353 * from a previous Non secure Interrupt. 354 * Update statistics and handle the S-EL1 355 * interrupt before returning to the TSPD. 356 * IRQ/FIQs are not enabled since that will 357 * complicate the implementation. Execution 358 * will be transferred back to the normal world 359 * in any case. The handler can return 0 360 * if the interrupt was handled or TSP_PREEMPTED 361 * if the expected interrupt was preempted 362 * by an interrupt that should be handled in EL3 363 * e.g. Group 0 interrupt in GICv3. In both 364 * the cases switch to EL3 using SMC with id 365 * TSP_HANDLED_S_EL1_INTR. Any other return value 366 * from the handler will result in panic. 367 * ------------------------------------------------ 368 */ 369 save_eret_context x2 x3 370 bl tsp_update_sync_sel1_intr_stats 371 bl tsp_common_int_handler 372 /* Check if the S-EL1 interrupt has been handled */ 373 cbnz x0, tsp_sel1_intr_check_preemption 374 b tsp_sel1_intr_return 375tsp_sel1_intr_check_preemption: 376 /* Check if the S-EL1 interrupt has been preempted */ 377 mov_imm x1, TSP_PREEMPTED 378 cmp x0, x1 379 b.ne tsp_sel1_int_entry_panic 380tsp_sel1_intr_return: 381 mov_imm x0, TSP_HANDLED_S_EL1_INTR 382 restore_eret_context x2 x3 383 smc #0 384 385 /* Should never reach here */ 386tsp_sel1_int_entry_panic: 387 no_ret plat_panic_handler 388endfunc tsp_sel1_intr_entry 389 390 /*--------------------------------------------- 391 * This entrypoint is used by the TSPD when this 392 * cpu resumes execution after an earlier 393 * CPU_SUSPEND psci call to ask the TSP to 394 * restore its saved context. In the current 395 * implementation, the TSPD saves and restores 396 * EL1 state so nothing is done here apart from 397 * acknowledging the request. 398 * --------------------------------------------- 399 */ 400func tsp_cpu_resume_entry 401 bl tsp_cpu_resume_main 402 restore_args_call_smc 403 404 /* Should never reach here */ 405 no_ret plat_panic_handler 406endfunc tsp_cpu_resume_entry 407 408 /*--------------------------------------------- 409 * This entrypoint is used by the TSPD to ask 410 * the TSP to service a fast smc request. 411 * --------------------------------------------- 412 */ 413func tsp_fast_smc_entry 414 bl tsp_smc_handler 415 restore_args_call_smc 416 417 /* Should never reach here */ 418 no_ret plat_panic_handler 419endfunc tsp_fast_smc_entry 420 421 /*--------------------------------------------- 422 * This entrypoint is used by the TSPD to ask 423 * the TSP to service a Yielding SMC request. 424 * We will enable preemption during execution 425 * of tsp_smc_handler. 426 * --------------------------------------------- 427 */ 428func tsp_yield_smc_entry 429 msr daifclr, #DAIF_FIQ_BIT | DAIF_IRQ_BIT 430 bl tsp_smc_handler 431 msr daifset, #DAIF_FIQ_BIT | DAIF_IRQ_BIT 432 restore_args_call_smc 433 434 /* Should never reach here */ 435 no_ret plat_panic_handler 436endfunc tsp_yield_smc_entry 437 438 /*--------------------------------------------------------------------- 439 * This entrypoint is used by the TSPD to abort a pre-empted Yielding 440 * SMC. It could be on behalf of non-secure world or because a CPU 441 * suspend/CPU off request needs to abort the preempted SMC. 442 * -------------------------------------------------------------------- 443 */ 444func tsp_abort_yield_smc_entry 445 446 /* 447 * Exceptions masking is already done by the TSPD when entering this 448 * hook so there is no need to do it here. 449 */ 450 451 /* Reset the stack used by the pre-empted SMC */ 452 bl plat_set_my_stack 453 454 /* 455 * Allow some cleanup such as releasing locks. 456 */ 457 bl tsp_abort_smc_handler 458 459 restore_args_call_smc 460 461 /* Should never reach here */ 462 bl plat_panic_handler 463endfunc tsp_abort_yield_smc_entry 464