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 <bl_common.h> 32#include <arch.h> 33#include <tsp.h> 34#include <asm_macros.S> 35 36 37 .globl tsp_entrypoint 38 .globl tsp_cpu_on_entry 39 .globl tsp_cpu_off_entry 40 .globl tsp_cpu_suspend_entry 41 .globl tsp_cpu_resume_entry 42 .globl tsp_fast_smc_entry 43 44 /* --------------------------------------------- 45 * Populate the params in x0-x7 from the pointer 46 * to the smc args structure in x0. 47 * --------------------------------------------- 48 */ 49 .macro restore_args_call_smc 50 ldp x6, x7, [x0, #TSP_ARG6] 51 ldp x4, x5, [x0, #TSP_ARG4] 52 ldp x2, x3, [x0, #TSP_ARG2] 53 ldp x0, x1, [x0, #TSP_ARG0] 54 smc #0 55 .endm 56 57 58func tsp_entrypoint 59 /*--------------------------------------------- 60 * Store the extents of the tzram available to 61 * BL32 for future use. 62 * TODO: We are assuming that x9-x10 will not be 63 * corrupted by any function before platform 64 * setup. 65 * --------------------------------------------- 66 */ 67 mov x9, x0 68 mov x10, x1 69 70 /* --------------------------------------------- 71 * The entrypoint is expected to be executed 72 * only by the primary cpu (at least for now). 73 * So, make sure no secondary has lost its way. 74 * --------------------------------------------- 75 */ 76 mrs x0, mpidr_el1 77 bl platform_is_primary_cpu 78 cbz x0, tsp_entrypoint_panic 79 80 /* --------------------------------------------- 81 * Set the exception vector to something sane. 82 * --------------------------------------------- 83 */ 84 adr x0, early_exceptions 85 msr vbar_el1, x0 86 87 /* --------------------------------------------- 88 * Enable the instruction cache. 89 * --------------------------------------------- 90 */ 91 mrs x0, sctlr_el1 92 orr x0, x0, #SCTLR_I_BIT 93 msr sctlr_el1, x0 94 isb 95 96 /* --------------------------------------------- 97 * Zero out NOBITS sections. There are 2 of them: 98 * - the .bss section; 99 * - the coherent memory section. 100 * --------------------------------------------- 101 */ 102 ldr x0, =__BSS_START__ 103 ldr x1, =__BSS_SIZE__ 104 bl zeromem16 105 106 ldr x0, =__COHERENT_RAM_START__ 107 ldr x1, =__COHERENT_RAM_UNALIGNED_SIZE__ 108 bl zeromem16 109 110 /* -------------------------------------------- 111 * Give ourselves a small coherent stack to 112 * ease the pain of initializing the MMU 113 * -------------------------------------------- 114 */ 115 mrs x0, mpidr_el1 116 bl platform_set_coherent_stack 117 118 /* --------------------------------------------- 119 * Perform early platform setup & platform 120 * specific early arch. setup e.g. mmu setup 121 * --------------------------------------------- 122 */ 123 mov x0, x9 124 mov x1, x10 125 bl bl32_early_platform_setup 126 bl bl32_plat_arch_setup 127 128 /* --------------------------------------------- 129 * Give ourselves a stack allocated in Normal 130 * -IS-WBWA memory 131 * --------------------------------------------- 132 */ 133 mrs x0, mpidr_el1 134 bl platform_set_stack 135 136 /* --------------------------------------------- 137 * Jump to main function. 138 * --------------------------------------------- 139 */ 140 bl tsp_main 141 142 /* --------------------------------------------- 143 * Tell TSPD that we are done initialising 144 * --------------------------------------------- 145 */ 146 mov x1, x0 147 mov x0, #TSP_ENTRY_DONE 148 smc #0 149 150tsp_entrypoint_panic: 151 b tsp_entrypoint_panic 152 153 /*--------------------------------------------- 154 * This entrypoint is used by the TSPD when this 155 * cpu is to be turned off through a CPU_OFF 156 * psci call to ask the TSP to perform any 157 * bookeeping necessary. In the current 158 * implementation, the TSPD expects the TSP to 159 * re-initialise its state so nothing is done 160 * here except for acknowledging the request. 161 * --------------------------------------------- 162 */ 163func tsp_cpu_off_entry 164 bl tsp_cpu_off_main 165 restore_args_call_smc 166 167 /*--------------------------------------------- 168 * This entrypoint is used by the TSPD when this 169 * cpu is turned on using a CPU_ON psci call to 170 * ask the TSP to initialise itself i.e. setup 171 * the mmu, stacks etc. Minimal architectural 172 * state will be initialised by the TSPD when 173 * this function is entered i.e. Caches and MMU 174 * will be turned off, the execution state 175 * will be aarch64 and exceptions masked. 176 * --------------------------------------------- 177 */ 178func tsp_cpu_on_entry 179 /* --------------------------------------------- 180 * Set the exception vector to something sane. 181 * --------------------------------------------- 182 */ 183 adr x0, early_exceptions 184 msr vbar_el1, x0 185 186 /* --------------------------------------------- 187 * Enable the instruction cache. 188 * --------------------------------------------- 189 */ 190 mrs x0, sctlr_el1 191 orr x0, x0, #SCTLR_I_BIT 192 msr sctlr_el1, x0 193 isb 194 195 /* -------------------------------------------- 196 * Give ourselves a small coherent stack to 197 * ease the pain of initializing the MMU 198 * -------------------------------------------- 199 */ 200 mrs x0, mpidr_el1 201 bl platform_set_coherent_stack 202 203 /* --------------------------------------------- 204 * Initialise the MMU 205 * --------------------------------------------- 206 */ 207 bl enable_mmu 208 209 /* --------------------------------------------- 210 * Give ourselves a stack allocated in Normal 211 * -IS-WBWA memory 212 * --------------------------------------------- 213 */ 214 mrs x0, mpidr_el1 215 bl platform_set_stack 216 217 /* --------------------------------------------- 218 * Enter C runtime to perform any remaining 219 * book keeping 220 * --------------------------------------------- 221 */ 222 bl tsp_cpu_on_main 223 restore_args_call_smc 224 225 /* Should never reach here */ 226tsp_cpu_on_entry_panic: 227 b tsp_cpu_on_entry_panic 228 229 /*--------------------------------------------- 230 * This entrypoint is used by the TSPD when this 231 * cpu is to be suspended through a CPU_SUSPEND 232 * psci call to ask the TSP to perform any 233 * bookeeping necessary. In the current 234 * implementation, the TSPD saves and restores 235 * the EL1 state. 236 * --------------------------------------------- 237 */ 238func tsp_cpu_suspend_entry 239 bl tsp_cpu_suspend_main 240 restore_args_call_smc 241 242 /*--------------------------------------------- 243 * This entrypoint is used by the TSPD when this 244 * cpu resumes execution after an earlier 245 * CPU_SUSPEND psci call to ask the TSP to 246 * restore its saved context. In the current 247 * implementation, the TSPD saves and restores 248 * EL1 state so nothing is done here apart from 249 * acknowledging the request. 250 * --------------------------------------------- 251 */ 252func tsp_cpu_resume_entry 253 bl tsp_cpu_resume_main 254 restore_args_call_smc 255tsp_cpu_resume_panic: 256 b tsp_cpu_resume_panic 257 258 /*--------------------------------------------- 259 * This entrypoint is used by the TSPD to ask 260 * the TSP to service a fast smc request. 261 * --------------------------------------------- 262 */ 263func tsp_fast_smc_entry 264 bl tsp_fast_smc_handler 265 restore_args_call_smc 266tsp_fast_smc_entry_panic: 267 b tsp_fast_smc_entry_panic 268 269