快速连接
👉👉👉【精选】ARMv8/ARMv9架构入门到精通-目录 👈👈👈
1、optee的fast call调用的代码导读
如果调用的是fast call,在ATF的代码中,将会把optee_vector_table->fast_smc_entry地址赋给ELR_EL3寄存器,el3_exit退出后,PC将会跳转到该地址处,对应着optee_os中的线程向量表vector_fast_smc_entry地址
static uintptr_t opteed_smc_handler(uint32_t smc_fid,
u_register_t x1,
u_register_t x2,
u_register_t x3,
u_register_t x4,
void *cookie,
void *handle,
u_register_t flags)
{
...
if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_FAST) {
cm_set_elr_el3(SECURE, (uint64_t)
&optee_vector_table->fast_smc_entry);
} else {
cm_set_elr_el3(SECURE, (uint64_t)
&optee_vector_table->yield_smc_entry);
}
...
}
optee_os中的线程向量表的定义
/*
* Vector table supplied to ARM Trusted Firmware (ARM-TF) at
* initialization.
*
* Note that ARM-TF depends on the layout of this vector table, any change
* in layout has to be synced with ARM-TF.
*/
FUNC thread_vector_table , : , .identity_map
b vector_std_smc_entry
b vector_fast_smc_entry
b vector_cpu_on_entry
b vector_cpu_off_entry
b vector_cpu_resume_entry
b vector_cpu_suspend_entry
b vector_fiq_entry
b vector_system_off_entry
b vector_system_reset_entry
END_FUNC thread_vector_table
DECLARE_KEEP_PAGER thread_vector_table
vector_fast_smc_entry的实现
LOCAL_FUNC vector_fast_smc_entry , : , .identity_map
readjust_pc
sub sp, sp, #THREAD_SMC_ARGS_SIZE
store_xregs sp, THREAD_SMC_ARGS_X0, 0, 7
mov x0, sp
bl thread_handle_fast_smc
load_xregs sp, THREAD_SMC_ARGS_X0, 1, 8
add sp, sp, #THREAD_SMC_ARGS_SIZE
ldr x0, =TEESMC_OPTEED_RETURN_CALL_DONE
smc #0
b . /* SMC should not return */
END_FUNC vector_fast_smc_entry
optee_os中fast call的实现
void thread_handle_fast_smc(struct thread_smc_args *args)
{
thread_check_canaries();
#ifdef CFG_VIRTUALIZATION
if (!virt_set_guest(args->a7)) {
args->a0 = OPTEE_SMC_RETURN_ENOTAVAIL;
goto out;
}
#endif
tee_entry_fast(args);
#ifdef CFG_VIRTUALIZATION
virt_unset_guest();
#endif
/* Fast handlers must not unmask any exceptions */
out:
__maybe_unused;
assert(thread_get_exceptions() == THREAD_EXCP_ALL);
}
/* Note: this function is weak to let platforms add special handling */
void __weak tee_entry_fast(struct thread_smc_args *args)
{
__tee_entry_fast(args);
}
/*
* If tee_entry_fast() is overridden, it's still supposed to call this
* function.
*/
void __tee_entry_fast(struct thread_smc_args *args)
{
switch (args->a0) {
/* Generic functions */
case OPTEE_SMC_CALLS_COUNT:
tee_entry_get_api_call_count(args);
break;
case OPTEE_SMC_CALLS_UID:
tee_entry_get_api_uuid(args);
break;
case OPTEE_SMC_CALLS_REVISION:
tee_entry_get_api_revision(args);
break;
case OPTEE_SMC_CALL_GET_OS_UUID:
tee_entry_get_os_uuid(args);
break;
case OPTEE_SMC_CALL_GET_OS_REVISION:
tee_entry_get_os_revision(args);
break;
/* OP-TEE specific SMC functions */
#ifdef CFG_CORE_RESERVED_SHM
case OPTEE_SMC_GET_SHM_CONFIG:
tee_entry_get_shm_config(args);
break;
#endif
case OPTEE_SMC_L2CC_MUTEX:
tee_entry_fastcall_l2cc_mutex(args);
break;
case OPTEE_SMC_EXCHANGE_CAPABILITIES:
tee_entry_exchange_capabilities(args);
break;
case OPTEE_SMC_DISABLE_SHM_CACHE:
tee_entry_disable_shm_cache(args);
break;
case OPTEE_SMC_ENABLE_SHM_CACHE:
tee_entry_enable_shm_cache(args);
break;
case OPTEE_SMC_BOOT_SECONDARY:
tee_entry_boot_secondary(args);
break;
case OPTEE_SMC_GET_THREAD_COUNT:
tee_entry_get_thread_count(args);
break;
#if defined(CFG_VIRTUALIZATION)
case OPTEE_SMC_VM_CREATED:
tee_entry_vm_created(args);
break;
case OPTEE_SMC_VM_DESTROYED:
tee_entry_vm_destroyed(args);
break;
#endif
default:
args->a0 = OPTEE_SMC_RETURN_UNKNOWN_FUNCTION;
break;
}
}
关注"Arm精选"公众号,备注进ARM交流讨论区。