四会市城乡规划建设局网站,淘宝代码网站有哪些,金湖做网站,网页链接怎么转换成pdf一、psci介绍 psci是arm提供的一套电源管理接口#xff0c;当前一共包含0.1、0.2和1.0三个版本。它可被用于以下场景#xff1a; #xff08;1#xff09;cpu的idle管理
#xff08;2#xff09;cpu hotplug以及secondary cpu启动
#xff08;3#xff09;系统shutdo…一、psci介绍 psci是arm提供的一套电源管理接口当前一共包含0.1、0.2和1.0三个版本。它可被用于以下场景 1cpu的idle管理
2cpu hotplug以及secondary cpu启动
3系统shutdown和reset 但该接口不包含dvfs和设备电源管理如像GPU之类的外设电源管理功能。 由于psci与虚拟化以及trust os有一定的关联为了专注于电源管理相关的实现故本系列的介绍都不涉及与它们相关的内容。 下面我们将按照电源管理拓扑结构power domain、电源状态power state以及armv8安全扩展几个方面介绍psci的一些基础知识
1.1 power domain 我们前面已经介绍过cpu的拓扑结构如aarch64架构下每块soc可能会包含多个cluster而每个cluster又包含多个core它们共同组成了层次化的拓扑结构。如以下为一块包含2个cluster每个cluster包含四个core的soc 由于其中每个core以及每个cluster的电源都可以独立地执行开关操作因此若core0 – core3的电源都关闭了则cluster 0的电源也可以被关闭以降低功耗。若core0 – core3中的任一个core需要上电则显然cluster 0需要先上电。为了更好地进行层次化电源管理psci在电源管理流程中将以上这些组件都抽象为power domain。如以下为上例的power domain层次结构 其中system level用于管理整个系统的电源cluster level用于管理某个特定cluster的电源而core level用于管理一个单独core的电源。
1.2 power state 由于aarch64架构有多种不用的电源状态不同电源状态的功耗和唤醒延迟不同。如standby状态会关闭power domain的clock但并不关闭电源。因此它虽然消除了门电路翻转引起的动态功耗但依然存在漏电流等引起的静态功耗。故其功耗相对较大但相应地唤醒延迟就比较低。 而对于power down状态会断开对应power domain的电源因此其不仅消除了动态功耗还消除了静态功耗相应地其唤醒延迟就比较高了。 psci一共为power domain定义了四种power state
1run电源和时钟都打开该domain正常工作
2standby关闭时钟但电源处于打开状态。其寄存器状态得到保存打开时钟后就可继续运行。功耗相对较大但唤醒延迟较低。arm执行wfi或wfe指令会进入该状态。
3retention它将core的状态包括调试设置都保存在低功耗结构中并使其部分关闭。其状态在从低功耗变为运行时能自动恢复。从操作系统角度看除了进入方法、延迟等有区别外其它都与standby相同。它的功耗和唤醒延迟都介于standby和power down之间。
4power down关闭时钟和电源。power domain掉电后所有状态都丢失上电以后软件必须重新恢复其状态。它的功耗最低但唤醒延迟也相应地最高。 显然power state的睡眠程度从run到power down逐步加深。而高层级power domain的power state不应低于低层级power domain。如以上例子中core 0 – core 2都为power down状态而core 3为standby状态则cluster 0不能为retention或power down状态。同样若cluster 0为standby状态而cluster 1为run状态则整个系统必须为run状态。 当然若core 0 –core 3都为power down状态则cluster 1保持其它状态除了增大功耗之外并没有其它意义因此也应该将其设置为power down状态。
为了达到上述约束不同power domain之间的power state具有以下关系 psci实现了父leve与子level之间的电源关系协调如cluster 0中最后一个core被设置为power down状态后psci就会将该cluster也设置为power donw状态。若其某一个core被设置为run状态则psci会先将其对应cluster的状态设置为run然后再设置对应core的电源状态这也是psci名字的由来power state coordinate interface
.3 armv8的安全扩展 为了增强arm架构的安全性aarch64一共实现了secure和non-secure两种安全状态。通过一系列硬件扩展在cpu执行状态、总线、内存、外设、中断、tlb、cache等方面都实现了两种状态之间的隔离。 在这种机制下secure空间的程序可以访问所有secure和non-secure的资源而non-secure空间的程序只能访问non-secure资源却不能访问secure资源。从而可以将一些安全关键的资源放到secure空间以增强其安全性。 为此aarch64实现了4个异常等级其中EL3工作在secure空间而EL0 – EL2既可以工作于secure空间又可以工作于non-secure空间。不同异常等级及不同secure状态的模式下可运行不同类型软件。 如secure EL1和El0用于运行trust os内核及其用户态程序non-secure EL1和El0用于运行普通操作系统内核如linux及其用户态程序EL2用于运行虚拟机的hypervisor。而EL3运行secure monitor程序通常为bl31其功能为执行secure和non secure状态切换、消息转发以及提供类似psci等secure空间服务。以下为其示意图 psci是工作于non secure EL1linux内核和EL3bl31之间的一组电源管理接口其目的是让linux实现具体的电源管理策略而由bl31管理底层硬件相关的操作。从而将cpu电源控制这种影响系统安全的控制权限放到安全等级更高的层级中从而提升系统的整体安全性。 那么psci如何从EL1调用EL3的服务呢其实它和系统调用是类似的只是系统调用是用户态程序陷入操作系统内核而psci是从操作系统内核陷入secure monitor。armv8提供了一条smc异常指令内核只需要提供合适的参数后触发该指令即可通过异常的方式进入secure monitor。
二、psci软件架构
由于psci是由linux内核调用bl31中的安全服务实现cpu电源管理功能的。因此其软件架构包含三个部分 1内核与bl31之间的调用接口规范
2内核中的架构
3bl31中的架构
2.1 psci接口规范
psci规定了linux内核调用bl31中电源管理相关服务的接口规范它包含实现以下功能所需的接口1cpu idle管理
2向系统动态添加或从系统动态移除cpu通常称为hotplug
3secondary cpu启动
4系统的shutdown和reset psci接口规定了命令对应的function_id、接口的输入参数以及返回值。 其中输入参数可通过x0 – x7寄存器传递而返回值通过x0 – x4寄存器传递。 如secondary cpu启动或cpu hotplug时可调用cpu_on接口为一个cpu执行上电操作。该接口的格式如下 1function_id0xc400 0003
2输入参数使用mpidr值表示的target cpu id cpu启动入口的物理地址 context id该值用于表示本次调用上下文相关的信息
3返回值可以为success、invalid_parameter、invalid_address、already_on、on_pending或internal_failure 有了以下这些接口的详细定义内核和bl31就只需按照该接口的规定独立开发psci相关功能。从而避免了它们之间的耦合简化了开发复杂度。
2.2 内核中的psci架构 内核psci软件架构包含psci驱动和每个cpu的cpu_ops回调函数实现两部分。其中psci驱动实现了驱动初始化和psci相关接口实现功能而cpu_ops回调函数最终也会调用psci驱动的接口。
2.2.1 psci驱动
首先我们看一下devicetree中的配置 psci {compatible arm,psci-0.2; 1method smc; 2} 1用于指定psci版本
2根据该psci由bl31处理还是hypervisor处理可以指定其对应的陷入方式。若由bl31处理为smc若由hypervisor处理则为hvc
目前我开发的英伟达板子上的设备树信息 驱动流程主要是与bl31通信以确认其是否支持给定的psci版本以及相关psci操作函数的实现其流程如下 其主要工作即为psci设置相关的回调函数该函数定义如下
// kernel/drivers/firmware/psci/psci.cstatic void __init psci_0_2_set_functions(void)
{pr_info(Using standard PSCI v0.2 function IDs\n);psci_ops.get_version psci_get_version;--------------------(1)psci_function_id[PSCI_FN_CPU_SUSPEND] PSCI_FN_NATIVE(0_2, CPU_SUSPEND);psci_ops.cpu_suspend psci_cpu_suspend;psci_function_id[PSCI_FN_CPU_OFF] PSCI_0_2_FN_CPU_OFF;psci_ops.cpu_off psci_cpu_off;psci_function_id[PSCI_FN_CPU_ON] PSCI_FN_NATIVE(0_2, CPU_ON);psci_ops.cpu_on psci_cpu_on;psci_function_id[PSCI_FN_MIGRATE] PSCI_FN_NATIVE(0_2, MIGRATE);psci_ops.migrate psci_migrate;psci_ops.affinity_info psci_affinity_info;psci_ops.migrate_info_type psci_migrate_info_type;pm_power_off psci_sys_poweroff;---------------------(2)arm_pm_restart psci_sys_reset;set_system_pmic_post_power_off_handler(psci_sys_poweroff);---(3)
}1为psci_ops设置相应的回调函数
2为psci模块设置系统重启时的通知函数
3将系统的power_off函数指向相应的psci接口
这里补充一点psci-1.0 也是先基于psci-0.2 初始化的。下面是内核源码。
static const struct of_device_id psci_of_match[] __initconst {{ .compatible arm,psci, .data psci_0_1_init},{ .compatible arm,psci-0.2, .data psci_0_2_init},{ .compatible arm,psci-1.0, .data psci_1_0_init},{},
};static int __init psci_1_0_init(struct device_node *np)
{int err;err psci_0_2_init(np);if (err)return err;if (psci_has_osi_support()) {pr_info(OSI mode supported.\n);/* Default to PC mode. */psci_set_osi_mode(false);}return 0;
}2.2.2 cpu_ops接口 驱动初始化完成后cpu的cpu_ops就可以调用这些回调实现psci功能的调用。如下所示当devicetree中cpu的enable-method设置为psci时该cpu的cpu_ops将指向cpu_psci_ops。
cpu0: cpu0 {...enable-method psci;…
}
其中cpu_psci_ops的定义如下
//kernel/arch/arm64/kernel/psci.cconst struct cpu_operations cpu_psci_ops {.name psci,.cpu_init cpu_psci_cpu_init,.cpu_prepare cpu_psci_cpu_prepare,.cpu_boot cpu_psci_cpu_boot,
#ifdef CONFIG_HOTPLUG_CPU.cpu_can_disable cpu_psci_cpu_can_disable,.cpu_disable cpu_psci_cpu_disable,.cpu_die cpu_psci_cpu_die,.cpu_kill cpu_psci_cpu_kill,
#endif
};如启动cpu的接口为cpu_psci_cpu_boot它会通过以下流程最终调用psci驱动中的psci_ops函数
static int cpu_psci_cpu_boot(unsigned int cpu)
{phys_addr_t pa_secondary_entry __pa_symbol(function_nocfi(secondary_entry));int err psci_ops.cpu_on(cpu_logical_map(cpu), pa_secondary_entry);if (err)pr_err(failed to boot CPU%d (%d)\n, cpu, err);return err;
}
2.3 bl31中的psci架构是安全系统optee-os 中的内核 bl31为内核提供了一系列运行时服务psci作为其标准运行时服务的一部分通过宏DECLARE_RT_SVC注册到系统中。其相应的定义如下
DECLARE_RT_SVC(std_svc,OEN_STD_START,OEN_STD_END,SMC_TYPE_FAST,std_svc_setup,std_svc_smc_handler
) 其中std_svc_setup会在bl31启动流程中被调用以用于初始化该服务相关的配置。而std_svc_smc_handler为其smc异常处理函数当内核通过psci接口调用相关服务时最终将由该函数执行实际的处理流程。 上图为psci初始化相关的流程它主要包含内容
1前面我们已经介绍过power domain相关的背景即psci需要协调不同层级的power domain状态因此其必须要了解系统的power domain配置情况。以上流程中红色虚线框的部分主要就是用于初始化系统的power domain拓扑及其状态
2由于psci在执行电源相关接口时最终需要操作实际的硬件。而它们是与架构相关的因此其操作函数最终需要注册到平台相关的回调中。plat_setup_psci_ops即用于注册特定平台的psci_ops回调其格式如下
typedef struct plat_psci_ops {void (*cpu_standby)(plat_local_state_t cpu_state);int (*pwr_domain_on)(u_register_t mpidr);void (*pwr_domain_off)(const psci_power_state_t *target_state);void (*pwr_domain_suspend_pwrdown_early)(const psci_power_state_t *target_state);void (*pwr_domain_suspend)(const psci_power_state_t *target_state);void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);void (*pwr_domain_on_finish_late)(const psci_power_state_t *target_state);void (*pwr_domain_suspend_finish)(const psci_power_state_t *target_state);void __dead2 (*pwr_domain_pwr_down_wfi)(const psci_power_state_t *target_state);void __dead2 (*system_off)(void);void __dead2 (*system_reset)(void);int (*validate_power_state)(unsigned int power_state,psci_power_state_t *req_state);int (*validate_ns_entrypoint)(uintptr_t ns_entrypoint);void (*get_sys_suspend_power_state)(psci_power_state_t *req_state);int (*get_pwr_lvl_state_idx)(plat_local_state_t pwr_domain_state,int pwrlvl);int (*translate_power_state_by_mpidr)(u_register_t mpidr,unsigned int power_state,psci_power_state_t *output_state);int (*get_node_hw_state)(u_register_t mpidr, unsigned int power_level);int (*mem_protect_chk)(uintptr_t base, u_register_t length);int (*read_mem_protect)(int *val);int (*write_mem_protect)(int val);int (*system_reset2)(int is_vendor,int reset_type, u_register_t cookie);
}
最后我们再看一下psci操作相应的异常处理流程 即其会根据function id的值分别执行相应的电源管理服务如启动cpu时会调用psci_cpu_on函数重启系统时会调用psci_system_rest函数等。
三、secondary cpu启动 由于psci方式启动secondary cpu的流程除了其所执行的cpu_ops不同之外其它流程与spin-table方式是相同的因此我们这里只给出执行流程图详细分析可以参考上篇博文。其中以下流程执行secondary cpu启动相关的一些初始化工作 在初始化完成且hotplug线程创建完成后就可通过以下流程唤醒cpu hotplug线程 此后hotplug线程将调用psci回调函数并最终触发smc异常进入bl31 bl31接收到该异常后执行std_svc_smc_handler处理函数并最终调用平台相关的电源管理接口完成cpu的上电工作以下为其执行流程 平台相关回调函数pwr_domain_on将为secondary cpu设置入口函数然后为其上电使该cpu跳转到内核入口secondary_entry处开始执行。以下为其内核启动流程 文章转载自: http://www.morning.kjgrg.cn.gov.cn.kjgrg.cn http://www.morning.kbqqn.cn.gov.cn.kbqqn.cn http://www.morning.rymd.cn.gov.cn.rymd.cn http://www.morning.sfyqs.cn.gov.cn.sfyqs.cn http://www.morning.kwpnx.cn.gov.cn.kwpnx.cn http://www.morning.gccdr.cn.gov.cn.gccdr.cn http://www.morning.xyyplp.cn.gov.cn.xyyplp.cn http://www.morning.kwnbd.cn.gov.cn.kwnbd.cn http://www.morning.brmbm.cn.gov.cn.brmbm.cn http://www.morning.rkgyx.cn.gov.cn.rkgyx.cn http://www.morning.qqhmg.cn.gov.cn.qqhmg.cn http://www.morning.ntqqm.cn.gov.cn.ntqqm.cn http://www.morning.jggr.cn.gov.cn.jggr.cn http://www.morning.nynyj.cn.gov.cn.nynyj.cn http://www.morning.3ox8hs.cn.gov.cn.3ox8hs.cn http://www.morning.npbkx.cn.gov.cn.npbkx.cn http://www.morning.fyskq.cn.gov.cn.fyskq.cn http://www.morning.bbjw.cn.gov.cn.bbjw.cn http://www.morning.chgmm.cn.gov.cn.chgmm.cn http://www.morning.zrwlz.cn.gov.cn.zrwlz.cn http://www.morning.fnbtn.cn.gov.cn.fnbtn.cn http://www.morning.qbfqb.cn.gov.cn.qbfqb.cn http://www.morning.rgyts.cn.gov.cn.rgyts.cn http://www.morning.pqnkg.cn.gov.cn.pqnkg.cn http://www.morning.ktnmg.cn.gov.cn.ktnmg.cn http://www.morning.jmnfh.cn.gov.cn.jmnfh.cn http://www.morning.bynf.cn.gov.cn.bynf.cn http://www.morning.kwjyt.cn.gov.cn.kwjyt.cn http://www.morning.rwfp.cn.gov.cn.rwfp.cn http://www.morning.yrdt.cn.gov.cn.yrdt.cn http://www.morning.hbfqm.cn.gov.cn.hbfqm.cn http://www.morning.jjsxh.cn.gov.cn.jjsxh.cn http://www.morning.dgsr.cn.gov.cn.dgsr.cn http://www.morning.rzdpd.cn.gov.cn.rzdpd.cn http://www.morning.nlryq.cn.gov.cn.nlryq.cn http://www.morning.znlhc.cn.gov.cn.znlhc.cn http://www.morning.qmzhy.cn.gov.cn.qmzhy.cn http://www.morning.stxg.cn.gov.cn.stxg.cn http://www.morning.wjplm.cn.gov.cn.wjplm.cn http://www.morning.mtrrf.cn.gov.cn.mtrrf.cn http://www.morning.wsgyq.cn.gov.cn.wsgyq.cn http://www.morning.jqjnl.cn.gov.cn.jqjnl.cn http://www.morning.qztdz.cn.gov.cn.qztdz.cn http://www.morning.dqkrf.cn.gov.cn.dqkrf.cn http://www.morning.jmmz.cn.gov.cn.jmmz.cn http://www.morning.chmcq.cn.gov.cn.chmcq.cn http://www.morning.dfqmy.cn.gov.cn.dfqmy.cn http://www.morning.zdbfl.cn.gov.cn.zdbfl.cn http://www.morning.xhgxd.cn.gov.cn.xhgxd.cn http://www.morning.tmrjb.cn.gov.cn.tmrjb.cn http://www.morning.dwxqf.cn.gov.cn.dwxqf.cn http://www.morning.jqjnl.cn.gov.cn.jqjnl.cn http://www.morning.ykrkq.cn.gov.cn.ykrkq.cn http://www.morning.dxpzt.cn.gov.cn.dxpzt.cn http://www.morning.jtcq.cn.gov.cn.jtcq.cn http://www.morning.yntsr.cn.gov.cn.yntsr.cn http://www.morning.qfdmh.cn.gov.cn.qfdmh.cn http://www.morning.rszbj.cn.gov.cn.rszbj.cn http://www.morning.qdlnw.cn.gov.cn.qdlnw.cn http://www.morning.kaweilu.com.gov.cn.kaweilu.com http://www.morning.swkzr.cn.gov.cn.swkzr.cn http://www.morning.pnljy.cn.gov.cn.pnljy.cn http://www.morning.kehejia.com.gov.cn.kehejia.com http://www.morning.phgz.cn.gov.cn.phgz.cn http://www.morning.tsqrc.cn.gov.cn.tsqrc.cn http://www.morning.xltdh.cn.gov.cn.xltdh.cn http://www.morning.kuaijili.cn.gov.cn.kuaijili.cn http://www.morning.tqygx.cn.gov.cn.tqygx.cn http://www.morning.dhxnr.cn.gov.cn.dhxnr.cn http://www.morning.xrqkm.cn.gov.cn.xrqkm.cn http://www.morning.nqlcj.cn.gov.cn.nqlcj.cn http://www.morning.gjwkl.cn.gov.cn.gjwkl.cn http://www.morning.mgnrc.cn.gov.cn.mgnrc.cn http://www.morning.fncgw.cn.gov.cn.fncgw.cn http://www.morning.czlzn.cn.gov.cn.czlzn.cn http://www.morning.dyxlm.cn.gov.cn.dyxlm.cn http://www.morning.hwxxh.cn.gov.cn.hwxxh.cn http://www.morning.snnwx.cn.gov.cn.snnwx.cn http://www.morning.wsgyq.cn.gov.cn.wsgyq.cn http://www.morning.pjbhk.cn.gov.cn.pjbhk.cn