当前位置: 首页 > news >正文

句容网站建设公司苏州园区已经烂掉了

句容网站建设公司,苏州园区已经烂掉了,网站推广策划案关键词,做特产网站本章介绍 ATF 中的 Runtime Service 是如何定义和被调用的。 要了解 SMC#xff0c;必须从 SMC 指令本身开始#xff0c;其指令如下图#xff1a; 指令格式为#xff1a;SMC #imm#xff0c;从官方文档了解到该指令只能在 EL1 以及更高的异常等级上调用#xff…本章介绍 ATF 中的 Runtime Service 是如何定义和被调用的。 要了解 SMC必须从 SMC 指令本身开始其指令如下图 指令格式为SMC #imm从官方文档了解到该指令只能在 EL1 以及更高的异常等级上调用用户空间 EL0 是无法直接调用该指令的。 同时根据 ARM 官方文档关于 SMCCC 的描述如下 可以知道 SMC 可以根据不同的 OENOwning Entity Number区分不同分服务的功能当注册具体了 SMC runtime service 时需要为对应的 service 指定正确的 OEN 范围。 这里比较抽象我们来举个例子就明白了比如我在 Hypervisor 中介绍的关于虚拟机管理器通过 SMC 系统调用去 ATF 通过 PSCI 协议拉起从核其中启动从核的 PSIC 的 function id 为PSCI_CPU_ON_AARCH640xc4000003不考虑后面跟的参数也就是最终调用了 smc #0xc4000003 按照其 32bit 划分 bit[31] 1Fast callbit[32] 0SMC64 call conventionbit[29 : 24] 4Standard service callbit[15 : 0] 3该类型的 call type 下的 function number 我们对 runtime service 进行了如下的定义和分类 ARM Architecture Calls获取 smcc 版本arch features 等CPU Service Calls提供针对该平台的 CPU 实现特定服务的接口SIP Service CallsSystem IP 的驱动OEM Service CallsOEM 服务的接口Standard Secure ServicePSCI call 就属于这个服务类型... ... Runtime Service 的注册 BL31 通过宏定义 DECLARE_RT_SVC 注册一个服务 比如 Standard Service 的注册 /* Register Standard Service Calls as runtime service */ DECLARE_RT_SVC(std_svc,OEN_STD_START,OEN_STD_END,SMC_TYPE_FAST,std_svc_setup,std_svc_smc_handler ); 比如 SIP Service 的注册 /* Define a runtime service descriptor for fast SMC calls */ DECLARE_RT_SVC(arm_sip_svc,OEN_SIP_START,OEN_SIP_END,SMC_TYPE_FAST,arm_sip_setup,arm_sip_handler ); 在注册处理 SMC 命令服务时DECLARE_RT_SVC 空定义定义了一个结构体__svc_desc_##_name并将其放到了 OS 镜像的一个特殊的段.rt_svc_descs 中其中__RT_SVC_DESCS_START__ 和__RT_SVC_DESCS_END__ 是该断的起始地址和结束地址并且可以通过地址范围计算出服务的数量 RT_SVC_DECS_NUM /** 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) \}#define RT_SVC_DESCS \. ALIGN(STRUCT_ALIGN); \__RT_SVC_DESCS_START__ .; \KEEP(*(.rt_svc_descs)) \__RT_SVC_DESCS_END__ .; Runtime Service 的启动 void __init runtime_svc_init(void) {int rc 0;uint8_t index, start_idx, end_idx;rt_svc_desc_t *rt_svc_descs;/* Assert the number of descriptors detected are less than maximum indices */assert((RT_SVC_DESCS_END RT_SVC_DESCS_START) (RT_SVC_DECS_NUM MAX_RT_SVCS));/* If no runtime services are implemented then simply bail out */if (RT_SVC_DECS_NUM 0U)return;/* Initialise internal variables to invalid state */(void)memset(rt_svc_descs_indices, -1, sizeof(rt_svc_descs_indices));rt_svc_descs (rt_svc_desc_t *) RT_SVC_DESCS_START;for (index 0U; index RT_SVC_DECS_NUM; index) {rt_svc_desc_t *service rt_svc_descs[index];/** An invalid descriptor is an error condition since it is* difficult to predict the system behaviour in the absence* of this service.*/rc validate_rt_svc_desc(service);if (rc ! 0) {ERROR(Invalid runtime service descriptor %p\n,(void *) service);panic();}/** The runtime service may have separate rt_svc_desc_t* for its fast smc and yielding smc. Since the service itself* need to be initialized only once, only one of them will have* an initialisation routine defined. Call the initialisation* routine for this runtime service, if it is defined.*/if (service-init ! NULL) {rc service-init();if (rc ! 0) {ERROR(Error initializing runtime service %s\n,service-name);continue;}}/** Fill the indices corresponding to the start and end* owning entity numbers with the index of the* descriptor which will handle the SMCs for this owning* entity range.*/start_idx (uint8_t)get_unique_oen(service-start_oen,service-call_type);end_idx (uint8_t)get_unique_oen(service-end_oen,service-call_type);assert(start_idx end_idx);assert(end_idx MAX_RT_SVCS);for (; start_idx end_idx; start_idx)rt_svc_descs_indices[start_idx] index;} } 先通过RT_SVC_DESCS_START 和RT_SVC_DESCS_END 之间的大小计算出当前的服务数量RT_SVC_DECS_NUM从RT_SVC_DESCS_START 位置开始遍历所有服务拿到其结构体地址service通过validate_rt_svc_desc 对该服务的参数进行校验通过 service-init 初始化该服务当然有些服务可能不需要 init setup初始化rt_svc_descs_indices 表 在 EL1/EL2 发起 SMC 调用时smc_fid 作为第一个参数传递给 ATFATF 需要根据 smc_fid 定位到是哪种 service。由于 service 有两种 type 组成每种 type 的 oen 最多有 64 个所以 type 和 oen 的组合会有 128 中可能。为了加快查找 service 类别ATF 在初始化 runtime service 时会维护一个表我们用如下两个服务作为例子 DECLARE_RT_SVC(arm_sip_svc,OEN_SIP_START, 2OEN_SIP_END, 2SMC_TYPE_FAST, 1arm_sip_setup,arm_sip_handler );start_idx SMC_TYPE_FAST 6 | OEN_SIP_START 66 end_idx SMC_TYPE_FAST 6 | OEN_SIP_END 66DECLARE_RT_SVC(tos_svc,OEN_TOS_START, 50OEN_TOS_END, 63SMC_TYPE_YIELD, 0tos_svc_setup,tos_svc_smc_handler );start_idx SMC_TYPE_YIELD 6 | OEN_TOS_START 50 end_idx SMC_TYPE_YIELD 6 | OEN_TOS_END 63 SMC 的处理流程 根据 bl31/aarch64/runtime_exceptions.S 中异常向量表 runtime_exceptions 的定义当 EL1/EL2 发起 SMC 调用后会触发sync_exception_aarch64并在最终的 smc_handler64 处理中跳转到相应的服务处理函数中 runtime_exceptions--sync_exception_aarch64--handle_sync_exception--sync_handler64 sync_handler64 中根据参数 1 中 smc_fid 的 type 和 oen 得到 desc_index由rt_svc_descs_indices[desc_index] 可以得到 svc_index再 由rt_svc_descs[svc_index] 就可以得到对应 runtime service 描述符的指针rt_svc_desc_t最后调用其 handler 处理函数 and x16, x0, #(FUNCID_SVE_HINT_MASK FUNCID_SVE_HINT_SHIFT)orr x7, x7, x16bic x0, x0, #(FUNCID_SVE_HINT_MASK FUNCID_SVE_HINT_SHIFT)/* Get the unique owning entity number */ubfx x16, x0, #FUNCID_OEN_SHIFT, #FUNCID_OEN_WIDTHubfx x15, x0, #FUNCID_TYPE_SHIFT, #FUNCID_TYPE_WIDTHorr x16, x16, x15, lsl #FUNCID_OEN_WIDTH/* Load descriptor index from array of indices */adrp x14, rt_svc_descs_indicesadd x14, x14, :lo12:rt_svc_descs_indicesldrb w15, [x14, x16]/* 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_l x11, (__RT_SVC_DESCS_START__ RT_SVC_DESC_HANDLE)lsl w10, w15, #RT_SVC_SIZE_LOG2ldr x15, [x11, w10, uxtw]/** 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 以 psci 为例由于 psci 属于 standard service所以会调用std_svc_smc_handler在std_svc_smc_handler 中再根据smc_fid 区分不同的细分服务然后调用psci_smc_handler 去处理 psci 协议 static uintptr_t std_svc_smc_handler(uint32_t smc_fid,u_register_t x1,u_register_t x2,u_register_t x3,u_register_t x4,void *cookie,void *handle,u_register_t flags) {if (((smc_fid FUNCID_CC_SHIFT) FUNCID_CC_MASK) SMC_32) {/* 32-bit SMC function, clear top parameter bits */x1 UINT32_MAX;x2 UINT32_MAX;x3 UINT32_MAX;x4 UINT32_MAX;}/** Dispatch PSCI calls to PSCI SMC handler and return its return* value*/if (is_psci_fid(smc_fid)) {uint64_t ret;ret psci_smc_handler(smc_fid, x1, x2, x3, x4,cookie, handle, flags);... }
http://www.w-s-a.com/news/78450/

