optee os 中的系统调用

当在TA 中发生系统调用时,其入口函数在optee_os-master/core/arch/arm/kernel/thread_a64.S
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
     /* 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;

    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();
得到系统调用的id
    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
根据id 调用系统调用,所以在optee中所有的系统调用都是定义在tee_svc_syscall_table 这个数组中
        scf = tee_svc_syscall_table[scn].fn;

    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();
    }
}
static const struct syscall_entry tee_svc_syscall_table[] = {
    SYSCALL_ENTRY(syscall_get_time),
}
以get_time 为例
TEE_Result syscall_get_time(unsigned long cat, TEE_Time *mytime)
{
    TEE_Result res, res2;
    struct tee_ta_session *s = NULL;
    TEE_Time t;
//session是TA和CA 通信的基础,得到当前的session
    res = tee_ta_get_current_session(&s);
    if (res != TEE_SUCCESS)
        return res;
//根据cat来判断要得到哪个时间
    switch (cat) {
    case UTEE_TIME_CAT_SYSTEM:
        res = tee_time_get_sys_time(&t);
        break;
    case UTEE_TIME_CAT_TA_PERSISTENT:
        res = tee_time_get_ta_time((const void *)&s->ctx->uuid, &t);
        break;
    case UTEE_TIME_CAT_REE:
        res = tee_time_get_ree_time(&t);
        break;
    default:
        res = TEE_ERROR_BAD_PARAMETERS;
        break;
    }
//成功得到时间后,通过tee_svc_copy_to_user 将数据copy到user space的TA
    if (res == TEE_SUCCESS || res == TEE_ERROR_OVERFLOW) {
        res2 = tee_svc_copy_to_user(mytime, &t, sizeof(t));
        if (res2 != TEE_SUCCESS)
            res = res2;
    }

    return res;
}
以UTEE_TIME_CAT_SYSTEM 为例的话,其实现如下:
TEE_Result tee_time_get_sys_time(TEE_Time *time)
{
    return _time_source.get_sys_time(time);
}



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值