【DeepSeek】SMC 调用约定
SMC 调用遵循ARM SMC Calling Convention (SMCCC)规范文档编号ARM DEN 0028。这是一套标准化的“握手协议”规定了非安全世界EL1/EL2如何向安全监控器EL3传递请求以及 EL3 如何返回结果。一、寄存器使用约定SMC 调用本质上是函数调用但通过寄存器传参。1. 输入参数寄存器名称说明x0Function ID核心标识。EL3 根据这个值决定执行哪个服务x1Arg1第 1 个参数x2Arg2第 2 个参数x3Arg3第 3 个参数………x7Arg7第 7 个参数2. 输出结果寄存器说明x0返回码表示执行状态成功、失败、不支持等x1返回值 1x2返回值 2x3返回值 3x4返回值 43. 重要限制最多传递 7 个参数x1-x7。最多返回 4 个输出值x1-x4。x5 - x17在 SMC 调用过程中被视为临时寄存器调用完成后其值未定义调用者必须自行保存/恢复。二、Function ID (x0) 的结构解析x0是 SMC 调用的灵魂EL3 的runtime_svc层会解析它来定位服务。x0是一个 32 位无符号整数其位域结构如下31(1 bit)30(1 bit)29:24(6 bits)23:16(8 bits)15:0(16 bits)1. 位 [31]调用类型0标准调用。通常用于 64 位调用者参数通过 x0-x7 传递。1快速调用。通常用于 32 位调用者参数通过 w0-w7 传递。2. 位 [30]调用指令类型0快速调用由SMC指令触发。1标准调用由HVC指令触发用于 Hypervisor 场景。注在 TF-A 实现中通常通过is_smc_fid()宏来区分。常见的 SMC FID 顶层十六进制为0x8...或0xC...。3. 位 [29:24]服务类型这是区分不同服务提供者的关键字段值类型说明0x00Arch架构服务如 PSCI0x01SiP硅片厂商服务0x02OEMOEM 厂商服务0x03Std标准安全服务0x04PSCI电源状态协调接口实际常用4. 位 [23:16]OENOEM 或 SiP 的具体编号用于进一步细分服务来源。5. 位 [15:0]功能编号具体的功能序号由服务提供者自定义。三、常见的 Function ID 示例以 TF-A 中最常用的PSCI服务为例Function ID (Hex)二进制关键位含义0x8400000010(Fast SMC)PSCI 版本查询0x8400000110(Fast SMC)CPU 关机0x8400000210(Fast SMC)CPU 开机0x8400000310(Fast SMC)CPU 挂起0xC400000011(Std SMC)PSCI 版本查询 (64-bit)解析0x84000001(PSCI_CPU_OFF)0x841000 0100(二进制)Bit 31 1(Fast Call)Bit 30 0(SMC)Bit 29:24 0001004(PSCI 类型)Bit 15:0 1(功能号 1即 CPU_OFF)四、标准返回码SMC 调用返回后x0保存执行状态。SMCCC 定义了以下标准返回码返回码 (Hex)名称说明0x00000000SUCCESS执行成功0xFFFFFFFENOT_SUPPORTED功能不支持0xFFFFFFFDINVALID_PARAMS参数无效0xFFFFFFFCDENIED权限拒绝0xFFFFFFFBNOT_PRESENT服务不存在0xFFFFFFF1ON_PENDINGCPU 开机操作挂起中五、代码示例1. 汇编层面发起 SMC// 示例调用 PSCI CPU_OFF (0x84000001) // 输入无参数 // 输出x0 返回码 smc_cpu_off: mov x0, #0x84000001 // 设置 Function ID smc #0 // 触发 SMC 异常 ret // 返回调用者 (x0 包含结果)2. C 语言层面发起 SMC在 Linux 内核或 U-Boot 中通常使用arm_smccc_smc宏/函数#includelinux/arm-smccc.h// 定义输入参数结构体structarm_smccc_resres;// 发起 SMC 调用// 参数1: Function ID// 参数2-7: 具体参数arm_smccc_smc(0x84000001,0,0,0,0,0,0,0,res);// 检查结果if(res.a00){pr_info(CPU off success\n);}else{pr_err(CPU off failed: %lx\n,res.a0);}六、总结图示EL3 (BL31)EL1/EL2 (调用者)EL3 (BL31)EL1/EL2 (调用者)准备参数 x0FuncID, x1-x7Args1. 读取 x02. 解析服务类型3. 查表找到 Handler设置返回 x0RetCode, x1-x4Out检查 x0 判断结果SMC执行服务逻辑ERET核心规则x0 是身份证EL3 靠它识别你要干什么。x1-x7 是快递包里面装着具体的参数。x0-x4 是回执单EL3 告诉你结果如何。遵守 SMCCC这是 ARM 生态Linux、TF-A、OP-TEE互通的基础。