secondary cpu初始化状态设置

描述

spin-table

spin-table启动流程的示意图如下:

SMP

芯片上电后primary cpu开始执行启动流程,而secondary cpu则将自身设置为WFE睡眠状态,并且为内核准备了一块内存,用于填写secondary cpu的入口地址。

uboot负责将这块内存的地址写入devicetree中,当内核初始化完成,需要启动secondary cpu时,就将其内核入口地址写到那块内存中,然后唤醒cpu。

secondary cpu被唤醒后,检查该内存的内容,确认内核已经向其写入了启动地址,就跳转到该地址执行启动流程。

secondary cpu初始化状态设置

uboot启动时,secondary cpu会通过以下流程进入wfe状态(arch/arm/cpu/armv8/start.S):

#if defined(CONFIG_ARMV8_SPIN_TABLE) && !defined(CONFIG_SPL_BUILD)
	branch_if_master x0, x1, master_cpu1b	spin_table_secondary_jump2)
	…
master_cpu:                                                  (3bl	_main

(1)若当前cpu为primary cpu,则跳转到step 3,继续执行启动流程。其中cpu id是通过mpidr区分的,而启动流程中哪个cpu作为primary cpu可以任意指定。当指定完成后,此处就可以根据其身份确定相应的执行流程

(2)若当前cpu为slave cpu,则执行spin流程。它是由spin_table_secondary_jump函数实现的(arch/arm/cpu/armv8/start.S)。以下为其代码实现:

ENTRY(spin_table_secondary_jump)
.globl spin_table_reserve_begin
spin_table_reserve_begin:
0:	wfe                                           (1)
	ldr	x0, spin_table_cpu_release_addr       (2)
	cbz	x0, 0b                                (3)
	br	x0                                    (4)
.globl spin_table_cpu_release_addr                    (5)
	.align	3
spin_table_cpu_release_addr:
	.quad	0
.globl spin_table_reserve_end
spin_table_reserve_end:
ENDPROC(spin_table_secondary_jump)

(1)secondary cpu当前没有事情要做,因此执行wfe指令进入睡眠模式,以降低功耗

(2)spin_table_cpu_release_addr将由uboot传递给内核,根据step 5的定义可知,其长度为8个字节,在64位系统中正好可以保存一个指针。而它的内容在启动时会被初始化为0,当内核初始化完成后,在启动secondary cpu之前,会在uboot中将其入口地址写到该位置,并唤醒它

(3)当secondary cpu从wfe状态唤醒后,会校验内核是否在spin_table_cpu_release_addr处填写了它的启动入口。若未填写,则其会继续进入wfe状态

(4)若内核填入了启动地址,则其直接跳转到该地址开始执行内核初始化流程

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分