[ATF]-smc指令详解
文章目录
- 1、在linux中发起smc的调用
- 2、陷入ATF的smc同步异常后,调用handler和exit_el3返回linux
- 3、fast call和std call的定义
- 4、fast call和std call有什么不同?
★★★ 友情链接 : 个人博客导读首页—点击此处 ★★★
思考:
(1)、在linux中执行smc指令后,是如何调用到ATF中的opteed_smc_handler函数的?
(2)、ATF又是如何返回到linux的?
(3)、fast call和std call又是怎样区分的?
1、在linux中发起smc的调用
SMCCC是一个宏,( \instr #0 )这一行其实就是( smc #0),就是smc调用
在调用smc之前,x0-x8值对应的分别是arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res)中的参数。
.macro SMCCC instr .cfi_startproc \instr #0 ldr x4, [sp] stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS] ret .cfi_endproc .endm /** void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,* unsigned long a3, unsigned long a4, unsigned long a5,* unsigned long a6, unsigned long a7, struct arm_smccc_res *res)*/ ENTRY(arm_smccc_smc)SMCCC smc ENDPROC(arm_smccc_smc) static void optee_smccc_smc(unsigned long a0, unsigned long a1,unsigned long a2, unsigned long a3,unsigned long a4, unsigned long a5,unsigned long a6, unsigned long a7,struct arm_smccc_res *res) {arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res); }invoke_fn = get_invoke_func(np); 这里会指向optee_smccc_smc
2、陷入ATF的smc同步异常后,调用handler和exit_el3返回linux
调用smc之后,cpu触发同步异常,进入ATF的sync_exception_aarch64—>handle_sync_exception—>smc_handler64处理函数
smc_handler64片段:
RT_SVC_DESCS_START + RT_SVC_DESC_HANDLE指向我们在opteed_main.c中注册的handler函数
DECLARE_RT_SVC(opteed_fast,OEN_TOS_START,OEN_TOS_END,SMC_TYPE_FAST,opteed_setup,opteed_smc_handler );/* Define an OPTEED runtime service descriptor for standard SMC calls */ DECLARE_RT_SVC(opteed_std,OEN_TOS_START,OEN_TOS_END,SMC_TYPE_STD,NULL,opteed_smc_handler );在执行完handler函数后,el3_exit调用ERET指令,恢复异常前的PC指针和PSTATE,回到EL1
3、fast call和std call的定义
(1)、在linux的optee_smc.h中,定义了fast call和std call的funcid宏
#define OPTEE_SMC_STD_CALL_VAL(func_num) \ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_32, \ARM_SMCCC_OWNER_TRUSTED_OS, (func_num)) #define OPTEE_SMC_FAST_CALL_VAL(func_num) \ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))在构造funcid宏时,如果是std call,cmd_id的31位需是0,如果是fast call,funcid的31位需是1
#define ARM_SMCCC_STD_CALL 0 #define ARM_SMCCC_FAST_CALL 1 #define ARM_SMCCC_TYPE_SHIFT 31(2)、在optee中 ,对应的也定义了fast和std的type
#define SMC_TYPE_FAST 1 #define SMC_TYPE_STD 0并且分别注册了std服务和fast服务,虽然指向的是同一个函数
/* Define an OPTEED runtime service descriptor for fast SMC calls */ DECLARE_RT_SVC(opteed_fast,OEN_TOS_START,OEN_TOS_END,SMC_TYPE_FAST,opteed_setup,opteed_smc_handler );/* Define an OPTEED runtime service descriptor for standard SMC calls */ DECLARE_RT_SVC(opteed_std,OEN_TOS_START,OEN_TOS_END,SMC_TYPE_STD,NULL,opteed_smc_handler );然后我们再看看,同步异常中断中,跳转的时候,如何解析TYPE的
代码片段
smc_handler64: ....../* Get the unique owning entity number */ubfx x16, x0, #FUNCID_OEN_SHIFT, #FUNCID_OEN_WIDTHubfx x15, x0, #FUNCID_TYPE_SHIFT, #FUNCID_TYPE_WIDTH ......ldr x15, [x11, w10, uxtw] ......blr x15b el3_exit使用ubfx指令,将FUNCID_TYPE_SHIFT和FUNCID_TYPE_WIDTH解析出来,放在了x15中
(3)、fast call和std call的funcid的定义,在ARM文档中有规定
4、fast call和std call有什么不同?
linux—>ATF—>optee的过程中,有fast call和std call,那么在这fast和std中有什么不同呢
(1)、在ATF中,将optee传过来的线程向量表中fast_smc_entry或std_smc_entry写入到ELR_EL3中
(2)、在optee中 fast call会执行thread_handle_fast_smc函数,然后立即执行funcid对应的函数
例如在我们的optee中,定义了如下fast call:
std call执行thread_handle_std_smc函数,该函数中不会立即执行funcid对应的函数,会进行调度等
在我们的optee中,有如下是std call:
总结,CA和TA的通信,都是std call,如open invoke close…,其它的基本是fast call
总结
以上是生活随笔为你收集整理的[ATF]-smc指令详解的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: [ATF]-ATF的异常向量表介绍-(i
- 下一篇: [architecture]-ARMV8