spin-table
spin-table启动流程的示意图如下:
芯片上电后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_cpu (1)
b spin_table_secondary_jump (2)
…
master_cpu: (3)
bl _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)若内核填入了启动地址,则其直接跳转到该地址开始执行内核初始化流程
-
芯片
+关注
关注
455文章
50812浏览量
423546 -
cpu
+关注
关注
68文章
10863浏览量
211740 -
SMP
+关注
关注
0文章
74浏览量
19662
发布评论请先 登录
相关推荐
评论