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