bl31中的psci架构介绍

描述

bl31中的psci架构

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函数等。

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

全部0条评论

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

×
20
完善资料,
赚取积分