接下来准备写几篇,结合前面的文章,从硬件和软件角度分析一下基于ARM系统的电源和时钟管理方法。
今天来看一个电源功耗相关的东西,PSCI(Power State Coordination Interface),翻译一下就是“电源状态协作接口”。从名字就能直观看出来,PSCI是一套电源管理的标准接口,可用于操作系统在ARM设备上以不同权限级别监控管理电源。在大型应用中,芯片的电源管理必须要灵活,需要软硬件协同。也就是说,操作系统、虚拟机监控程序、安全固件或者受信任的操作系统(trusted OS)要能够参与到芯片的电源管理中。
在现代的操作系统中,有专用的电源管理程序,叫OSPM(OS Power Management),用来管理处理器和设备的电源。比如下图中的CPUFreq,主要工作是负责动态调压调频(DVFS),关于DVFS,在前面的文章讲过,《SoC设计之功耗 -- DVFS》;CPUIdle是管理处理器在空闲状态时的功耗;Hotplug技术是可以动态的给处理器核上下电,并且完成处理器核的加载(上电)/移除(下电)。Hotplug与CPUIdle虽然都可以做电源开关管理,不同之处在于hotplug在移除处理器核时,同时要把相关信息从操作系统的调度器(scheduler)移除,并且需要重新配置中断处理器以保证新的中断不会再发给该处理器核;反过来,如果处理器核重新上电,要在OS调度器中加载该处理器的信息,并且需要重新配置中断寄存器。而CPUIdle就没有加载/移除的需要。
从上图可以看出来,PSCI主要负责的是三方面的事情:
- 处理器空闲管理
- 处理器动态加载/移除,以及二次启动
- 系统关闭和复位
至于DVFS和设备的电源管理并不在本协议里面。
ARM系统通常包括一个或多个电源控制器,可以管理核心电源,在上图中对应部分是左侧的SCP。考虑到ARM定义了4个异常等级和安全域与非安全域,电源管理变得更加复杂。
多核处理器系统中通常会有很多的电源域。每个电源域可能包含一个或多个处理单元(处理器,协处理器,GPU),存储系统(缓存,DRAM),互连。虽然所有这些电源域在物理上不一定是分层方式构建的,但从软件角度看,它们是有逻辑层次的,并且会有一定的依赖关系。比如在带有共享高速缓存的设计中,如果要关闭共享缓存的电源,就必须保证在此之前,所有能访问这个高速缓存的处理器核全部关闭,这样才能保证功能上的正确性。
PSCI提供一套API来协调电源管理,如下:
- PSCI_VERSION:可以调用此API得到当前PSCI的版本信息;
- CPU_SUSPEND:OSPM调用此API使处理器核进入低功耗模式;
- CPU_OFF:此API用于hotplug,从系统中动态移除某个处理器核。被CPU_OFF移除的处理器核只能通过CPU_ON再次加载。与CPU_SUSPEND不同的是,这个接口函数不需要返回值;
- CPU_ON:此API用于动态加载处理器核;
- AFFINITY_INFO:此API允许调度方查询亲和实体(affinity instance)的状态;
- MIGRATE:用于将受信任的操作系统(trusted OS)迁移到另一个处理器核,从而原处理器核可以调用CPU_OFF关闭电源;
- MIGRATE_INFO_TYPE:允许调用方识别受信任操作系统中存在的多核支持级别,通过返回值可以判定受信任操作系统是否必须运行在单一处理器上,是否支持迁移;
- MIGRATE_INFO_UP_CPU:指示受信任的操作系统当前的位置;
- SYSTEM_OFF:系统关闭;
- SYSTEM_RESET:系统冷复位;
- SYSTEM_RESET2:此API是对SYSTEM_RESET的扩展;
- MEM_PROTECT:此API确保内存在交给操作系统加载程序之前被重写,从而提供防止冷重启攻击的保护;
- MEM_PROTECT_CHECK_RANGE:此API用于检查某段内存范围是否受MEM_PROTECT保护;
- PSCI_FEATURES:此API允许调用方检测已实现的PSCI函数及其属性;
- CPU_FREEZE:此API将处理器核设置于低功耗状态(依赖具体设计实现)。与CPU_SUSPEND和CPU_DEFAULT_SUSPEND不同,中断不能唤醒该处理器;与CPU_OFF也不同,不需要迁移;
- CPU_DEFAULT_SUSPEND:此API将处理器核设置于低功耗状态(依赖具体设计实现),与CPU_FREEZE的调用参数不同;
- NODE_HW_STATE:此API允许直接从电源控制器或电源控制逻辑确定节点的电源状态。与AFFINITY_INFO不同,此API返回电源状态的物理视图;
- SYSTEM_SUSPEND:此API相当于CPU_SUSPEND到最深的低功耗状态,但实际系统中有可能实现比CPU_SUSPEND更深的低功耗状态,比如支持RAM挂起;
- PSCI_SET_ SUSPEND_MODE:此API允许设置CPU_SUSPEND用于协调电源状态的模式;
- PSCI_STAT_RESIDENCY:此API返回自冷启动后平台处于某个电源状态的时间;
- PSCI_STAT_COUNT:此API返回自冷启动后平台使用某个电源状态的次数;
这些API中有一些是必选项,有一些是可选项(名字加粗),至于支持哪些要根据实际实现来定。对于这些API调用参数不做介绍,感兴趣的话去查手册。
今天的短文结束前,再多解释一个概念。CPU的亲和性(affinity)属性是一种调度属性(scheduler property),通过它可以将一个进程“绑定”到一个或一组CPU上。在SMP(Symmetric Multi-Processing)架构下,Linux的调度器会根据affinity的设置让指定的进程运行在“绑定”的CPU上,而不会在别的CPU上运行。Linux的调度器也支持自然CPU亲和性(natural CPU affinity),调度器会试图保持进程在相同的CPU上运行,这意味着进程通常不会在处理器之间频繁迁移。ARMv8-A中,CPU的亲和性值保存在寄存器MPIDR_EL1{Aff3, Aff2, Aff1,Aff0}中。
今天讲的主要是电源管理的软件相关部分。如果大家对ARM体系下的硬件低功耗设计感兴趣,可以翻一下前面的旧文,《ARM系列 -- PCSA(一)》,《ARM系列 -- PCSA(二)》。个人认为,对于做SoC设计来说,知道软硬件如何协调工作也是有必要的,尤其是做架构设计。下周我们来看MHU,也就是第一张图中的灰色部分。
原文链接:老秦谈芯
作者:老秦谈芯
推荐阅读
更多IC设计技术干货请关注IC设计技术专栏。