0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

SMP多核启动PSCI代码示例

麦辣鸡腿堡 来源:TrustZone 作者:Hcoco 2023-12-05 17:45 次阅读

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
    cpu
    +关注

    关注

    68

    文章

    10825

    浏览量

    211146
  • 服务器
    +关注

    关注

    12

    文章

    9021

    浏览量

    85183
  • SMP
    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架构下启动多核的两种方式

    psci 两种方式,下面针对这两种启动流程进行分析。代码版本boot-wrapper-aarch64 version
    发表于 06-13 18:23

    ARM64 SMP多核启动(上)—spin-table

    一般嵌入式系统使用的都是对称多处理器(Symmetric Multi-Processor, SMP)系统,包含了多个cpu, 这几个cpu都是相同的处理器,如4核Contex-A53。
    发表于 06-09 14:28 961次阅读
    ARM64 <b class='flag-5'>SMP</b><b class='flag-5'>多核</b><b class='flag-5'>启动</b>(上)—spin-table

    ARM64 SMP多核启动(下)—PSCI

    上面说了pin-table的多核启动方式,看似很繁琐,实际上并不复杂,无外乎主处理器唤醒从处理器到指定地址上去执行指令
    发表于 06-09 14:31 678次阅读
    ARM64 <b class='flag-5'>SMP</b><b class='flag-5'>多核</b><b class='flag-5'>启动</b>(下)—<b class='flag-5'>PSCI</b>

    多核CPU的启动方式

    工作中遇到的多核 ARM CPU 越来越多,总结分享一些多核启动的知识,希望能帮助更多小伙伴。 在 ARM64 架构下如果想要启动多核,有
    的头像 发表于 06-22 10:04 2086次阅读

    SMP是什么?多核芯片(SMP)的启动方法

    SMP 英文为Symmetric Multi-Processing ,是对称多处理结构的简称,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构,一个服务器系统可以同时运行多个处理器,并共享内存和其他的主机资源。
    的头像 发表于 07-26 09:26 1.8w次阅读
    <b class='flag-5'>SMP</b>是什么?<b class='flag-5'>多核</b>芯片(<b class='flag-5'>SMP</b>)的<b class='flag-5'>启动</b>方法

    SMP是什么 启动方式介绍

    ,一个服务器系统可以同时运行多个处理器,并共享内存和其他的主机资源。 CMP 英文为Chip multiprocessors,指的是单芯片多处理器,也指多核心。其思想是将大规模并行处理器中的SMP集成到同一芯片内,各个处理器并行执行不同的进程。 (1)CPU数:独立的中央
    的头像 发表于 12-05 15:23 1742次阅读

    SMP多核启动cpu操作函数

    其中spin-table启动方式的回调如下: const struct cpu_operations smp_spin_table_ops = {.name= "spin-table
    的头像 发表于 12-05 16:04 708次阅读
    <b class='flag-5'>SMP</b><b class='flag-5'>多核</b><b class='flag-5'>启动</b>cpu操作函数

    psci接口规范介绍

    hotplug (3)secondary cpu启动 (4)系统的shutdown和reset psci接口规定了命令对应的function_id、接口的输入参数
    的头像 发表于 12-05 16:53 856次阅读

    内核中的psci驱动是什么

    内核中的psci架构 内核psci软件架构包含psci驱动和每个cpu的cpu_ops回调函数实现两部分。 其中psci驱动实现了驱动初始化和psc
    的头像 发表于 12-05 16:58 661次阅读
    内核中的<b class='flag-5'>psci</b>驱动是什么

    SMP多核secondary cpu启动流程

    secondary cpu启动 由于psci方式启动secondary cpu的流程,除了其所执行的cpu_ops不同之外,其它流程与spin-table方式是相同的,因此我们这里只给出执行流程图
    的头像 发表于 12-05 17:41 783次阅读
    <b class='flag-5'>SMP</b><b class='flag-5'>多核</b>secondary cpu<b class='flag-5'>启动</b>流程

    PSCI处理函数代码分析

    处理函数根据funid来决定服务,可以看到PSCI_CPU_ON_AARCH64为0xc4000003,这正是设备树中填写的cpu_on属性的id,会委托psci_cpu_on来执行核上电任务。下面
    的头像 发表于 12-05 18:08 873次阅读