2017-10-18 1534 views
1

我一直在阅读Android的内核,以了解CPU内核(又名DVFS,DCVS)的动态电源管理是如何完成的。我找到的代码here可以调用以下函数(定义为here),该函数又调用SMC汇编指令。如何解读ARM的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); 
+0

类似[this](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0333h/Chdfjdgi.html)? –

+0

@DavidWohlferd链接解释了安全模型。我更感兴趣的是知道在进行SMC调用后运行的代码。 – Mahdi

+1

关键是SMC呼叫去安全的世界。这可以有一个完全不同的**物理**内存映射,并且存在安全世界中的软件如何运行的不同模型。它绝对不一定是(也可能不是)Linux。这通常是封闭的源代码软件,您可能可以访问二进制映像,甚至可能很难。您可能必须进行逆向工程或与创建安全世界软件的供应商交谈。 –

回答

1

SMC calling conventions是从ARM关于如何实现横世界 API的建议,从而使多个厂商可以写在任何世界和代码共存以最小的不兼容。至少这是意图。一个供应商(你的情况下的Android/Linux)不必这样做,如果安全的世界没有遵循它,可能无法做到这一点。

,但我一直没能利用它来进行以下功能

SMC指令的感觉是正常的世界变化控制到安全监控。显示器有它自己的矢量表,svc的条目是SMC呼叫。注册是世界之间的“共享”信息。通常在世界开关上,显示器可以将所有寄存器交换到某个上下文存储器。在SMC的情况下,寄存器可以传送参数并返回结果。这是所有这个功能正在做的。

register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 4); 

这是SMC位域表2-1调用约定文件。它是从正常的世界Linux到安全监视器来告诉哪个函数(以及编组/保持四个参数的数量)。

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内核)也通过。

如何进一步追踪SMC指令,根据其输入操作数来查看实际执行的操作?

要做到这一点,您需要安全世界的代码。我的猜测是,这是一些手机和基带,等在安全的世界,代码不可用。如果您拥有安全的世界代码,则监视器向量表将具有SMC条目。这将基于r0或“CMD”值(其选择特定的smc函数)具有开关(或者如果/然后)。通用的smc处理程序可以恢复安全的世界寄存器/上下文,但保留r0位字段中指定的四个参数。

所以可能的答案是你不能追查它做什么。你必须依赖供应商的文档,或者有足够的幸运来获得安全世界的代码。

+1

你也许幸运和[PSCI(http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf)文档可能适用。检出OpenSource [ARM可信固件](https://github.com/ARM-software/arm-trusted-firmware)。我没有看到MSM SOC,但它有可能在某些CPU上使用它(对于其他读取)。 –

+0

谢谢,我会研究它。假设这个实现是封闭源代码,你知道我应该在哪里可以找到这个源代码树中的二进制文件吗? https://android.googlesource.com/kernel/msm/+/android-5.1.0_r0.6/arch/arm/mach-msm – Mahdi

+1

它甚至不是在源代码树。它将在设备中编程(如BIOS芯片)。 –