2017-10-18 1538 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芯片)。 –