如何解释ARM的SMC调用?
How to interpret ARM's SMC calls?
我一直在阅读 Android 的内核,以了解 CPU 内核(又名 DVFS、DCVS)的动态电源管理是如何完成的。我找到的代码 here makes some calls to the following function (defined here) 依次调用 SMC 汇编指令。
ARM有文档解释SMC calling convention,但我一直没能用它来理解下面的功能。我如何进一步追踪 SMC 指令以查看它根据其输入操作数实际执行的操作?
s32 scm_call_atomic4_3(u32 svc, u32 cmd, u32 arg1, u32 arg2,
u32 arg3, u32 arg4, u32 *ret1, u32 *ret2)
{
int ret;
int context_id;
register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 4);
register u32 r1 asm("r1") = (u32)&context_id;
register u32 r2 asm("r2") = arg1;
register u32 r3 asm("r3") = arg2;
register u32 r4 asm("r4") = arg3;
register u32 r5 asm("r5") = arg4;
asm volatile(
__asmeq("%0", "r0")
__asmeq("%1", "r1")
__asmeq("%2", "r2")
__asmeq("%3", "r0")
__asmeq("%4", "r1")
__asmeq("%5", "r2")
__asmeq("%6", "r3")
#ifdef REQUIRES_SEC
".arch_extension sec\n"
#endif
"smc #0 @ switch to secure world\n"
: "=r" (r0), "=r" (r1), "=r" (r2)
: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4), "r" (r5));
ret = r0;
if (ret1)
*ret1 = r1;
if (ret2)
*ret2 = r2;
return r0;
}
EXPORT_SYMBOL(scm_call_atomic4_3);
SMC calling conventions是ARM关于如何实现cross worldAPI的建议,让多个厂商可以在任意一个world编写代码,共同协作- 以最小的不兼容性存在。至少那是意图。供应商(Android/Linux 在您的情况下)不必执行此操作,如果安全世界不遵循它,则可能无法执行此操作。
but I haven't been able to use it to make sense of the following function
SMC
指令是从正常世界到安全监视器的受控更改。监视器有自己的向量 table,svc
的条目是 SMC 调用。寄存器是世界之间的 'shared' 信息。通常在世界切换上,监视器可能会将所有寄存器换出到某个上下文存储。在SMC
情况下,寄存器可以传递参数和return结果。这就是这个函数所做的全部。
register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 4);
这是liketableSMC调用约定文档中的位域table2-1。它是从正常世界 Linux 到安全监视器来告诉哪个函数(以及参数数量 marshal/keep 的四个)。
register u32 r2 asm("r2") = arg1;
register u32 r3 asm("r3") = arg2;
register u32 r4 asm("r4") = arg3;
register u32 r5 asm("r5") = arg4;
如果ARM ABI是偶然的,参数arg1-arg4已经在这些寄存器中,所以不会生成代码。全局 context_id
(到 Linux/Android 内核)也被传递。
How can I track down the SMC instruction further to see what it actually does based on its input operands?
为此,您需要安全世界的代码。我的猜测是,这是一些小区 phone 和基带等在安全世界中,代码不可用。如果您有安全世界代码,监控向量 table 将有一个 SMC
条目。这将有一个基于 r0
或 'cmd' 值的开关(或 if/then),它选择特定的 smc
函数。通用 smc
处理程序可以恢复安全世界 registers/context 但保留 r0
位字段中指定的四个参数。
所以答案可能是您无法追踪它的作用。您必须依赖供应商文档,或者幸运地拥有通往安全世界的代码。
我一直在阅读 Android 的内核,以了解 CPU 内核(又名 DVFS、DCVS)的动态电源管理是如何完成的。我找到的代码 here makes some calls to the following function (defined here) 依次调用 SMC 汇编指令。
ARM有文档解释SMC calling convention,但我一直没能用它来理解下面的功能。我如何进一步追踪 SMC 指令以查看它根据其输入操作数实际执行的操作?
s32 scm_call_atomic4_3(u32 svc, u32 cmd, u32 arg1, u32 arg2,
u32 arg3, u32 arg4, u32 *ret1, u32 *ret2)
{
int ret;
int context_id;
register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 4);
register u32 r1 asm("r1") = (u32)&context_id;
register u32 r2 asm("r2") = arg1;
register u32 r3 asm("r3") = arg2;
register u32 r4 asm("r4") = arg3;
register u32 r5 asm("r5") = arg4;
asm volatile(
__asmeq("%0", "r0")
__asmeq("%1", "r1")
__asmeq("%2", "r2")
__asmeq("%3", "r0")
__asmeq("%4", "r1")
__asmeq("%5", "r2")
__asmeq("%6", "r3")
#ifdef REQUIRES_SEC
".arch_extension sec\n"
#endif
"smc #0 @ switch to secure world\n"
: "=r" (r0), "=r" (r1), "=r" (r2)
: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4), "r" (r5));
ret = r0;
if (ret1)
*ret1 = r1;
if (ret2)
*ret2 = r2;
return r0;
}
EXPORT_SYMBOL(scm_call_atomic4_3);
SMC calling conventions是ARM关于如何实现cross worldAPI的建议,让多个厂商可以在任意一个world编写代码,共同协作- 以最小的不兼容性存在。至少那是意图。供应商(Android/Linux 在您的情况下)不必执行此操作,如果安全世界不遵循它,则可能无法执行此操作。
but I haven't been able to use it to make sense of the following function
SMC
指令是从正常世界到安全监视器的受控更改。监视器有自己的向量 table,svc
的条目是 SMC 调用。寄存器是世界之间的 'shared' 信息。通常在世界切换上,监视器可能会将所有寄存器换出到某个上下文存储。在SMC
情况下,寄存器可以传递参数和return结果。这就是这个函数所做的全部。
register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 4);
这是liketableSMC调用约定文档中的位域table2-1。它是从正常世界 Linux 到安全监视器来告诉哪个函数(以及参数数量 marshal/keep 的四个)。
register u32 r2 asm("r2") = arg1;
register u32 r3 asm("r3") = arg2;
register u32 r4 asm("r4") = arg3;
register u32 r5 asm("r5") = arg4;
如果ARM ABI是偶然的,参数arg1-arg4已经在这些寄存器中,所以不会生成代码。全局 context_id
(到 Linux/Android 内核)也被传递。
How can I track down the SMC instruction further to see what it actually does based on its input operands?
为此,您需要安全世界的代码。我的猜测是,这是一些小区 phone 和基带等在安全世界中,代码不可用。如果您有安全世界代码,监控向量 table 将有一个 SMC
条目。这将有一个基于 r0
或 'cmd' 值的开关(或 if/then),它选择特定的 smc
函数。通用 smc
处理程序可以恢复安全世界 registers/context 但保留 r0
位字段中指定的四个参数。
所以答案可能是您无法追踪它的作用。您必须依赖供应商文档,或者幸运地拥有通往安全世界的代码。