处理函数根据funid来决定服务,可以看到PSCI_CPU_ON_AARCH64为0xc4000003,这正是设备树中填写的cpu_on属性的id,会委托psci_cpu_on来执行核上电任务。下面分析是重点:!!!
- >psci_cpu_on() //lib/psci/psci_main.c
- >psci_validate_entry_point() //验证入口地址有效性并 保存入口点到一个结构ep中
- >psci_cpu_on_start(target_cpu, &ep) //ep入口地址
- >psci_plat_pm_ops- >pwr_domain_on(target_cpu)
- >qemu_pwr_domain_on //实现核上电(平台实现)
/* Store the re-entry information for the non-secure world. */
- >cm_init_context_by_index() //重点:会通过cpu的编号找到 cpu上下文(cpu_context_t),存在cpu寄存器的值,异常返回的时候写写到对应的寄存器中,然后eret,旧返回到了el1!!!
- >cm_setup_context() //设置cpu上下文
- > write_ctx_reg(state, CTX_SCR_EL3, scr_el3); //lib/el3_runtime/aarch64/context_mgmt.c
write_ctx_reg(state, CTX_ELR_EL3, ep- >pc); //注:异常返回时执行此地址 于是完成了cpu的启动!!!
write_ctx_reg(state, CTX_SPSR_EL3, ep- >spsr);
psci_cpu_on主要完成开核的工作 ,然后会设置一些异常返回后寄存器的值(eg:从el1 -> el3 -> el1),重点关注 ep->pc写到cpu_context结构的CTX_ELR_EL3偏移处(从处理器启动后会从这个地址取指执行)。
实际上, 所有的从处理器启动后都会从bl31_warm_entrypoint开始执行 ,在plat_setup_psci_ops中会设置(每个平台都有自己的启动地址寄存器,通过写这个寄存器来获得上电后执行的指令地址)。
大致说一下:主处理器通过smc进入el3请求开核服务,atf中会响应这种请求, 通过平台的开核操作来启动从处理器并且设置从处理的一些寄存器eg:scr_el3、spsr_el3、elr_el3,然后主处理器,恢复现场,eret再次回到el1 ,
而处理器开核之后会从bl31_warm_entrypoint开始执行,最后通过el3_exit返回到el1的elr_el3设置的地址。
分析到这atf的分析到此为止,atf中主要是响应内核的snc的请求,然后做开核处理,也就是实际的开核动作,但是从处理器最后还是要回到内核中执行
全部0条评论
快来发表一下你的评论吧 !