1 /* 2 * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 8 /******************************************************************************* 9 * This is the Secure Payload Dispatcher (SPD). The dispatcher is meant to be a 10 * plug-in component to the Secure Monitor, registered as a runtime service. The 11 * SPD is expected to be a functional extension of the Secure Payload (SP) that 12 * executes in Secure EL1. The Secure Monitor will delegate all SMCs targeting 13 * the Trusted OS/Applications range to the dispatcher. The SPD will either 14 * handle the request locally or delegate it to the Secure Payload. It is also 15 * responsible for initialising and maintaining communication with the SP. 16 ******************************************************************************/ 17 #include <arch_helpers.h> 18 #include <assert.h> 19 #include <bl_common.h> 20 #include <bl31.h> 21 #include <context_mgmt.h> 22 #include <debug.h> 23 #include <errno.h> 24 #include <platform.h> 25 #include <runtime_svc.h> 26 #include <stddef.h> 27 #include <uuid.h> 28 #include "opteed_private.h" 29 #include "teesmc_opteed_macros.h" 30 #include "teesmc_opteed.h" 31 32 /******************************************************************************* 33 * Address of the entrypoint vector table in OPTEE. It is 34 * initialised once on the primary core after a cold boot. 35 ******************************************************************************/ 36 optee_vectors_t *optee_vectors; 37 38 /******************************************************************************* 39 * Array to keep track of per-cpu OPTEE state 40 ******************************************************************************/ 41 optee_context_t opteed_sp_context[OPTEED_CORE_COUNT]; 42 uint32_t opteed_rw; 43 44 45 46 static int32_t opteed_init(void); 47 48 /******************************************************************************* 49 * This function is the handler registered for S-EL1 interrupts by the 50 * OPTEED. It validates the interrupt and upon success arranges entry into 51 * the OPTEE at 'optee_fiq_entry()' for handling the interrupt. 52 ******************************************************************************/ 53 static uint64_t opteed_sel1_interrupt_handler(uint32_t id, 54 uint32_t flags, 55 void *handle, 56 void *cookie) 57 { 58 uint32_t linear_id; 59 optee_context_t *optee_ctx; 60 61 /* Check the security state when the exception was generated */ 62 assert(get_interrupt_src_ss(flags) == NON_SECURE); 63 64 /* Sanity check the pointer to this cpu's context */ 65 assert(handle == cm_get_context(NON_SECURE)); 66 67 /* Save the non-secure context before entering the OPTEE */ 68 cm_el1_sysregs_context_save(NON_SECURE); 69 70 /* Get a reference to this cpu's OPTEE context */ 71 linear_id = plat_my_core_pos(); 72 optee_ctx = &opteed_sp_context[linear_id]; 73 assert(&optee_ctx->cpu_ctx == cm_get_context(SECURE)); 74 75 cm_set_elr_el3(SECURE, (uint64_t)&optee_vectors->fiq_entry); 76 cm_el1_sysregs_context_restore(SECURE); 77 cm_set_next_eret_context(SECURE); 78 79 /* 80 * Tell the OPTEE that it has to handle an FIQ (synchronously). 81 * Also the instruction in normal world where the interrupt was 82 * generated is passed for debugging purposes. It is safe to 83 * retrieve this address from ELR_EL3 as the secure context will 84 * not take effect until el3_exit(). 85 */ 86 SMC_RET1(&optee_ctx->cpu_ctx, read_elr_el3()); 87 } 88 89 /******************************************************************************* 90 * OPTEE Dispatcher setup. The OPTEED finds out the OPTEE entrypoint and type 91 * (aarch32/aarch64) if not already known and initialises the context for entry 92 * into OPTEE for its initialization. 93 ******************************************************************************/ 94 int32_t opteed_setup(void) 95 { 96 entry_point_info_t *optee_ep_info; 97 uint32_t linear_id; 98 99 linear_id = plat_my_core_pos(); 100 101 /* 102 * Get information about the Secure Payload (BL32) image. Its 103 * absence is a critical failure. TODO: Add support to 104 * conditionally include the SPD service 105 */ 106 optee_ep_info = bl31_plat_get_next_image_ep_info(SECURE); 107 if (!optee_ep_info) { 108 WARN("No OPTEE provided by BL2 boot loader, Booting device" 109 " without OPTEE initialization. SMC`s destined for OPTEE" 110 " will return SMC_UNK\n"); 111 return 1; 112 } 113 114 /* 115 * If there's no valid entry point for SP, we return a non-zero value 116 * signalling failure initializing the service. We bail out without 117 * registering any handlers 118 */ 119 if (!optee_ep_info->pc) 120 return 1; 121 122 /* 123 * We could inspect the SP image and determine it's execution 124 * state i.e whether AArch32 or AArch64. Assuming it's AArch32 125 * for the time being. 126 */ 127 opteed_rw = OPTEE_AARCH64; 128 opteed_init_optee_ep_state(optee_ep_info, 129 opteed_rw, 130 optee_ep_info->pc, 131 &opteed_sp_context[linear_id]); 132 133 /* 134 * All OPTEED initialization done. Now register our init function with 135 * BL31 for deferred invocation 136 */ 137 bl31_register_bl32_init(&opteed_init); 138 139 return 0; 140 } 141 142 /******************************************************************************* 143 * This function passes control to the OPTEE image (BL32) for the first time 144 * on the primary cpu after a cold boot. It assumes that a valid secure 145 * context has already been created by opteed_setup() which can be directly 146 * used. It also assumes that a valid non-secure context has been 147 * initialised by PSCI so it does not need to save and restore any 148 * non-secure state. This function performs a synchronous entry into 149 * OPTEE. OPTEE passes control back to this routine through a SMC. 150 ******************************************************************************/ 151 static int32_t opteed_init(void) 152 { 153 uint32_t linear_id = plat_my_core_pos(); 154 optee_context_t *optee_ctx = &opteed_sp_context[linear_id]; 155 entry_point_info_t *optee_entry_point; 156 uint64_t rc; 157 158 /* 159 * Get information about the OPTEE (BL32) image. Its 160 * absence is a critical failure. 161 */ 162 optee_entry_point = bl31_plat_get_next_image_ep_info(SECURE); 163 assert(optee_entry_point); 164 165 cm_init_my_context(optee_entry_point); 166 167 /* 168 * Arrange for an entry into OPTEE. It will be returned via 169 * OPTEE_ENTRY_DONE case 170 */ 171 rc = opteed_synchronous_sp_entry(optee_ctx); 172 assert(rc != 0); 173 174 return rc; 175 } 176 177 178 /******************************************************************************* 179 * This function is responsible for handling all SMCs in the Trusted OS/App 180 * range from the non-secure state as defined in the SMC Calling Convention 181 * Document. It is also responsible for communicating with the Secure 182 * payload to delegate work and return results back to the non-secure 183 * state. Lastly it will also return any information that OPTEE needs to do 184 * the work assigned to it. 185 ******************************************************************************/ 186 uint64_t opteed_smc_handler(uint32_t smc_fid, 187 uint64_t x1, 188 uint64_t x2, 189 uint64_t x3, 190 uint64_t x4, 191 void *cookie, 192 void *handle, 193 uint64_t flags) 194 { 195 cpu_context_t *ns_cpu_context; 196 uint32_t linear_id = plat_my_core_pos(); 197 optee_context_t *optee_ctx = &opteed_sp_context[linear_id]; 198 uint64_t rc; 199 200 /* 201 * Determine which security state this SMC originated from 202 */ 203 204 if (is_caller_non_secure(flags)) { 205 /* 206 * This is a fresh request from the non-secure client. 207 * The parameters are in x1 and x2. Figure out which 208 * registers need to be preserved, save the non-secure 209 * state and send the request to the secure payload. 210 */ 211 assert(handle == cm_get_context(NON_SECURE)); 212 213 cm_el1_sysregs_context_save(NON_SECURE); 214 215 /* 216 * We are done stashing the non-secure context. Ask the 217 * OPTEE to do the work now. 218 */ 219 220 /* 221 * Verify if there is a valid context to use, copy the 222 * operation type and parameters to the secure context 223 * and jump to the fast smc entry point in the secure 224 * payload. Entry into S-EL1 will take place upon exit 225 * from this function. 226 */ 227 assert(&optee_ctx->cpu_ctx == cm_get_context(SECURE)); 228 229 /* Set appropriate entry for SMC. 230 * We expect OPTEE to manage the PSTATE.I and PSTATE.F 231 * flags as appropriate. 232 */ 233 if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_FAST) { 234 cm_set_elr_el3(SECURE, (uint64_t) 235 &optee_vectors->fast_smc_entry); 236 } else { 237 cm_set_elr_el3(SECURE, (uint64_t) 238 &optee_vectors->std_smc_entry); 239 } 240 241 cm_el1_sysregs_context_restore(SECURE); 242 cm_set_next_eret_context(SECURE); 243 244 write_ctx_reg(get_gpregs_ctx(&optee_ctx->cpu_ctx), 245 CTX_GPREG_X4, 246 read_ctx_reg(get_gpregs_ctx(handle), 247 CTX_GPREG_X4)); 248 write_ctx_reg(get_gpregs_ctx(&optee_ctx->cpu_ctx), 249 CTX_GPREG_X5, 250 read_ctx_reg(get_gpregs_ctx(handle), 251 CTX_GPREG_X5)); 252 write_ctx_reg(get_gpregs_ctx(&optee_ctx->cpu_ctx), 253 CTX_GPREG_X6, 254 read_ctx_reg(get_gpregs_ctx(handle), 255 CTX_GPREG_X6)); 256 /* Propagate hypervisor client ID */ 257 write_ctx_reg(get_gpregs_ctx(&optee_ctx->cpu_ctx), 258 CTX_GPREG_X7, 259 read_ctx_reg(get_gpregs_ctx(handle), 260 CTX_GPREG_X7)); 261 262 SMC_RET4(&optee_ctx->cpu_ctx, smc_fid, x1, x2, x3); 263 } 264 265 /* 266 * Returning from OPTEE 267 */ 268 269 switch (smc_fid) { 270 /* 271 * OPTEE has finished initialising itself after a cold boot 272 */ 273 case TEESMC_OPTEED_RETURN_ENTRY_DONE: 274 /* 275 * Stash the OPTEE entry points information. This is done 276 * only once on the primary cpu 277 */ 278 assert(optee_vectors == NULL); 279 optee_vectors = (optee_vectors_t *) x1; 280 281 if (optee_vectors) { 282 set_optee_pstate(optee_ctx->state, OPTEE_PSTATE_ON); 283 284 /* 285 * OPTEE has been successfully initialized. 286 * Register power management hooks with PSCI 287 */ 288 psci_register_spd_pm_hook(&opteed_pm); 289 290 /* 291 * Register an interrupt handler for S-EL1 interrupts 292 * when generated during code executing in the 293 * non-secure state. 294 */ 295 flags = 0; 296 set_interrupt_rm_flag(flags, NON_SECURE); 297 rc = register_interrupt_type_handler(INTR_TYPE_S_EL1, 298 opteed_sel1_interrupt_handler, 299 flags); 300 if (rc) 301 panic(); 302 } 303 304 /* 305 * OPTEE reports completion. The OPTEED must have initiated 306 * the original request through a synchronous entry into 307 * OPTEE. Jump back to the original C runtime context. 308 */ 309 opteed_synchronous_sp_exit(optee_ctx, x1); 310 311 312 /* 313 * These function IDs is used only by OP-TEE to indicate it has 314 * finished: 315 * 1. turning itself on in response to an earlier psci 316 * cpu_on request 317 * 2. resuming itself after an earlier psci cpu_suspend 318 * request. 319 */ 320 case TEESMC_OPTEED_RETURN_ON_DONE: 321 case TEESMC_OPTEED_RETURN_RESUME_DONE: 322 323 324 /* 325 * These function IDs is used only by the SP to indicate it has 326 * finished: 327 * 1. suspending itself after an earlier psci cpu_suspend 328 * request. 329 * 2. turning itself off in response to an earlier psci 330 * cpu_off request. 331 */ 332 case TEESMC_OPTEED_RETURN_OFF_DONE: 333 case TEESMC_OPTEED_RETURN_SUSPEND_DONE: 334 case TEESMC_OPTEED_RETURN_SYSTEM_OFF_DONE: 335 case TEESMC_OPTEED_RETURN_SYSTEM_RESET_DONE: 336 337 /* 338 * OPTEE reports completion. The OPTEED must have initiated the 339 * original request through a synchronous entry into OPTEE. 340 * Jump back to the original C runtime context, and pass x1 as 341 * return value to the caller 342 */ 343 opteed_synchronous_sp_exit(optee_ctx, x1); 344 345 /* 346 * OPTEE is returning from a call or being preempted from a call, in 347 * either case execution should resume in the normal world. 348 */ 349 case TEESMC_OPTEED_RETURN_CALL_DONE: 350 /* 351 * This is the result from the secure client of an 352 * earlier request. The results are in x0-x3. Copy it 353 * into the non-secure context, save the secure state 354 * and return to the non-secure state. 355 */ 356 assert(handle == cm_get_context(SECURE)); 357 cm_el1_sysregs_context_save(SECURE); 358 359 /* Get a reference to the non-secure context */ 360 ns_cpu_context = cm_get_context(NON_SECURE); 361 assert(ns_cpu_context); 362 363 /* Restore non-secure state */ 364 cm_el1_sysregs_context_restore(NON_SECURE); 365 cm_set_next_eret_context(NON_SECURE); 366 367 SMC_RET4(ns_cpu_context, x1, x2, x3, x4); 368 369 /* 370 * OPTEE has finished handling a S-EL1 FIQ interrupt. Execution 371 * should resume in the normal world. 372 */ 373 case TEESMC_OPTEED_RETURN_FIQ_DONE: 374 /* Get a reference to the non-secure context */ 375 ns_cpu_context = cm_get_context(NON_SECURE); 376 assert(ns_cpu_context); 377 378 /* 379 * Restore non-secure state. There is no need to save the 380 * secure system register context since OPTEE was supposed 381 * to preserve it during S-EL1 interrupt handling. 382 */ 383 cm_el1_sysregs_context_restore(NON_SECURE); 384 cm_set_next_eret_context(NON_SECURE); 385 386 SMC_RET0((uint64_t) ns_cpu_context); 387 388 default: 389 panic(); 390 } 391 } 392 393 /* Define an OPTEED runtime service descriptor for fast SMC calls */ 394 DECLARE_RT_SVC( 395 opteed_fast, 396 397 OEN_TOS_START, 398 OEN_TOS_END, 399 SMC_TYPE_FAST, 400 opteed_setup, 401 opteed_smc_handler 402 ); 403 404 /* Define an OPTEED runtime service descriptor for standard SMC calls */ 405 DECLARE_RT_SVC( 406 opteed_std, 407 408 OEN_TOS_START, 409 OEN_TOS_END, 410 SMC_TYPE_STD, 411 NULL, 412 opteed_smc_handler 413 ); 414