[ATF]-ATF的RT_SVC的详解(runtime service)
文章目录
- 1、RT_SVC的分类
- 2、RT_SVC的注册
- 3、rt_svc定义的原理和rt_svc的请求实现
★★★ 链接 : 个人博客导读首页—点击此处 ★★★
1、RT_SVC的分类
在SCC文档中对rt_svc进行了定义和分类,具体形式如下:
- ARM Architecture Calls
- CPU Service Calls
- SiP Service Calls
- OEM Service Calls
- Standard Secure Service Calls
- Standard Hypervisor Service Calls
- Vendor Specific Hypervisor Service Calls
- Trusted Application Calls
- Trusted OS Calls
目前我们在ATF中常用的主要是Trusted OS Calls,如果是在MTK平台上SiP Service Calls也常使用的.
2、RT_SVC的注册
在ATF中有多种类型的rt_svc, 不同的rt_svc为不同的场景服务. 我们下面举三个例子详细说明:
(1)、Trusted OS Calls
我们以optee os为例,在ATF中注册一个rt_svc,为linux和optee_os交互服务.
例如在opteed_main.c中,定义了一个service,该servic call ranges是OEN_TOS_START–OEN_TOS_END,正好落在50-63之间, 对应的就是Trusted OS Calls
DECLARE_RT_SVC(opteed_fast,OEN_TOS_START,OEN_TOS_END,SMC_TYPE_FAST,opteed_setup,opteed_smc_handler
);
那么我们在linux kernel程序中,想和optee os通信,需要通过ATF中的这类rt_svc才行,所以呢我们在linux kernel中构造的smc cmdid的bit29:24需为50–63之间,才能调起ATF中的该服务。 同样,在optee发起返回linux kernel的smc call的smcid也需在50–63之间
(2)、ARM Architecture Calls
例如在arm_arch_svc_setup.c中,定义了一个service,它的call类型是OEN_ARM_START–OEN_ARM_END,落在0-0之间,对应的恰好是ARM Architecture Calls
/* Register Standard Service Calls as runtime service */
DECLARE_RT_SVC(arm_arch_svc,OEN_ARM_START,OEN_ARM_END,SMC_TYPE_FAST,NULL,arm_arch_svc_smc_handler
);
那么我们在linux kernel中,调用smc时的smc id的bit29:24需要等于0,此次的smc调用才会调用到这个runtime service的handler程序
(3)、SiP Service Calls
例如在mtk_sip_svc.c中,定义了一个service,它的call类型是OEN_SIP_START–OEN_SIP_END,落在2-2之间,对应的恰好是SiP Service Calls
/* Define a runtime service descriptor for fast SMC calls */
DECLARE_RT_SVC(mediatek_sip_svc,OEN_SIP_START,OEN_SIP_END,SMC_TYPE_FAST,NULL,sip_smc_handler
);
那么我们在linux kernel中,调用smc时的smc id的bit29:24需要等于2,那么此次的smc调用才会调用到这个runtime service的handler程序
3、rt_svc定义的原理和rt_svc的请求实现
**(1)、定义实现 **
在runtime_svc.h中,DECLARE_RT_SVC宏其实就是在section(“rt_svc_descs”)段中定义了一个全局变量.
/** Convenience macros to declare a service descriptor*/
#define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch) \static const rt_svc_desc_t __svc_desc_ ## _name \__section("rt_svc_descs") __used = { \.start_oen = (_start), \.end_oen = (_end), \.call_type = (_type), \.name = #_name, \.init = (_setup), \.handle = (_smch) \}
section “rt_svc_descs”在RT_SVC_DESCS宏中
#define RT_SVC_DESCS \. = ALIGN(STRUCT_ALIGN); \__RT_SVC_DESCS_START__ = .; \KEEP(*(rt_svc_descs)) \__RT_SVC_DESCS_END__ = .;
而在rodata_common的宏中,定义了RT_SVC_DESCS
#define RODATA_COMMON \RT_SVC_DESCS \FCONF_POPULATOR \PMF_SVC_DESCS \PARSER_LIB_DESCS \CPU_OPS \GOT \BASE_XLAT_TABLE_RO
在bl31.ld.S中,将RODATA_COMMON放入了rodata段
.rodata . : {__RODATA_START__ = .;*(SORT_BY_ALIGNMENT(.rodata*))RODATA_COMMON/* Place pubsub sections for events */. = ALIGN(8);
#include <lib/el3_runtime/pubsub_events.h>. = ALIGN(PAGE_SIZE);__RODATA_END__ = .;} >RAM
(2)、请求RT_SVC
在linux/optee中调用smc call后,触发同步异常,进入smc_handler64程序,然后跳转到对应的rt_svc
完整代码和注释如下
smc_handler64:/* NOTE: The code below must preserve x0-x4 *//** Save general purpose and ARMv8.3-PAuth registers (if enabled).* If Secure Cycle Counter is not disabled in MDCR_EL3 when* ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter.*/bl save_gp_pmcr_pauth_regs#if ENABLE_PAUTH/* Load and program APIAKey firmware key */bl pauth_load_bl31_apiakey
#endif/** Populate the parameters for the SMC handler.* We already have x0-x4 in place. x5 will point to a cookie (not used* now). x6 will point to the context structure (SP_EL3) and x7 will* contain flags we need to pass to the handler.*/mov x5, xzrmov x6, sp/** Restore the saved C runtime stack value which will become the new* SP_EL0 i.e. EL3 runtime stack. It was saved in the 'cpu_context'* structure prior to the last ERET from EL3.*/ldr x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]/* Switch to SP_EL0 */msr spsel, #MODE_SP_EL0/** Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there is a world* switch during SMC handling.* TODO: Revisit if all system registers can be saved later.*/mrs x16, spsr_el3mrs x17, elr_el3mrs x18, scr_el3stp x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]str x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]/* Copy SCR_EL3.NS bit to the flag to indicate caller's security */bfi x7, x18, #0, #1mov sp, x12/* Get the unique owning entity number */ubfx x16, x0, #FUNCID_OEN_SHIFT, #FUNCID_OEN_WIDTH ---------------- 获取FUNCID_OEN_SHIFT,对应第一节中的OEN_TOS_STARTubfx x15, x0, #FUNCID_TYPE_SHIFT, #FUNCID_TYPE_WIDTH ---------------- 获取FUNCID_TYPE_SHIFT,对应第一节中的SMC_TYPE_FAST(fast还是yield,yield其实就是standard)orr x16, x16, x15, lsl #FUNCID_OEN_WIDTH/* Load descriptor index from array of indices */adrp x14, rt_svc_descs_indices ----在runtime_svc_init()中会将所有的section rt_svc_descs段放入rt_svc_descs_indices数组,这里获取该数组地址add x14, x14, :lo12:rt_svc_descs_indicesldrb w15, [x14, x16] ---找到rt_svc在rt_svc_descs_indices数组中的index/* Any index greater than 127 is invalid. Check bit 7. */tbnz w15, 7, smc_unknown/** Get the descriptor using the index* x11 = (base + off), w15 = index -------------------------重要的注释** handler = (base + off) + (index << log2(size)) ------ 这句注释特别重要,整段汇编看不懂没关系,这句注释看懂就行*/adr x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)lsl w10, w15, #RT_SVC_SIZE_LOG2ldr x15, [x11, w10, uxtw] ------------------------------这句话对应的就是上述注释:handler = (base + off) + (index << log2(size))/** Call the Secure Monitor Call handler and then drop directly into* el3_exit() which will program any remaining architectural state* prior to issuing the ERET to the desired lower EL.*/
#if DEBUGcbz x15, rt_svc_fw_critical_error
#endifblr x15 -------------------------------------跳转到handlerb el3_exit
[ATF]-ATF的RT_SVC的详解(runtime service)相关推荐
- 43. Systemd的Unit配置详解,unit文件位置,优先级,unit类型,unit文件字段详解,Unit/Service/Install字段,添加mysql服务等例子
Systemd的Unit配置详解,unit文件位置和优先级,unit文件类型,unit文件字段详解,[Unit]字段,[Service]字段,[Install]字段,添加服务,创建.service 文 ...
- iOS模式详解runtime面试工作
简书:http://www.jianshu.com/p/19f280afcb24 对于从事 iOS 开发人员来说,所有的人都会答出「runtime 是运行时」,什么情况下用runtime?,大部分人能 ...
- 学习笔记之-Kubernetes(K8S)介绍,集群环境搭建,Pod详解,Pod控制器详解,Service详解,数据存储,安全认证,DashBoard
笔记来源于观看黑马程序员Kubernetes(K8S)教程 第一章 kubernetes介绍 应用部署方式演变 在部署应用程序的方式上,主要经历了三个时代: 传统部署:互联网早期,会直接将应用程序部署 ...
- 十一:外观模式详解(Service,action与dao)
定义:外观模式是软件工程中常用的一种软件设计模式.它为子系统中的一组接口提供一个统一的高层接口.这一接口使得子系统更加容易使用. 该定义引自百度百科,它的表现很简单,将一系列子接口的功能进行整理,从而 ...
- k8s、Deployment多副本资源详解、SERVICE通信、案例一nginx端口暴漏、案例二tomcat端口暴漏、案例三jenkins端口暴漏
文章目录 案例一 创建SERVICE 案例一nginx端口暴露 案例二tomcat端口暴露 案例三jenkins端口暴漏 使用yaml创建Deployment k8s deployment资源创建流程 ...
- 以新增用户为例子解释前后端整体连接方式详解(Service、Mapper、Controller、Entity)
目录 编辑 前端 1.点击新增用户按钮执行 handleAdd() 方法 2.添加用户表单校验:(这里明显是简介版本,还有很大的优化空间) 3.点击表单里的确 定按钮通过 submitForm() ...
- android demo示例代码,Android Service demo例子使用详解(示例代码)
Android Service demo例子使用详解\ 概述 Service 是 Android 的四大组件之一,它主要的作用是后台执行操作,Activity 属于带有 UI 界面跟用户进行交互,而 ...
- [ATF]-smc指令详解
文章目录 1.在linux中发起smc的调用 2.陷入ATF的smc同步异常后,调用handler和exit_el3返回linux 3.fast call和std call的定义 4.fast cal ...
- ATF中smc指令详解
1 ATF的smc指令调用流程 在REE侧调用smc异常之后,会根据中断向量表触发cpu的同步异常sync_exception_aarch64/32,然后跳转执行到handle_sync_except ...
最新文章
- INNODB在裸设备上的性能简单测试
- python模拟sed在每行添加##
- 计算机一级考试有三科,全国计算机一级考试是一级WPS Office 一级MS Office 一级Photoshop 三个任选一个考试吗?...
- mysql 客户端 csv_使用mysql客户端程序远程导出csv文件
- java扶贫,基于jsp的扶贫网站-JavaEE实现扶贫网站 - java项目源码
- Gstreamer之No package ‘gstreamer-1.0‘ found解决(十一)
- Angular使用echarts
- p系列服务器产品介绍,常用p系列服务器RS6000服务器产品号码对照表.doc
- 共轴双桨直升机飞行原理介绍
- python偏最小二乘法公式,python3 偏最小二乘法实现
- python mysqldb insert_Python MySQLdb 插入数据
- 点云检测--欧式聚类Euclidean Cluster
- C4D和Maya哪个学起来更容易
- 梅科尔工作室-孙溢博-鸿蒙笔记1
- 下载软件创建桌面图标
- linux sed替换文件,linux的sed命令替换文件
- 堪称教科书级别的Android音视频入门进阶学习手册,开源分享
- Android~快捷方式兼容适配
- Git: checkout的用法总结(1)
- [STM32F103C8T6] 超声波测距
热门文章
- 2018年数据中心行业三大发展趋势
- python处理文本格式_python linecache 处理固定格式文本数据的方法
- 手机怎么打开f12_手机App调试(Android)
- Python之ffmpeg-python:ffmpeg-python库的简介、安装、使用方法之详细攻略
- 成功解决解决VM软件安装Linux的Ubuntu过程,打开时 Operating System not found
- TF之Windows:Windows系统下设置Tensorflow运行方式为GPU加速运行的详细攻略
- DL:LinearNN(numpy自定义的) solve XOR problem
- Python ML环境搭建与学习资料推荐
- 新项目新工作空间新仓库新setting文件
- Springboot 连接数据库