1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2016-2020, Linaro Limited 4 * Copyright (c) 2014, STMicroelectronics International N.V. 5 */ 6 #include <arm.h> 7 #include <compiler.h> 8 #include <config.h> 9 #include <kernel/misc.h> 10 #include <kernel/thread.h> 11 #include <platform_config.h> 12 #include <sm/optee_smc.h> 13 #include <sm/sm.h> 14 #include <sm/std_smc.h> 15 #include <string.h> 16 #include "sm_private.h" 17 18 static void smc_arch_handler(struct thread_smc_args *args) 19 { 20 uint32_t smc_fid = args->a0; 21 uint32_t feature_fid = args->a1; 22 23 switch (smc_fid) { 24 case ARM_SMCCC_VERSION: 25 args->a0 = SMCCC_V_1_1; 26 break; 27 case ARM_SMCCC_ARCH_FEATURES: 28 switch (feature_fid) { 29 case ARM_SMCCC_VERSION: 30 case ARM_SMCCC_ARCH_SOC_ID: 31 args->a0 = ARM_SMCCC_RET_SUCCESS; 32 break; 33 default: 34 args->a0 = ARM_SMCCC_RET_NOT_SUPPORTED; 35 break; 36 } 37 break; 38 case ARM_SMCCC_ARCH_SOC_ID: 39 args->a0 = ARM_SMCCC_RET_NOT_SUPPORTED; 40 break; 41 case ARM_SMCCC_ARCH_WORKAROUND_1: 42 case ARM_SMCCC_ARCH_WORKAROUND_2: 43 args->a0 = ARM_SMCCC_RET_NOT_REQUIRED; 44 break; 45 default: 46 args->a0 = OPTEE_SMC_RETURN_UNKNOWN_FUNCTION; 47 break; 48 } 49 } 50 51 uint32_t sm_from_nsec(struct sm_ctx *ctx) 52 { 53 uint32_t *nsec_r0 = (uint32_t *)(&ctx->nsec.r0); 54 struct thread_smc_args *args = (struct thread_smc_args *)nsec_r0; 55 56 /* 57 * Check that struct sm_ctx has the different parts properly 58 * aligned since the stack pointer will be updated to point at 59 * different parts of this struct. 60 */ 61 COMPILE_TIME_ASSERT(!(offsetof(struct sm_ctx, sec.r0) % 8)); 62 COMPILE_TIME_ASSERT(!(offsetof(struct sm_ctx, nsec.r0) % 8)); 63 COMPILE_TIME_ASSERT(!(sizeof(struct sm_ctx) % 8)); 64 65 #ifdef CFG_SM_PLATFORM_HANDLER 66 if (sm_platform_handler(ctx) == SM_HANDLER_SMC_HANDLED) 67 return SM_EXIT_TO_NON_SECURE; 68 #endif 69 70 switch (OPTEE_SMC_OWNER_NUM(args->a0)) { 71 case OPTEE_SMC_OWNER_STANDARD: 72 if (IS_ENABLED(CFG_PSCI_ARM32)) { 73 smc_std_handler(args, &ctx->nsec); 74 return SM_EXIT_TO_NON_SECURE; 75 } 76 break; 77 case OPTEE_SMC_OWNER_ARCH: 78 smc_arch_handler(args); 79 return SM_EXIT_TO_NON_SECURE; 80 default: 81 break; 82 } 83 84 sm_save_unbanked_regs(&ctx->nsec.ub_regs); 85 sm_restore_unbanked_regs(&ctx->sec.ub_regs); 86 87 memcpy(&ctx->sec.r0, args, sizeof(*args)); 88 if (OPTEE_SMC_IS_FAST_CALL(ctx->sec.r0)) 89 ctx->sec.mon_lr = (uint32_t)&thread_vector_table.fast_smc_entry; 90 else 91 ctx->sec.mon_lr = (uint32_t)&thread_vector_table.std_smc_entry; 92 93 return SM_EXIT_TO_SECURE; 94 } 95