1 介绍
本文主要是在ARM架构的不同异常等级上工作的软件之间,提供一个标准的电源管理接口。这些软件,比如Linux、Hypervisor、安全Firmware和可信OS之间必须能够实现互相操作。而这些软件可能由不同厂商提供,本标准就是为这些软件的集成提供便利。
这些PSCI接口有利于电源管理代码通用化、模块化:
- CPU核的空闲管理
- CPU核的动态添加、删除,以及辅核引导
- 系统关机和复位
该接口规范不会包含动态电压频率调节(DVFS)或设备电源管理(比如,GPU等外设的管理).
该接口规范设计用来与硬件探测技术(如ACPI和FDT)等配合使用,并不是要取代ACPI或FDT。
本文描述了PSCI版本1.1,1.0和0.2。对于0.2,还提供了一个勘误更新。
本文包含以下内容:
- 第1章 提供介绍和文档引用
- 第2-4章 提供背景知识,包括:
- PSCI的设计目的
- 电源状态术语的定义
- 发送PSCI请求的方法
- ARM架构知识
- 第5章 提供PSCI功能的主要描述
- 第6章 提供PSCI功能的实现细节
- 第7-8章 提供PSCI规范的修订历史和术语表
1.1 ARM官方文档
下面这些文档包含与本文档相关的信息:
- [1] ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition (ARM DDI 0406).
- [2] Embedded Trace Macrocell Architecture Specification (ARM IHI 0014).
- [3] Program Flow Trace Architecture Specification (ARM IHI 0035).
- [4] SMC调用约定(ARM DEN 0028).
- [5] ARM Architecture Reference Manual ARMv8, for ARMv8-A architecture profile (ARM DDI 0487).
- [6] ACPI规范.
- [7] PSCI设备树定义.
- [8] ARM可信固件(
ATF). - [9] Power Control System Architecture Specification (ARM DEN 0050).
2 背景知识
支持电源管理的操作系统,能够动态改变CPU核的电源状态,根据进行负载均衡,努力降低功耗。电源管理技术主要分为两类:
- 空闲管理:当在某个核上,OS的内核没有线程可以调度时,可以将该核置于
clock-gated、retention、power-gated状态。但是,该核对于OS而言还是可用的。 Hotplug热插拔:根据对算力的需求变化,而将CPU核置于离线、在线。离线时,OS负责将所有中断和线程从核上迁移走;当在线时,OS负责重新进行负载均衡。
尽管由单个供应商提供嵌入式系统的软件可能更简单,但事实并非如此。为了安全,ARM将硬件架构划分为4个不同的异常级(EL)以及2个安全状态,以便支持不同特权的软件分区。
下表是基于ARM架构的硬件平台上的软件划分:
| AArch32 | AArch64 | 软件和供应商 |
NS_EL0 (PL0) |
NS_EL0 |
非特权应用,如APP |
NS_EL1 (PL1) |
NS_EL1 |
富操作系统内核,如Linux、Windows、iOS |
NS_EL2 (PL2) |
NS_EL2 |
Hypervisor(Citrix、VMWare、OK-Labs) |
S_EL0 (PL0) |
S_EL0 |
可信OS的应用 |
S_EL3 (PL1) |
S_EL1 |
可信OS的内核(Trustonic) |
S_EL3 (PL1) |
S_EL3 |
安全Monitor,执行安全固件(ATF) |
AArch32是ARMv8架构的32位执行状态,在ARMv8架构之前采用的执行状态。在ARMv7处理器中,异常级的概念是隐含的,相关文档也并未说明。那时候,虚拟化扩展提供
EL2功能,安全扩展提供EL3功能,安全状态由特权级(PL-Privilege Level)标识异常的层次结构。更多信息,参考第3.2节。
因为不同供应商的不同操作系统都可运行在ARM系统上,电源管理就需要一个协作的方法。考虑到运行在EL1上的类OS软件或运行在EL2上的hypervisor软件,一般处于非安全状态,如果想要进入idle状态、给一个核上电或掉电、或复位或关闭系统,更高异常级的监控软件必须能够响应这种电源状态变化的请求。
同样,如果某个wakeup事件改变了核的电源状态,那么这些监管软件需要执行诸如恢复上下文之类的操作。PSCI提供了不同监管软件之间互操作和集成的标准接口定义。本文档会详细描述这类接口,以及在idle、hotplug、shutdown和reset情况下如何使用它们。
3 假设和建议
本文档定义了在不同监管软件之间协调电源管理的API。这种API允许监管软件请求给核上电、掉电,安全上下文的核间迁移(可信OS需要)。本文中,假设EL2和EL3都已经实现。
3.1 PSCI用途
PSCI具有下面的用途:
- 提供给监控程序通用接口,可以在下列情况时,管理功耗:
- CPU核的空闲管理;
- 系统中的CPU核动态添加和删除,也称之为
hotplug热插拔; - 其它辅核的启动;
- 将受信任的操作系统上下文从一个核迁移到另一个核;
- 系统关机和复位。
- 提供给监控管理程序通用接口,结合
FDT和ACPI描述去支持电源管理代码的泛化。
PSCI不包括:外设电源管理 和 动态电压和频率调节(DVFS)。
PSCI不提供给监控软件电源状态表示。但是,可以和ACPI或FDT等硬件描述技术结合使用。
3.2 异常级别、ARMv7特权级别和最高特权级别
ARMv8架构明确提出了EL的概念,也定义了安全状态下软件执行特权的层次结构。
ARMv7架构中,EL概念是隐含在架构体系中的:
- 虚拟化扩展提供了
EL2的功能(只存在非安全状态下)。 - 安全扩展提供了
EL3功能,包含对两种安全状态的支持。控制是在Monitor模式下完成的,该模式也只存在于安全状态下。
ARMv7使用PL(特权级)的概念描述软件执行的特权层级结构。因为Monitor模式的存在,ARMv7的非安全状态和安全状态是非对称的,如下所述:
- 非安全状态,特权层次结构是:
PL0, 非特权,适用于User模式PL1,OS级特权,适用于System,FIQ,IRQ,Supervisor,Abort和Undefined模式PL2,hypervisor特权,适用于Hyp模式
- 安全状态,特权层次结构是:
Secure PL0, 非特权,仅适用于User模式Secure PL1, 可信OS和Monitor级特权,适用于System,FIQ,IRQ,Supervisor,Abort,Undefined和Monitor模式
AArch32执行状态下,异常级和之前的运行模式对应关系如下:
- 非安全状态:
EL0:User模式EL1:System,FIQ,IRQ,Supervisor,Abort和Undefined模式EL2:Hyp模式
- 安全状态:
Secure EL0:User模式EL3:System,FIQ,IRQ,Supervisor,Abort,Undefined和Monitor模式
本文档中如果不特殊声明,则使用异常级别(EL)的术语:
- 通常情况下,提及的
EL1和EL0就是指非安全EL1和EL0,除非有特殊说明;
3.3 ARM架构上的软件栈
ARM设备上可能有的软件栈,如下所示:
如图所示,非安全空间中的拥有特权的代码:
Rich-OS内核:比如,Linux或Windows,运行在非安全EL1。如果运行在Hypervisor之上,则Rich-OS内核作为hypervisor的一个客户机运行。Hypervisor:运行在EL2,只有非安全状态(新ARMv8架构中,已经存在安全状态的hypervisor)。
安全空间中拥有特权的代码:
安全平台固件(SPF):
芯片或OEM厂商提供。也是系统启动阶段,运行的第一段程序。它提供的服务有,平台初始化、可信OS的安装、SMC调用的调度执行。有些调用的目标可能是SPF,另一些则可能是可信OS。SPF可以运行在EL3,也可以运行在安全EL1(但是,条件是EL3运行在AArch64状态)。ARM提供了一个开源的可信固件代码。可信OS:
为normal空间提供安全服务,即为安全应用提供一个运行时环境。在AArch32状态下,可信OS运行在安全EL3,如果是AArch64状态,运行在EL1。
PSCI规范主要关注安全、非安全世界之间的电源管理接口。它提供了发送电源管理请求的方法。所以,为了处理这些请求,SPF必须包含PSCI实现。
另外,PSCI实现也可能需要在SPF和可信OS之间建立通信。当然,它们之间的处理根据厂商不同而有所不同。
尽管,PSCI主要关注安全和非安全世界之间的电源管理请求,但是,也可以在Rich OS和hypervisor之间使用。
3.4 通道
在不同的异常级别之间提供可以传送消息的通道(一般使用SMC异常指令实现),这样才能提供相同的PSCI电源管理接口。具体参考SMCCC。
3.5 安全软件和电源管理
许多可信OS不支持SMP。即使在多核平台上,也是运行在某个指定的核上。所以,期望发起SMC调用的核与可信OS运行的核是同一个。不支持多核,可以保证可信OS小而美,容易通过功能安全认证。
基于ARM架构的系统通常会包含一个电源控制器,或者电源管理电路,以便管理CPU核的电源。它会提供许多电源管理功能,比如将核、簇或者集群转变为低功耗状态。在低功耗状态,核可以完全关掉,也可以不执行代码而处于静默状态。ARM 强烈推荐由安全空间控制电源状态的变化。否则,在进入低功耗状态之前,不能清除安全状态(包括安全cache的清零)。其它的电源管理,比如动态电源性能管理(通过调节电压和频率实现)不在本接口规范的范围内。
3.6 虚拟化和CPU核电源管理策略
虚拟机可以分为两种类型
Type-1: 有时候称为native或bare metal。通俗理解的话,就是hypervisor代码直接接管硬件,对上提供统一的虚拟隔离空间。所以,Guest OS看到的都是虚拟设备。Type-2: 有时候称为hosted,或者托管类型hypervisor。这类虚拟程序需要依赖一个主机OS,作为宿主。该Host OS看到的是真实硬件,但是Guest OS看到的是虚拟设备。
这是一个泛泛的分类,可能会有许多变种。ARMv8架构允许在EL1或EL2运行一个Type-2类型的hypervisor,这更加模糊了类型-1和类型-2的差异。但是,对于电源管理来说,不论哪种类型的hypervisor,都需要捕获这种PSCI调用。
从电源管理和虚拟化的角度来看的话,有两种类型的OSPM:
- 物理OSPM: 这个概念包含管理物理电源状态的软件。
- 虚拟OSPM: 这是存在于虚拟机的
Guest OS中的OSPM,它管理的是虚拟的,而不是物理电源状态。
对于type-2 hypervisor,物理OSPM存在于主机OS中。电源管理策略由运行在EL1的Rich OS负责管理。物理OSPM就包含在这种Rich OS中。在该层,直接拥有物理核的视角。下图的左边部分就是示例。
对于本文涉及的电源管理,type-2 hypervisor的行为取决于调用者。如果调用者是Host OS,hypervisor允许调用直接穿透到安全平台固件(SPF)。在这种情况下,hypervisor只需执行必要的操作,比如保存powerdown时的状态。然后,使用调用者传递过来的参数调用SPF。如果没有特殊操作,hypervisor甚至不会捕获来自Host OS的调用,直接将其路由给SPF。Guest OS使用虚拟OSPM,也是通过PSCI API发出电源管理请求,但是发送的目标是虚拟核和虚拟电源状态。hypervisor会捕获这些请求,然后将其发送到物理OSPM。然后,由物理OSPM决定是否请求真实的物理电源管理。对于虚拟机来说,电源管理到hypervisor就结束了。
对于type-1 hypervisor,电源管理策略通常是hypervisor自身管理的。如上图右半部分所示。hypervisor实现物理OSPM模块。这种情况下,虚拟机拥有的是虚拟核。由hypervisor决定虚拟机的虚拟电源状态是否请求物理电源控制,如果需要,则使用PSCI API调用安全平台固件SPF。同样,Guest OS也使用PSCI API接口将虚拟电源管理请求发送给hypervisor。对于虚拟机来说,电源管理到hypervisor就结束了。
在某些情况下,type-1 hypervisor委托一个特权Guest OS管理电源。这种情况下,物理OSPM在特权Guest OS中实现。大概的电源管理方法与type-2 hypervisor类似。
4 PSCI使用场景和要求
4.1 空闲管理
当一个核处于idle状态时,OSPM将其置于低功耗状态。通常,选择进入不同的电源状态,会有不同的entry和exit延迟,也会有不同的功耗。想要进入哪种电源状态,依赖于核重新工作的时间。除了核之外,电源状态也可能依赖于SoC中的其它组件的活动。每种状态都由一组组件的状态共同决定,进入该状态时,这些组件通过时钟控制(clock-gated)或电源控制(power-gated)。这些状态有时候也描述为浅睡眠或深度睡眠。通常,文献描述使用X标识深度睡眠,Y标识浅睡眠:
X状态应该是Y状态的超集。X状态比Y状态更省电。
从低功耗状态进入运行状态所需要的时间称为唤醒延迟。通常,深度睡眠状态具有更长的唤醒延迟。
尽管空闲电源管理是由核上的线程行为引起的,但是OSPM将硬件平台设置的状态,也可能会影响除CPU核之外的其它组件。比如,如果SoC中的最后一个核进入idle状态,OSPM就可以考虑整个SoC的电源状态了。此时的选择也会受系统中的其它组件影响,所以,应该在SPF、hypervisor、OS之间协调电源管理。典型的例子是,当所有核,和其它请求者都处于空闲状态时,将系统置于一种状态,在这种状态下,将上下文保存在内存中(内存不断刷新中)。OSPM必须提供必要的电源管理软件基础设施,确定能够对电源状态作出正确的选择。
在空闲管理中,当一个核被置于低功耗状态,它可能随时被唤醒事件激活,比如说中断。
ARM架构划分的电源状态有四种:
Run
CPU核上电,且可以正常运行的状态。Standby
CPU核上电。通过WFI或WFE指令进入该状态,由唤醒事件唤醒。此过程中,CPU核保持所有状态。也就是说,从standby到run状态,不会复位CPU核。CPU核的上下文都会被保持,唤醒即可访问这些内容。处于该核所在电源域的外部调试器(debugger),能够访问debug寄存器。换句话说,standby状态不会影响调试器的使用。Retention
CPU核的状态,包括debug设置等,保存在低功耗的保持寄存器中,这样允许CPU核至少可以关闭部分电源。从低功耗状态到运行态的转变,不用复位CPU核。低功耗转变到运行态时,原先保存的状态数据从保持寄存器中恢复。所以,从OS的角度来说,Retention和Standby状态没有什么差别,除了恢复时的入口地址,延迟和使用上的一些限制之外。但是,对于外部debugger来说,就不一样了,外部debug请求事件会被挂起,debug寄存器无法访问。Powerdown
该状态下,CPU核会被掉电。软件需要保存所有的核状态数据。从掉电到恢复运行,需要:
- 上电后,需要复位CPU核
- 恢复之前保存的核的状态数据
Powerdown状态对上下文是破坏性的。不仅仅是CPU核的状态数据,如果是更深的休眠状态,可能包括GIC或者平台依赖的其它一些IP核也会掉电。所以,相关数据或状态必须保存。根据debug和trace电源域的组织架构,其上下文内容也有可能会丢失。所以,OS必须提供保存和恢复这些内容的机制。
对于OS来说,standby和retention都是一样的,除了debugger之外。所以,后面我们使用standby代表这两种状态。
ARM期望在具有最高特权的异常级别上,实现管理电源控制器的代码(通常就是ATF)。那么就必须提供接口,以便OSPM将CPU核置于低功耗状态的消息事件,从不同的异常级层层往下传递(假设越往下,异常级别越高)。而PSCI就是这样的一种机制,将OSPM的电源请求传递给下一个异常级EL。
对于standby状态,直接使用WFI或WFE指令即可进入。但是,更深层的standby或retention状态,则要求对电源控制器进行编程,而PSCI仅提供访问电源控制器的接口,并隐藏了与平台相关的代码。
对于Powerdown状态,则要求提供每一级EL下保存和恢复上下文的接口。而且,对于Powerdown状态还要求一个return地址。这地址是被唤醒时,OS期望的开始运行的地方。对于Powerdown状态,CPU核从reset复位向量(安全状态)开始运行。待完成初始化,则跳转到Powerdown之前要求的那个返回地址处开始执行。PSCI提供了传递返回地址和上下文的参数。
4.2 电源状态系统拓扑
多核系统中,不同的电源域控制系统的不同部分。每一个电源域可能是一个或多个PE(CPU核、协处理器、GPU),内存(Cache、DRAM),簇内、簇间一致性部件等组成。
电源域中的每个组件的电源状态,都可以影响电源域中的其它组件。虽然,从物理上来说,电源域不是一个必须存在的层次结构。但是,从软件的角度来说,必须进行一个逻辑上的划分。如果想要改变电源域的电源状态,必须对其依赖项进行排序。比如,共享Cache的电源域,以及使用共享Cache的CPU核的电源域,它们之间的依赖关系。在这样一个系统中,为了保证数据的一致性,必须先关闭CPU核的电源,然后再关闭共享Cache的电源。
上图展示了一个系统级的电源域的拓扑结构的示例。它拥有两个子电源域,每一个包含一个cluster簇,支持一组cluster电源状态。每一个cluster电源域,又包含两个子电源域,每一个包含一个CPU核,并额外支持一个电源状态。
从硬件的角度来看,一个系统被划分为多个单独或共享的电源域。每个电源域都可以表示为电源域拓扑树中的一个节点。兄弟电源域是互斥的。父电源域由子电源域共享。树中的各种级别(示例中的核、cluster簇和系统)称为电源级别。较高的级别,更接近树的根(系统),较低的级别更接近树叶(核)。
4.2.1 局部电源状态和组合电源状态
上面拓扑结构中的各个节点都有自己的电源状态,我们称为局部电源状态。当处于空闲核上的OS请求电源状态的改变时,不仅需要请求改变CPU核的局部电源状态,还需要请求改变父节点的电源状态。比如,上图的示例中,假设核1是簇0内最后进入空闲状态的,对于OS来说,就需要同时为簇0和核1请求电源状态改变。这种组合的电源状态我们就称为组合电源状态。这种组合电源状态可不是随意组合的,而是电源等级越高的节点上,其电源状态越浅。换句话说,子节点进入休眠的程度应该大于等于父节点。规则如下:
- 电源等级高的节点掉电(
Powerdown),电源等级低的节点也必须掉电; - 电源等级高的节点保持(
Retention),电源等级低的节点只能是保持或掉电; - 电源等级高的节点待机(
Standby),电源等级低的节点只能是待机、保持或掉电; - 电源等级高的节点运行(
Run),电源等级低的节点可以是任意状态。
如下表所示:
| 系统级 | 簇级 | 核级 |
| Run | Run | Standby |
| Run | Run | Retention |
| Run | Run | Powerdown |
| Run | Retention | Retention |
| Run | Retention | Powerdown |
| Run | Powerdown | Powerdown |
| Retention | Retention | Retention |
| Retention | Retention | Powerdown |
| Retention | Powerdown | Powerdown |
| Powerdown | Powerdown | Powerdown |
4.2.2 亲和力的层次结构
ARM系统通常是多核、或多簇的处理器。本文档使用亲和力的层次结构描述CPU核和簇的架构关系。亲和力层次结构往往直接对应系统的电源拓扑,但这也不是绝对的。
4.2.3 电源状态协调
高层的节点进入某种局部电源状态,必须与子节点的电源状态进行协调。比如说,想要使一个簇(cluster)进入Powerdown状态,那么该簇内所有的核也必须进入Powerdown状态。实现方式就是,其它核都进入Powerdown状态,最后一个核再把自己和簇置于Powerdown状态。
对于这种对子节点的电源状态进行协调的方式,PSCI支持两种:平台协调模式、OS发起模式。
- 平台协调模式
这是默认的电源协调模式。在该模式下,PSCI实现者(如ATF等)负责协调电源状态。当某个核上没有任务时,OSPM为该核、以及所在簇请求允许范围内的最深休眠状态。因为该核的电源状态改变请求,可能影响其父节点,所以,PSCI实现者得根据簇内所有节点的情况选择最深的休眠状态。实际上,电源状态请求表达了两种限制:
PSCI实现就会根据这两个限制,为指定的节点内所有核,选择一个最深的电源状态。下表展示了OSPM请求不同的电源组合状态,而PSCI最终能够响应的状态。假设簇1一直处于掉电状态中。 - 通常情况下,电源状态越深,唤醒延迟越长。所以,我们假设保持状态比掉电状态具有更短的唤醒延迟。但是,事实并非如此。根据第2个限制,PSCI实现者必须满足每个核唤醒时间的请求。假设双核系统,具有3层系统状态,状态A、B、C,电源休眠程度
A < B < C,而唤醒延迟则是A < C < B。如果核0选择状态B,而核1选择状态C,系统将会进入状态A。状态B和C,不能同时满足2个核的要求。PSCI 1.0之前的版本只支持平台协调模式。
- 调用者请求的电源状态已经是最深休眠状态了;
- 调用者请求的电源状态的唤醒延迟不能比这更长了;
- OS协调模式
PSCI 1.0引入,这种模式将电源协调的权利交给了OS。这种模式下,只有节点内的最后一个核进入空闲状态,OSPM才会为该节点申请空闲状态。
相比平台协调方式,OS协调方式则是将怎么选择最合适的休眠节点交给了OS,PSCI实现者只需实现,给我什么请求,我就响应什么动作即可。示例如下表所示: - 如表所示,我们可以看到OS视角和PSCI实现的视角有些不同的地方(红色标记)。这是因为OS虽然请求了,但是PSCI实现还未响应导致的。在上电的时候也会发生,因为PSCI实现会比OS更早看到CPU核。为了实现OS协调方式,必须解决
竞争问题。
- PSCI实现必须怀疑与自己视角不一样的电源状态请求;
- OS必须指明哪个核是最后一个,而且还要指明该核处于哪一级电源中,如,是簇内的最后一个核,还是系统内最后的一个核。
4.3 CPU热插拔和辅核启动
CPU热插拔的概念不需要再重复。但是,CPU热插拔和空闲管理中的powerdown还是有一些差异:
- 当核被拔出时,监控软件会停止在中断和线程处理中对该核的所有使用。调用监控软件认为核不再可用。
- 想要使用该核,必须发送命令将核再插入。
- 唤醒事件不会唤醒被拔出的核。
操作系统通常在主核上完成内核的引导过程,然后再启动辅核。所以,对于支持热插拔的系统来说,辅核的启动和hotplug的操作是相同的,可以提供一套接口。
对于运行在单核上的可信OS,移除该核可能不可行,除非把可信OS迁移到其它核上。
PSCI提供具有下列属性的接口:
- 监控软件可以请求给一个核上电。监控软件还必须提供一个启动地址,作为它从安全固件退出时,继续执行的地方。通过提供一个入口地址,监控软件可以直接在自己的地址空间中干一些特殊的事情。为此,监控软件还必须使用内部的
per-CPU数据结构保存这些值。 - 监控软件可以请求给一个核掉电。并且还能通知更高异常级别上的软件。
- 监控软件还能请求将可信OS迁移到另一个核上。
监控软件,狭义上理解为操作系统的内核。
4.4 系统级的shutdown、reset和suspend
PSCI提供了接口,允许OS请求系统system shutdown、system reset和system suspend(suspend-to-RAM)。芯片供应商应该提供这些函数的统一实现,它们与监控软件是独立的。没有提供suspend-to-disk,这是因为它是系统关机的一种特殊情况。
这儿,system的意思是从整台机器的视角看待问题。也就是说,不是单一关闭某个核或者簇那么简单。当然,运行在虚拟机中的客户机OS,如果调用这些接口不会发生物理状态的变化。
但是,如果没有hypervisor,或者调用者是hypervisor,则会导致电源状态的物理变化。即使调用者在物理机器上运行,术语系统可能也不是指整个物理机器。例如,假设一个高级服务器系统由多个单板组成,每个单板具有一个BMC (board management controller),每个单板包含多个SoC。这样的系统可以在每个SoC上运行一个OS实例。在本例中,用于关闭系统的PSCI命令应用于单个SoC,而关闭整个单板需要通过管理接口访问BMC,而这个管理接口是调用操作系统或PSCI实现无法访问的。在本文档中,术语系统仅指对操作系统可见的机器视图。反映到本文档中,就是指一个SOC。




