SOC的多核启动流程和概念详解

思考:
1、 soc一上电,只有一个核启动,还是所有核都启动?
2、如果soc一上电,如果只有一个核启动,那么从核启动的时候,从核的入口是哪里?
3、啥是cold boot?啥时warm boot? 在哪些场景下会使用warm boot?
4、啥是cold reset/warm reset/primary boot/senondary boot?
说明:
1、本文以为armv8-aarch64、armv9为例、tf-a代码为例,不讨论其它硬件架构和固件软件中的设计。
2、重点讲述cold reset/warm reset/primary boot/senondary boot之间的流程和概念。
1、基础概念
请先自行理解以下4个概念:
cold boot
warm boot
primary boot
secondary boot
另外还两种配置:
你的reset地址是可编程的,则会配置 programmable_reset_address=1,与之对立的则是你的reset地址是不可编程的。
你在soc启动的时候,首先只启动一个core,则会配置 cold_boot_single_cpu=1,与之对立的则是你的soc启动的时候,所有core都上电了。
2、启动流程
我们就假定 reset地址是可编程的、soc启动的时候只启动一个core,来讲解我们的boot流程:
(1)、soc一上电,soc给arm core的signal configuration会改变rvbarel3,这里一般就是就是bootrom的首地址。即cpu一上电,primary core的pc指向的就是rvbarel3的地址,机器就开始启动了。
(2)、当需要secondary core启动的时候,例如会走psci协议,【主核】进入atf会将bl31warmentrypoint(或平台自定义的地址)写入到soc寄存器,改变reset地址(改变rvbarel3的值),然后此时soc的pmic给secondary core上电,此时secondary core也就发生了cold reset,pc从rvbarel3(bl31warmentrypoint或平台自定义函数)处开始执行.
总结(针对本文示例情况:reset地址是可编程的、cold boot的时候只启动一个cpu):
开机一上电只有primary core再跑,从rvbar_el3处开始跑,属于cold boot
从核启动时,会修改reset的值,影响到rvbar_el3的值,然后给从核上电,此时属于secondary boot,仍然是cold boot.
一般会将bl31warmentrypoint设置为reset地址,即secondary core的启动地址;
这个示例中没有用到warm boot
3、atf(tf-a)代码的剖析
以bl1代码为例分析,该代码适配支持cold reset/warm reset/primary boot/senondary boot等诸多场景。
如果reset是可编程的, programmable_reset_address=1, 则 _warm_boot_mailbox=0,则下面这段代码不会被编译,无论cold boot还是warm boot都不会走 _warm_boot_mailbox。
如果reset是不可编程的, programmable_reset_address=0, 则 _warm_boot_mailbox=1,则下面这段代码会被编译,但cold boot走 do_cold_boot流程,warm boot需要走 br x0流程
.if \_warm_boot_mailbox
/* -------------------------------------------------------------
* this code will be executed for both warm and cold resets.
* now is the time to distinguish between the two.
* query the platform entrypoint address and if it is not zero
* then it means it is a warm boot so jump to this address.
* -------------------------------------------------------------
*/
bl plat_get_my_entrypoint
cbz x0, do_cold_boot
br x0
do_cold_boot:
.endif /* _warm_boot_mailbox */
如果soc启动的时候只启动一个core, cold_boot_single_cpu=1, _secondary_cold_boot=0,则下面代码不被编译, 则无论主核还是从核都不需要走 _secondary_cold_boot流程
如果soc启动的时候启动多个core, cold_boot_single_cpu=0, _secondary_cold_boot=1, 则下面代码会被编译,则主核走 do_primary_cold_boot流程, 从核需要走 plat_secondary_cold_boot_setup流程
.if \_secondary_cold_boot
/* -------------------------------------------------------------
* check if this is a primary or secondary cpu cold boot.
* the primary cpu will set up the platform while the
* secondaries are placed in a platform-specific state until the
* primary cpu performs the necessary actions to bring them out
* of that state and allows entry into the os.
* -------------------------------------------------------------
*/
bl plat_is_my_cpu_primary
cbnz w0, do_primary_cold_boot
/* this is a cold boot on a secondary cpu */
bl plat_secondary_cold_boot_setup
/* plat_secondary_cold_boot_setup() is not supposed to return */
bl el3_panic
do_primary_cold_boot:
根据以上的代码规则,这里也画了两张图:(1)、bl2 at el3的场景
(2)、bl2 at s-el1的场景
5、软件如何判断当前是cold reset/warm reset/primary boot/senondary boot
tf-a中定义了多核的启动框架,如上一节框图所示,在启动的过程中会进行一些判断,是cold reset还是warm reset,是primary boot还是secondary boot?那么代码中是怎么知道这些状态的呢?
5.1 cold reset和warm reset
这种判断方法由平台实现,其实就是读取mailbox的值。在第一个核cold boot时,会写mailbox内存(magic,entrypoint...)在第二个核启动时、或第一个核再次启动时(有可能是resume唤醒时),会读取mailbox内存,如果读取到了符合期望的magic的值,则走warm流程,否则走cold流程。注意这里所说的warm流程,只是软件上的warm流程,并非说当前是warm reset。
5.2 primary boot和secondary boot
这种判断方法由平台实现,看似也很简单,一般而言就说读取mpidr寄存器进行判断。
(trusted-firmware-a/plat/marvell/armada/a8k/common/aarch64/plat_helpers.s)
func plat_is_my_cpu_primary
mrs x0, mpidr_el1
and x0, x0, #(mpidr_cluster_mask | mpidr_cpu_mask)
cmp x0, #mvebu_primary_cpu
cset w0, eq
ret
endfunc plat_is_my_cpu_primary
6、mailbox的介绍
6.1 mailbox是什么
mailbox就说一块内存,所有的core都能访问这块内存。第一次启动时,core会填充mailbox,将其下次resume时的地址、secondary core的启动地址、warm reset的地址写入到mailbox内存中,这几个地址其实是一个地址。同时也会将这个地址写入到soc pmic寄存器中,影响到rvbar_el3的值。
当soc一上电所有core都启动的这种情况下,主核会继续跑,从核会在soc一上电就进入wfi状态。当从核需要继续启动时,该core从bl1 bl2 bl31正常流程启动时,会在bl1、bl2 at el3、bl31中,强制跳转到mailbox的地址,跳过主核已经初始化的部分;
当soc一上电,只有一个core上电的情况下,主核继续跑,从核未上电。当从核需要启动时,相当于cold reset,从核会直接从rvbar_el3处开始跑,也就是你设置的entrypoint。
6.2 mailbox的作用
mailbox中定义了entrypoint地址,当core从bl1 bl2 bl31正常流程启动时,会在bl1、bl2 at el3、bl31中,强制跳转到mailbox的地址,以跳过已初始化的部分。
6.3 mailbox的示例
其实就是定义了一块内存,主核第一次跑时,会填充该内存。主核第二次跑时或从和跑时,检测该内存已经填充过了,则走warm启动流程,即强制跳转到mailbox中的address地址。
7、具体场景的总结
串口中断中敲击reboot命令、或系统panic时导致的机器重启 :在一些的soc厂商设计中,应该是code reboot。比如在linux kernel中敲击reboot,到底层还是写的一些寄存器控制pmic(或pmu),直接给cpu下电了。然后再上电,soc还是会给core发送signal configuration,此时rvbar_el3又会变成asic设置的值.
suspend和resume :比如我在看atf中的海思平台,在atf的suspend函数,将bl31_warm_entrypoint地址写入到了soc pmic的一个寄存器中(上电时,该寄存器会影响的是rvbaraddr信号)。此时系统深睡的时候,应该是linux kernel调用到atf,将bl31_warm_entrypoint地址写入到了pmu/pmic相关的寄存器中,在下一次reset时,会影响到signal configuration继而改变rvbar_el3的值。然后还会给各个模块下电(给哪些模块下电是soc的设计和逻辑),最后再给arm core下电, 这就算是深睡了。resume的时候,也是有一些soc的硬件行为,然后再给core上电,那给core上电后,一上电执行的是哪里?pc还是指向rvbar_el3中的地址,当然这是我们suspend的时候更改过的,其实就是bl31_warm_entrypoint
rmr_el3 :本文中都没有提到rmr_el3。那么rmr_el3是干啥的呢?这是arm的一个feature,怎么用?是你自己的设计,随便你。你写rmr_el3中的bit,就可以触发warm reset. 一般的kernel dump、或者一些工具,就可以主动触发rmrel3,然后去干一些活. 还有在csdn上看到一篇高通soc的启动流程的博客,他们正常的启动流程中,某一个镜像跳转到另外一个镜像时,竟然就是写了一些rmr_el3,触发warm_reset,另外一个镜像的地址恰好就是warm reset的跳转地址。


帮助监测森林火灾无线传感器网络设计
技术分析:开关电源用新型零功耗AC/DC转换器
示波器的探头模型及负载效应
中国乘用车企业将迎来第一轮新能源积分交易
CPU导热硅胶片需要具备以下几个特性
SOC的多核启动流程和概念详解
PCB组装厂精成科将与日本ELNA公司合作
OPPOR11跑分逼近12万, 骁龙660让骁龙820都汗颜!
单片机采用高电平和低电平的复位说明
纯电动汽车和氢能源汽车谁会成为未来市场的主流
SPMC65P2408A在空调中的应用
BrainChip与MYWAI建立合作,助力边缘人工智能解决方案
IC设计:CMOS器件及其电路
伺服电机为什么我们要坚持做
人工智能在不同领域中的作用
雷神Dino-X6评测 创新十足略有瑕疵
自动驾驶三大传感器主要优劣介绍
Vega游戏显卡性能怎么样?AMD RX Vega游戏显卡对比GTX1080Ti跑分曝光
计算机算力和算法助力新基建
DC/DC稳压器ARG81800的技术优势及关键特性