1、std_svc_setup (主要关注设置psci操作集)--有服务
std_svc_setup //services/std_svc/std_svc_setup.c
- >psci_setup //lib/psci/psci_setup.c
- >plat_setup_psci_ops //设置平台的psci操作 调用平台的plat_setup_psci_ops函数去设置psci操作 eg:qemu平台
- >*psci_ops = &plat_qemu_psci_pm_ops;
208 static const plat_psci_ops_t plat_qemu_psci_pm_ops = {
209 .cpu_standby = qemu_cpu_standby,
210 .pwr_domain_on = qemu_pwr_domain_on,
211 .pwr_domain_off = qemu_pwr_domain_off,
212 .pwr_domain_suspend = qemu_pwr_domain_suspend,
213 .pwr_domain_on_finish = qemu_pwr_domain_on_finish,
214 .pwr_domain_suspend_finish = qemu_pwr_domain_suspend_finish,
215 .system_off = qemu_system_off,
216 .system_reset = qemu_system_reset,
217 .validate_power_state = qemu_validate_power_state,
218 .validate_ns_entrypoint = qemu_validate_ns_entrypoint
219 };
在遍历每一个注册的运行时服务的时候,会导致std_svc_setup调用,其中会做psci操作集的设置,操作集中我们可以看到对核电源的管理的接口如:核上电,下电,挂起等,我们主要关注上电 .pwr_domain_on = qemu_pwr_domain_on,这个接口当我们主处理器boot从处理器的时候会用到。
2、运行时服务触发和处理--来请求
smc指令触发进入el3异常向量表:
runtime_exceptions //el3的异常向量表
- >sync_exception_aarch64
- >handle_sync_exception
- >smc_handler64
- > ¦* 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 Hence save x5-x7.
¦*
¦* Note: x4 only needs to be preserved for AArch32 callers but we do it
¦* for AArch64 callers as well for convenience
¦*/
stp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] //保存x4-x7到栈
stp x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]
/* Save rest of the gpregs and sp_el0*/
save_x18_to_x29_sp_el0
mov x5, xzr //x5清零
mov x6, sp //sp保存在x6
/* Get the unique owning entity number */ //获得唯一的入口编号
ubfx x16, x0, #FUNCID_OEN_SHIFT, #FUNCID_OEN_WIDTH
ubfx x15, x0, #FUNCID_TYPE_SHIFT, #FUNCID_TYPE_WIDTH
orr x16, x16, x15, lsl #FUNCID_OEN_WIDTH
adr x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE)
/* Load descriptor index from array of indices */
adr x14, rt_svc_descs_indices //获得服务描述 标识数组
ldrb w15, [x14, x16] //根据唯一的入口编号 找到处理函数的 地址
/*
¦* 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]
/*
¦* Any index greater than 127 is invalid. Check bit 7 for
¦* a valid index
¦*/
tbnz w15, 7, smc_unknown
/* Switch to SP_EL0 */
msr spsel, #0
/*
¦* Get the descriptor using the index
¦* x11 = (base + off), x15 = index
¦*
¦* handler = (base + off) + (index < < log2(size))
¦*/
lsl w10, w15, #RT_SVC_SIZE_LOG2
ldr x15, [x11, w10, uxtw]
/*
¦* 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_el3 //spsr_el3保存在x16
mrs x17, elr_el3 //elr_el3保存在x17
mrs x18, scr_el3 //scr_el3保存在x18
stp x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] / x16, x17/保存在栈
str x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3] //x18保存到栈
/* Copy SCR_EL3.NS bit to the flag to indicate caller's security */
bfi x7, x18, #0, #1
mov sp, x12
/*
¦* 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 DEBUG
cbz x15, rt_svc_fw_critical_error
#endif
blr x15 //跳转到处理函数
b el3_exit //从el3退出 会eret 回到el1 (后面会讲到)
3、找到对应handler--请求匹配处理函数
上面其实主要的是找到服务例程,然后跳转执行 下面是跳转的处理函数:
std_svc_smc_handler //services/std_svc/std_svc_setup.c
- >ret = psci_smc_handler(smc_fid, x1, x2, x3, x4,
¦ cookie, handle, flags)
...
480 } else {
481 /* 64-bit PSCI function */
482
483 switch (smc_fid) {
484 case PSCI_CPU_SUSPEND_AARCH64:
485 ret = (u_register_t)
486 psci_cpu_suspend((unsigned int)x1, x2, x3);
487 break;
488
489 case PSCI_CPU_ON_AARCH64:
490 ret = (u_register_t)psci_cpu_on(x1, x2, x3);
491 break;
492
...
}
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
cpu
+关注
关注
68文章
10825浏览量
211146 -
服务器
+关注
关注
12文章
9021浏览量
85183 -
SMP
+关注
关注
0文章
71浏览量
19631 -
函数
+关注
关注
3文章
4305浏览量
62430
发布评论请先 登录
相关推荐
AliOS Things SMP系统及其在esp32上实现示例
对应CPU的SMP功能:2.1 核启动加载目前的启动顺序是,系统默认开始启动0核,在0核的主任务入口内启动其他核的加载,使其都进入任务调度,
发表于 05-15 12:45
ARM电源管理中的PSCI是什么意思呢
;PSCI_STAT_RESIDENCY:此API返回自冷启动后平台处于某个电源状态的时间;PSCI_STAT_COUNT:此API返回自冷启动后平台使用某个电源状态的次数;这些API
发表于 04-02 09:45
记录学习ARM Linux的多核启动过程
1.概述本文主要是记录学习Linux的多核启动的过程,对学习过程进行总结,以便进行后续回顾。平台:ARM Vexpress内核版本:linux-4.92.smp_operations初始化系统
发表于 05-25 10:43
ARM64 SMP多核启动相关资料推荐(下)
2、psci方式多核启动描述上面说了pin-table的多核启动方式,看似很繁琐,实际上并不复杂,无外乎主处理器唤醒从处理器到指定地址上去执
发表于 06-06 17:11
ARM64 SMP多核启动(上)—spin-table
一般嵌入式系统使用的都是对称多处理器(Symmetric Multi-Processor, SMP)系统,包含了多个cpu, 这几个cpu都是相同的处理器,如4核Contex-A53。
发表于 06-09 14:28
•961次阅读
ARM64 SMP多核启动(下)—PSCI
上面说了pin-table的多核启动方式,看似很繁琐,实际上并不复杂,无外乎主处理器唤醒从处理器到指定地址上去执行指令
发表于 06-09 14:31
•678次阅读
多核CPU的启动方式
工作中遇到的多核 ARM CPU 越来越多,总结分享一些多核启动的知识,希望能帮助更多小伙伴。 在 ARM64 架构下如果想要启动多核,有
SMP是什么?多核芯片(SMP)的启动方法
SMP 英文为Symmetric Multi-Processing ,是对称多处理结构的简称,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构,一个服务器系统可以同时运行多个处理器,并共享内存和其他的主机资源。
SMP是什么 启动方式介绍
,一个服务器系统可以同时运行多个处理器,并共享内存和其他的主机资源。 CMP 英文为Chip multiprocessors,指的是单芯片多处理器,也指多核心。其思想是将大规模并行处理器中的SMP集成到同一芯片内,各个处理器并行执行不同的进程。 (1)CPU数:独立的中央
SMP多核启动cpu操作函数
其中spin-table启动方式的回调如下: const struct cpu_operations smp_spin_table_ops = {.name= "spin-table
psci接口规范介绍
hotplug (3)secondary cpu启动 (4)系统的shutdown和reset psci接口规定了命令对应的function_id、接口的输入参数
SMP多核secondary cpu启动流程
secondary cpu启动 由于psci方式启动secondary cpu的流程,除了其所执行的cpu_ops不同之外,其它流程与spin-table方式是相同的,因此我们这里只给出执行流程图
PSCI处理函数代码分析
处理函数根据funid来决定服务,可以看到PSCI_CPU_ON_AARCH64为0xc4000003,这正是设备树中填写的cpu_on属性的id,会委托psci_cpu_on来执行核上电任务。下面
评论