相关文章:

  • 青岛房产网站东莞网络营销外包公司
  • 网站建设中的页数网上工伤做实网站
  • 给公司做网站这个工作怎么样wordpress不支持中文标签
  • 湖南网站推广优化cc域名做门户网站
  • 网站开发大概多久怎么制做网站
  • 鄂州官方网站食品网站建设需求分析
  • 福州网站建设金森要做好网络营销首先要
  • 中山哪里有好网站建设公司企业培训考试平台下载
  • 域名备案查询 网站备案查询企业网站建设问题研究
  • wordpress无法编辑北京优化网站方法
  • 公司建设一个网站最好的网站建设哪家好
  • 南京市住宅建设总公司网站wordpress 自己写的网页
  • 淄博网站制作企业高端长沙企业网站制作服务报价
  • 网站服务理念中外商贸网站建设
  • 如何自己建立网站中国建设银行网站忘记密码
  • 什么是a站如何在12366网站上做实名认证
  • 斗蟋蟀网站建设谭谭心怎么建设网站
  • 优秀网站开发商郑州网站建设套餐
  • 做伤残鉴约号网站购物网站建设新闻
  • 黄江网站建设公司自己房子做民宿挂什么网站
  • 手游网站做cpc还是cpm广告号宣武郑州阳网站建设
  • vs连接数据库做网站建立网站
  • 电商网站设计图片素材p2p网站建设石家庄
  • 莲塘网站建设如何文字推广一个婚恋网站
  • 医院网站建设工作汇报WordPress不发邮件了
  • 怎么做外语网站个人网页设计作品ps
  • 网站原型怎么做vps如何建两个网站
  • 商城网站建设源码嘉兴seo计费管理
  • 城乡建设网站证件查询系统wordpress 时间代码
  • php网站建设 关键技术做网站哪家正规