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 sm_platform_handler(struct sm_ctx * ctx __unused)18enum sm_handler_ret __weak sm_platform_handler(struct sm_ctx *ctx __unused) 19 { 20 return SM_HANDLER_PENDING_SMC; 21 } 22 smc_arch_handler(struct thread_smc_args * args)23static void smc_arch_handler(struct thread_smc_args *args) 24 { 25 uint32_t smc_fid = args->a0; 26 uint32_t feature_fid = args->a1; 27 28 switch (smc_fid) { 29 case ARM_SMCCC_VERSION: 30 args->a0 = SMCCC_V_1_1; 31 break; 32 case ARM_SMCCC_ARCH_FEATURES: 33 switch (feature_fid) { 34 case ARM_SMCCC_VERSION: 35 case ARM_SMCCC_ARCH_SOC_ID: 36 args->a0 = ARM_SMCCC_RET_SUCCESS; 37 break; 38 default: 39 args->a0 = ARM_SMCCC_RET_NOT_SUPPORTED; 40 break; 41 } 42 break; 43 case ARM_SMCCC_ARCH_SOC_ID: 44 args->a0 = ARM_SMCCC_RET_NOT_SUPPORTED; 45 break; 46 case ARM_SMCCC_ARCH_WORKAROUND_1: 47 case ARM_SMCCC_ARCH_WORKAROUND_2: 48 args->a0 = ARM_SMCCC_RET_NOT_REQUIRED; 49 break; 50 default: 51 args->a0 = OPTEE_SMC_RETURN_UNKNOWN_FUNCTION; 52 break; 53 } 54 } 55 sm_from_nsec(struct sm_ctx * ctx)56uint32_t sm_from_nsec(struct sm_ctx *ctx) 57 { 58 uint32_t *nsec_r0 = (uint32_t *)(&ctx->nsec.r0); 59 struct thread_smc_args *args = (struct thread_smc_args *)nsec_r0; 60 61 /* 62 * Check that struct sm_ctx has the different parts properly 63 * aligned since the stack pointer will be updated to point at 64 * different parts of this struct. 65 */ 66 COMPILE_TIME_ASSERT(!(offsetof(struct sm_ctx, sec.r0) % 8)); 67 COMPILE_TIME_ASSERT(!(offsetof(struct sm_ctx, nsec.r0) % 8)); 68 COMPILE_TIME_ASSERT(!(sizeof(struct sm_ctx) % 8)); 69 70 if (IS_ENABLED(CFG_SM_PLATFORM_HANDLER) && 71 sm_platform_handler(ctx) == SM_HANDLER_SMC_HANDLED) 72 return SM_EXIT_TO_NON_SECURE; 73 74 switch (OPTEE_SMC_OWNER_NUM(args->a0)) { 75 case OPTEE_SMC_OWNER_STANDARD: 76 if (IS_ENABLED(CFG_PSCI_ARM32)) { 77 smc_std_handler(args, &ctx->nsec); 78 return SM_EXIT_TO_NON_SECURE; 79 } 80 break; 81 case OPTEE_SMC_OWNER_ARCH: 82 smc_arch_handler(args); 83 return SM_EXIT_TO_NON_SECURE; 84 default: 85 break; 86 } 87 88 sm_save_unbanked_regs(&ctx->nsec.ub_regs); 89 sm_restore_unbanked_regs(&ctx->sec.ub_regs); 90 91 memcpy(&ctx->sec.r0, args, sizeof(*args)); 92 if (OPTEE_SMC_IS_FAST_CALL(ctx->sec.r0)) 93 ctx->sec.mon_lr = (uint32_t)vector_fast_smc_entry; 94 else 95 ctx->sec.mon_lr = (uint32_t)vector_std_smc_entry; 96 97 return SM_EXIT_TO_SECURE; 98 } 99