当在TA中通过system call陷入到secure的el1的时候会调用到core/arch/arm/kernel/thread_a64.S中的el0_sync_a64
el0_sync_a64:
store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 3
mrs x2, esr_el1
mrs x3, sp_el0
lsr x2, x2, #ESR_EC_SHIFT
cmp x2, #ESR_EC_AARCH64_SVC
b.eq el0_svc
b el0_sync_abort
check_vector_size el0_sync_a64
.align 7
在el0_sync_a64 中又会call el0_svc
LOCAL_FUNC el0_svc , :
/* get pointer to current thread context in x0 */
get_thread_ctx sp, 0, 1, 2
/* load saved kernel sp */
ldr x0, [x0, #THREAD_CTX_KERN_SP]
/* Keep pointer to initial recod in x1 */
mov x1, sp
/* Switch to SP_EL0 and restore kernel sp */
msr spsel, #0
mov x2, sp /* Save SP_EL0 */
mov sp, x0
/*
* Unmask native interrupts, Serror, and debug exceptions since we have
* nothing left in sp_el1. Note that the SVC handler is excepted to
* re-enable foreign interrupts by itself.
*/
msr daifclr, #(DAIFBIT_FIQ | DAIFBIT_ABT | DAIFBIT_DBG)
/* Call the handler */
bl tee_svc_handler
跳转到tee_svc_handler
void tee_svc_handler(struct thread_svc_regs *regs)
{
size_t scn;
size_t max_args;
syscall_t scf;
//所有的系统调用都定义在tee_svc_syscall_table 这个数组中
COMPILE_TIME_ASSERT(ARRAY_SIZE(tee_svc_syscall_table) ==
(TEE_SCN_MAX + 1));
thread_user_save_vfp();
/* TA has just entered kernel mode */
tee_ta_update_session_utime_suspend();
/* Restore foreign interrupts which are disabled on exception entry */
thread_restore_foreign_intr();
//得到具体调用的systemcall的id,即scn
get_scn_max_args(regs, &scn, &max_args);
trace_syscall(scn);
if (max_args > TEE_SVC_MAX_ARGS) {
DMSG("Too many arguments for SCN %zu (%zu)", scn, max_args);
set_svc_retval(regs, TEE_ERROR_GENERIC);
return;
}
if (scn > TEE_SCN_MAX)
scf = syscall_not_supported;
else // 指向这个systemcall
scf = tee_svc_syscall_table[scn].fn;
//通过tee_svc_do_call 来调用这个system call,tee_svc_do_call 定义在/core/arch/arm/tee/arch_svc_a64.S 中会通过tee_svc_copy_from_user 从user space copy数据
set_svc_retval(regs, tee_svc_do_call(regs, scf));
if (scn != TEE_SCN_RETURN) {
/* We're about to switch back to user mode */
tee_ta_update_session_utime_resume();
}
}
el0_sync_a64:
store_xregs sp, THREAD_CORE_LOCAL_X0, 0, 3
mrs x2, esr_el1
mrs x3, sp_el0
lsr x2, x2, #ESR_EC_SHIFT
cmp x2, #ESR_EC_AARCH64_SVC
b.eq el0_svc
b el0_sync_abort
check_vector_size el0_sync_a64
.align 7
在el0_sync_a64 中又会call el0_svc
LOCAL_FUNC el0_svc , :
/* get pointer to current thread context in x0 */
get_thread_ctx sp, 0, 1, 2
/* load saved kernel sp */
ldr x0, [x0, #THREAD_CTX_KERN_SP]
/* Keep pointer to initial recod in x1 */
mov x1, sp
/* Switch to SP_EL0 and restore kernel sp */
msr spsel, #0
mov x2, sp /* Save SP_EL0 */
mov sp, x0
/*
* Unmask native interrupts, Serror, and debug exceptions since we have
* nothing left in sp_el1. Note that the SVC handler is excepted to
* re-enable foreign interrupts by itself.
*/
msr daifclr, #(DAIFBIT_FIQ | DAIFBIT_ABT | DAIFBIT_DBG)
/* Call the handler */
bl tee_svc_handler
跳转到tee_svc_handler
void tee_svc_handler(struct thread_svc_regs *regs)
{
size_t scn;
size_t max_args;
syscall_t scf;
//所有的系统调用都定义在tee_svc_syscall_table 这个数组中
COMPILE_TIME_ASSERT(ARRAY_SIZE(tee_svc_syscall_table) ==
(TEE_SCN_MAX + 1));
thread_user_save_vfp();
/* TA has just entered kernel mode */
tee_ta_update_session_utime_suspend();
/* Restore foreign interrupts which are disabled on exception entry */
thread_restore_foreign_intr();
//得到具体调用的systemcall的id,即scn
get_scn_max_args(regs, &scn, &max_args);
trace_syscall(scn);
if (max_args > TEE_SVC_MAX_ARGS) {
DMSG("Too many arguments for SCN %zu (%zu)", scn, max_args);
set_svc_retval(regs, TEE_ERROR_GENERIC);
return;
}
if (scn > TEE_SCN_MAX)
scf = syscall_not_supported;
else // 指向这个systemcall
scf = tee_svc_syscall_table[scn].fn;
//通过tee_svc_do_call 来调用这个system call,tee_svc_do_call 定义在/core/arch/arm/tee/arch_svc_a64.S 中会通过tee_svc_copy_from_user 从user space copy数据
set_svc_retval(regs, tee_svc_do_call(regs, scf));
if (scn != TEE_SCN_RETURN) {
/* We're about to switch back to user mode */
tee_ta_update_session_utime_resume();
}
}