PSCI接口规范(下)

简介: PSCI接口规范(下)

5 函数接口描述


功能接口描述。这些API描述不包含底层的SMCHVC调用。但是,这些函数却都遵守SMCCC调用规约。如果实现了EL2却没有实现EL3,则hypervisor使用HVC为运行在EL1Guest OS提供调用支持。调用格式都是一样的。PSCI函数只能由非安全空间发起调用(EL1EL2)。


5.1 PSCI_VERSION


  • 功能描述
    返回PSCI实现的版本号。
  • 参数
    uint32 Function ID: 0x8400 0000
  • 返回值
    uint32
  • [31:16]-主版本号;
  • [15:0]-次版本号;
  • 注意
    对于没有实现的PSCI函数,返回NOT_SUPPORTED


5.2 CPU_SUSPEND


  • 功能描述
    挂起CPU核或它之上的更高拓扑结构中的节点。用于空闲状态管理,期望CPU核唤醒时从之前的执行位置继续执行。
  • 参数
  • 对于powerdown请求,调用者必须保存复位重新运行时所需要的状态。也就是说保存的上下文必须是调用者在发生powerdown调用之前power_state参数所指示的电源级别(power_level字段)下所有可见的状态。(就是调用者自己保存自己的状态,被调用者不管
  • 对于掉电请求,调用者无需执行Cache或一致性操作。PSCI实现者完成(PSCI实现侧负责内存一致性)。
  • 调用者不能假设powerdown请求使用指定的entry point地址返回。因为,powerdown可能不能完成,比如因为中断挂起。也有可能因为与其它核的协调,真正进入的是浅睡眠模式(相比请求的休眠模式)。因此,PSCI实现可能将请求的powerdown状态降为standby状态。如果降为standby状态,PSCI实现返回到PSCI调用之后的指令,而不是指定的entry_point入口地址。此时,返回码也是成功的。如果发生比较早的wakeup事件,实现也是返回下一条指令,返回码也是成功的,也有可能成功的在指定的entry point地址处返回。
  • 正确的唤醒事件必须能够保证恢复到之前的状态。
  • CPU_SUSPEND调用传递的入口地址必须是调用者视角下的物理地址。
  • 上下文标识符只对调用者有意义。PSCI实现者保存,唤醒时在返回的异常级别下,再传递给CPU核,通过该值,恢复掉电前的上下文。
  • INVALID_PARAMETERS:如果发生下面的情况,就会返回该错误。
  • INVALID_ADDRESS
    如果传递的入口地址,PSCI实现者认为是非法的,就返回该值。

PSCI 1.0之前使用INVALID_PARAMETERS代替该值。

  • OS协调模式下,如果发生以下两种情况,就会返回DENIED
    OS协调模式下,如果系统的状态和请求状态不一致,会返回INVALID_PARAMETERS,不同之处在于:
  • 为高于电源级别的拓扑节点请求低功耗电源状态
  • 该节点中至少一个子节点与请求的电源状态不兼容(比如,一个核发起请求,将系统级节点置于powerdown状态,但是,该系统节点中的另一个核处于retention状态时,就会返回参数错误。)
  • 提供的power_state参数不正确。预期是与平台固件表(如ACPIFDT一致)
  • 在OS协调模式下,发生以下两种条件时,也会返回参数错误:
  • DENIED情况中,不一致的核必须运行中。错误会出现在调用者和实现者两侧。
  • INVALID_PARAMETERS情况中,不一致的节点必须处于低功耗状态,不一致只能通过调用者(OS)的错误产生。
  • 为高于电源级别的拓扑节点请求低功耗电源状态
  • 所有与请求不一致的核必须处于运行中,而不是低功耗状态
  • 原始格式
    PSCI 1.0之前的版本支持的形式。当使用这种格式时,PSCI_FEATURES使用CPU_SUSPEND功能ID返回的标志字段的bit[1]位被设置为0
    各比特位的意义:


位域 描述
31:26 保留,必须是0
25:24 PowerLevel
23:17 保留,必须是0
16 StateType
15:0 StateID
  • 扩展StateID
    对于一个硬件平台,支持每个核、簇或整个系统固定组合状态。这些状态产生了一组合法的power_state值。这些状态应该通过固件表(如ACPIFDT)表示给OSPM。为此,PSCI 1.0引入了一个新的扩展StateID格式。这种格式对于PSCI的实现者来说更为灵活,方便开发者实现PSCI,可以通过ACPIFDT电源状态的描述进行改进。这样的情况下,原先的格式有些字段就多余了。
    使用这种格式的时候,PSCI_FEATURES函数的返回标志中的bit[1]会被设为1(传递CPU_SUSPEND功能ID)。

注意:一种实现中不可能混用这两种格式。

  • 下表是power_state参数的位域(扩展StateID格式)。


位域 描述
31 保留,必须是0
30 StateType
29:28 保留,必须是0
27:0 StateID
  • 推荐的编码格式:参考前面。
    StateID示例编码
  • 0,表示standbyretention状态;
  • 1,表示powerdown状态。另外,还说明entry_point_addresscontext_id的值合法;
  • Level 0: 核
  • Level 1: 簇
  • Level 2: 系统
  • PowerLevel,定义的电源域级别,也就是表示是核,簇还是系统层电源请求。

PSCI 1.0之前的版本称为AffinityLevel

  • 但是电源域级别的命名,却是实现者定义的。一般情况下,按照如下方式命名:
  • StateType:状态类型
  • StateID:状态ID
    对请求的组合电源状态进行标识。一般是实现者定义的。在OS协调模式下,StateID必须能够表示哪个核是最后一个进入idle状态的。
    这些信息必须体现在FDTACPI固件表中,以便在请求电源状态时,将这些信息添加到StateID字段中。推荐编码格式可以参考第6.5小节。


位域 描述
15:12 核是电源等级中的最后一个
• 0: Core Level
• 1: Cluster Level
• 2: System Level
11:8 系统级局部电源状态:
• 0: Run
• 2: Retention
• 3: Powerdown
7:4 簇级局部电源状态:
• 0: Run
• 2: Retention
• 3: Powerdown
3:0 核级局部电源状态:
• 0: Run
• 1: standby
• 2: Retention
• 3: Powerdown
  • 0x8400 0001-SMC32版本
  • 0xC400 0001-SMC64版本
  • uint32 Function ID:
  • uint32 power_state
    PSCI 1.0开始,支持两种格式。
  • entry_point_address
    唤醒时,程序继续执行的起始地址。可以是PA(物理地址)或IPA(中间物理地址)。
  • context_id
    该参数只对调用者有用。PSCI实现者只需保留一下该参数的备份即可。从掉电状态唤醒时,PSCI将该值写入到R0W0X0通用寄存器中,进入异常的程序会通过该寄存器将保存的上下文内容恢复。
  • 调用者的责任
    在发起CPU_SUSPEND调用之前,非安全空间必须遵守以下规则:
    调用者必须处理可能的错误码:
  • PSCI实现者的责任:状态协调
    平台协调者模式中,调用者通过power_state参数传递的指定进入的电源状态,在语义上不是强制的。相反,它代表的是调用者容忍的最深的电源状态。此种情况下,是通过PSCI实现真正进入的电源状态。为此,如果一个核没有调用CPU_ON而上电,或者调用了CPU_OFF而关闭的情况下,假定该核进入了最深的电源状态。
    而在OS协调模式中,调用者显式请求某个特定的电源状态,而不是让PSCI实现决定。实现必须遵循请求,除非与实现当前的状态不一致。
  • PSCI实现者的责任:与可信OS或PF进行交互
    PSCI实现必须能够与可信OS或SP进行通信。交互方法请参考ARMv8-AFirmware Framework
    因为某些原因,可信OS或SP可能不兼容某种特殊的状态。这种情况下,ARM建议:可信OS或SP使用自定义的机制与非安全空间通信,保证它的限制可以被非安全空间的代码考虑。
  • PSCI实现者的责任:Cache和内存一致性管理
    Powerdown状态要求清除Cache。PSCI实现者必须在掉电一个节点之前,为该节点中所有的Cache和正在最后关闭的那个核执行清除操作。另外,PSCI实现还需要在启动阶段执行对Cache的失效操作,除非这是硬件能够自动完成的。在相关处理器和互连IP的技术参考手册中可以看到,上电或掉电应该遵守的顺序。
  • PSCI实现者的责任:返回状态
    当从standby状态返回时,对于调用者来说,CPU核的状态应该没有变化,除了定时器和由于唤醒中断造成的CPU interface的变化之外。对于核来说,standby状态和使用WFI指令没有什么不同。唯一的不同就是,调用SMC指令造成的寄存器变化。R0W0返回的值是错误码。对于standby状态,成功时返回SUCCESS。对于powerdown状态,如果成功不会返回,因为唤醒时,从传递的入口地址处开始执行。如果不成功,返回错误码,表明错误原因。
  • 返回值
    int32
  • SUCCESS;
  • INVALID_PARAMETERS;
  • INVALID_ADDRESS;
  • DENIED;
  • 注意
    对于没有实现的PSCI函数,返回NOT_SUPPORTED

5.3 CPU_OFF


  • 功能描述
    关闭核。用于hotplug。只能使用CPU_ON调用重新开启一个核。
  • 参数
  • 0x8400 0002
  • uint32 Function ID:
  • 返回值
    int32:成功不会返回;否则返回DENIED

5.4 CPU_ON


  • 功能描述
    启动一个核。有两种情况:(1)启动阶段时调用;(2)该核之前被CPU_OFF关闭。
  • 参数
  • [24:31]: 必须是0
  • [16:23]: 匹配MPIDR.Aff2位域
  • [8:15]:  匹配MPIDR.Aff1位域
  • [0:7]:   匹配MPIDR.Aff0位域
  • [40:63]: 必须是0
  • [32:39]: 匹配MPIDR.Aff3位域
  • [24:31]: 必须是0
  • [16:23]: 匹配MPIDR.Aff2位域
  • [8:15]:  匹配MPIDR.Aff1位域
  • [0:7]:   匹配MPIDR.Aff0位域
  • 0x8400 0003-SMC32版本
  • 0xC400 0003-SMC64版本
  • uint32 Function ID: 功能ID
  • uint32/uint64 target_cpu:目标核
    MPIDR寄存器的备份。如果是AArch32
    如果是AArch64
  • uint32/uint64 entry_point_address:入口地址
    当核返回到非安全异常级时必须执行的地址。SMC64版本时,是64位的物理地址或中间物理地址;SMC32版本时,是32位的物理地址或中间物理地址;
  • uint32/uint64 context_id:上下文地址
    当核返回到非安全异常级时:SMC64版本时,该值必须保存在X0寄存器;SMC32版本时,该值必须保存在R0寄存器。需要把该地址的上下文内容恢复(堆栈、执行状态、中断状态等)。
  • 返回值
    int32
  • SUCCESS,成功则返回该值;
  • INVALID_PARAMETERS,描述了一个无效的MPIDR
  • INVALID_ADDRESSATF认为传递进来的入口地址非法;
  • ALREADY_ONATF认为该核已经启动;
  • ON_PENDING,已经发起了CPU_ON请求,ATF还未处理;
  • INTERNAL_FAILURE,因为物理原因,不能启动CPU核。

5.5 AFFINITY_INFO


  • 功能描述
    请求某个亲和力等级上的信息。
  • 参数
  • 0target_affinity中的所有位域都是有效的。在不支持硬件线程化的处理器系统中,target_affinity将会表示单个核。
  • 1:表示target_affinity中,忽略Aff0位域。target_affinity表示亲和力等级为1的处理单元。
  • 2:表示target_affinity中,忽略Aff0Aff1位域。target_affinity表示亲和力等级为2的处理单元。
  • 3:表示target_affinity中,忽略Aff0Aff1Aff2位域。target_affinity表示亲和力等级为3的处理单元。
  • 0x8400 0004-SMC32版本
  • 0xC400 0004-SMC64版本
  • uint32 Function ID:
  • target_affinity
    CPU_ONtarget_cpu参数格式一样。(SMC32SMC64
  • lowest_affinity_level
    表示target_affinity参数中有效的最低亲和力级别。该参数允许AFFINITY_INFO调用者请求大于0的亲和力等级的信息。
    可能的值:
    PSCI 1.0版本开始,AFFINITY_INFO不再需要支持高于0的亲和级别。
  • 返回值
    int32
  • 2 ON_PENDING,亲和力对象正在转换为ON状态的过程中;
  • 1 OFF,亲和力对象中,所有核都关闭;
  • 0 ON,亲和力对象中,至少有一个核开启;
  • INVALID_PARAMETERSPSCI 1.0以上,请求亲和力值大于0的请求会返回该值);
  • DISABLED,由于物理原因禁止。

5.6 MIGRATE


  • 功能描述
    (可选的)请求将可信OS迁移到另一个核上。
  • 参数
  • 0x8400 0005-SMC32版本
  • 0xC400 0005-SMC64版本
  • uint32 Function ID:
  • target_cpu
    CPU_ON调用的target_cpu参数一样。
  • 返回值
    int32
  • SUCCESS,成功则返回该值;
  • NOT_SUPPORTED,不支持该功能,或不需要迁移;
  • INVALID_PARAMETERS,描述了一个无效的MPIDR
  • DENIED,可信OS启动,但是不可迁移;
  • INTERNAL_FAILURE,因为物理原因,不能迁移;
  • NOT_PRESENT,可信OS不在请求的核上。

5.7 MIGRATE_INFO_TYPE


  • 功能描述
    (可选的)请求可信OS支持多核的情况。
  • 参数
  • 0x8400 0006
  • uint32 Function ID:
  • 返回值
    int32
  • 0 支持单核迁移的可信OS。可信OS只能运行在一个核上。可信OS支持迁移功能,可以被迁移到任意一个核上。如果尝试对运行可信OS的核调用CPU_OFF,请求会被拒绝(DENIED)。
  • 1 不支持单核迁移的可信OS。可信OS只能运行在一个核上。可信OS不支持迁移功能。调用MIGRATE会被拒绝。
  • 2 可信OS既不存在、也不需要迁移。这类系统不要求调用者使用MIGRATE功能。如果硬要调用,返回NOT_SUPPORTED
  • NOT_SUPPORTED 调用操作系统可以认为等价于返回值为2的情况。

5.8 MIGRATE_INFO_UP_CPU


  • 功能描述
    (可选的)返回单核可信OS所在的核。
  • 参数
  • 0x8400 0007-SMC32版本
  • 0xC400 0007-SMC64版本
  • uint32 Function ID:
  • 返回值
    可能是32位或64位:
  • UNDEFINED:如果 MIGRATE_INFO_TYPE调用返回2NOT_SUPPORTED
  • 基于MPIDR的值:格式与CPU_ON调用中的target_cpu参数一样。

5.9 SYSTEM_OFF


  • 功能描述
    关闭系统。
    SYSTEM_OFF提供了一个系统关闭的接口。在调用该接口之前,调用者必须将所有的核置于已知状态。调用也只能是由非安全空间发起。一旦发起该调用,PSCI实现将会完全关闭最高等级的电源(也就是系统电源)。
    启动必须是冷启动。
  • 参数
  • 0x8400 0008
  • uint32 Function ID:
  • 返回值
    不需要返回。

5.10 SYSTEM_RESET


  • 功能描述
    提供系统冷复位的方法。
  • 参数
  • 0x8400 0009
  • uint32 Function ID:
  • 返回值
    不需要返回。

5.11 SYSTEM_RESET2


  • 功能描述
    (可选)对SYSTEM_RESET的扩展,PSCI 1.1引入。提供:
  • 架构相关的reset方法
  • 供应商提供的reset方法
  • 参数
  • Bit[31],保留的话就必须为0.
  • Bits[30:0]
  • 设为1,则使用供应商提供的reset方法;
  • 设为0,则为架构提供的reset方法;
  • 0x0SYSTEM_WARM_RESET.
  • 其它值保留.
  • 对于供应商提供的reset方法,这些位的意义由供应商定义。
  • 对于架构提供的reset方法,定义如下:
  • 0x8400 0012-SMC32版本
  • 0xC400 0012-SMC64版本
  • uint32 Function ID:
  • reset_type
    32位值,被分为两部分:
  • cookie
    32位或64位值。用来传递额外的reset信息。
  • 返回值
    int32
  • SUCCESS,成功不返回
  • NOT_SUPPORTED
  • INVALID_PARAMETERS

5.12 MEM_PROTECT


  • 功能描述
    (可选)通过在将内存移交给操作系统加载程序之前,重写这段内存,来提供针对冷重启攻击的保护。PSCI 1.1引入
  • 参数
  • 0x8400 0013
  • uint32 Function ID:
  • enable
    32位值,非0值表示内存保护被启动。0值表示禁止保护功能。
  • 返回值
    int32
  • 成功,则返回之前的使能状态:0,表示之前是被禁止的;1,表示之前是使能的。
  • 失败,则返回NOT_SUPPORTED

5.13 MEM_PROTECT_CHECK_RANGE


  • 功能描述
    (可选)可以检查某段内存是否被MEM_PROTECT保护。PSCI 1.1引入
  • 参数
  • 0x8400 0014-SMC32版本
  • 0xC400 0014-SMC64版本
  • uint32 Function ID:
  • uint32/64 base
    要检查的内存的基地址;
  • uint32/64 length
    要检查的内存的长度;
  • 返回值
    int32
  • SUCCESS
  • DENIED
  • NOT_SUPPORTED

5.14 PSCI_FEATURES


  • 功能描述
    查询SMCCC_VERSION或者某个PSCI功能是否被实现。PSCI 1.0引入
  • 参数
  • 0x8400 000A
  • uint32 Function ID:
  • psci_func_id
    功能ID:PSCISMCCC_VERSION
  • 返回值
    如果功能实现,则意义如下:
psci_func_id 标志位 描述
CPU_SUSPEND功能ID [31:2] 保留,等于0

[1] 0power_state使用原始格式(PSCI 2.0)
1power_state新的扩展StateID格式

[0] 0,不支持OS协调方式
1,支持OS协调方式
其它功能ID [31:0] 保留都是0


5.15 CPU_FREEZE


  • 功能描述
    (可选)将核置于供应商自定义的低功耗状态中。与CPU_OFF不同,中断仍然可以传递给该核。但是,该核一直会处于低功耗状态中,直到CPU_ON调用将其启动。PSCI 1.0引入
  • 参数
  • 0x8400 000B
  • uint32 Function ID:
  • 返回值
    int32
  • 成功,不返回。
  • 失败,则返回NOT_SUPPORTEDDENIED

5.16 CPU_DEFAULT_SUSPEND


  • 功能描述
    (可选)将核置于供应商自定义的低功耗状态中。与CPU_SUSPEND不同的是,不需要指定power_state参数。PSCI 1.0引入
  • 参数
  • 0x8400 000C-SMC32版本
  • 0xC400 000C-SMC64版本
  • uint32 Function ID:
  • entry_point_address
    参考CPU_SUSPEND
  • context_id
    参考CPU_SUSPEND
  • 返回值
    int32
  • SUCCESS
  • INVALID_ADDRESS

5.17 NODE_HW_STATE


  • 功能描述
    (可选)返回系统的电源域拓扑结构中一个节点的硬件状态。PSCI 1.0引入
  • 参数
  • 0x8400 000D-SMC32版本
  • 0xC400 000D-SMC64版本
  • uint32 Function ID:
  • target_cpu
    参考CPU_ON
  • power_level
    表示想要请求的节点,在电源域拓扑结构的层级。这是供应商自定义的,但是0保留给CPU核。
  • 返回值
    int32
  • 2 HW_STANDBY:返回2,表示处于standbyretention电源状态;
  • 1 HW_OFF:返回1,表示处于powerdown状态;
  • 0 HW_ON:返回0,表示处于run状态;
  • NOT_SUPPORTED
  • INVALID_PARAMETERS

5.18 SYSTEM_SUSPEND


  • 功能描述
    语义等价于CPU_SUSPEND,将系统置于最低功耗状态。该调用是实现system suspend-to-RAM的基础(ACPI规范中描述的S2和S3状态)。值得注意的是,系统进入S2或S3状态,需要几个前提条件。系统中所有设备必须与进入该系统挂起状态兼容,可能需要在调用之前,优雅地处理各个外设。这些前提条件不在本文的讨论范围内。SYSTEM_SUSPEND仅限于提供进入S2或S3状态的机制,所有必要的条件都由调用OS满足。尽管ACPI将suspend-to-RAM功能分为S2S3两种状态,但是PSCI只提供了一个API。
    SYSTEM_SHUTDOWNSYSTEM_RESET一样,该函数适用于调用OS的机器视角。
    为了使用该函数调用,调用者必须使用CPU_OFF关闭所有的核,但保留一个核。剩下的这个核调用SYSTEM_SUSPEND,传递entry_point_addresscontext_id参数(唤醒时用),进入挂起状态。调用者(OS)可以在调用SYSTEM_SUSPEND之前,使用AFFINITY_INFO函数保证所有其它核都已关闭。
  • 参数
  • 0x8400 000E-SMC32版本
  • 0xC400 000E-SMC64版本
  • uint32 Function ID:
  • entry_point_address:参考CPU_SUSPEND
  • context_id:参考CPU_SUSPEND
  • 返回值
    返回32位值。
  • NOT_SUPPORTED
  • INVALID_ADDRESS
  • ALREADY_ON
  • 成功不会返回;
  • 失败则返回:


5.19 PSCI_SET_SUSPEND_MODE


  • 功能描述
    (可选)设置电源状态协调方式。PSCI 1.0引入
  • 参数
  • 0: 平台协调方式
  • 1: OS协调方式
  • 0x8400 000F
  • uint32 Function ID:
  • mode
  • 返回值
    int32
  • SUCCESS
  • NOT_SUPPORTED
  • INVALID_PARAMETERS
  • DENIED


5.20 PSCI_STAT_RESIDENCY


  • 功能描述
    (可选)返回冷启动之后,在某种状态下的度过时间。PSCI 1.0引入
  • 参数
  • 0x8400 0010-SMC32版本
  • 0xC400 0010-SMC64版本
  • uint32 Function ID:
  • target_cpu
    格式与CPU_ON调用相同;
  • power_state
    指定的电源状态。
  • 返回值
    可能是32位或64位。返回处于指定电源状态的时间。


5.21 PSCI_STAT_COUNT


  • 功能描述
    (可选)返回冷启动之后,进入某种状态下的次数。PSCI 1.0引入
  • 参数
  • 0x8400 0010-SMC32版本
  • 0xC400 0010-SMC64版本
  • uint32 Function ID:
  • target_cpu
    格式与CPU_ON调用相同;
  • power_state
    指定的电源状态。
  • 返回值
    可能是32位或64位。进入某种状态下的次数。


5.22 错误码


定义
SUCCESS 0
NOT_SUPPORTED -1
INVALID_PARAMETERS -2
DENIED -3
ALREADY_ON -4
ON_PENDING -5
INTERNAL_FAILURE -6
NOT_PRESENT -7
DISABLED -8
INVALID_ADDRESS -9


6 其它实现细节


6.1 PSCI调用流程


6.1.1 CPU_SUSPEND、CPU_DEFAULT_SUSPEND和SYSTEM_SUSPEND调用流程


640.png


6.1.2 CPU_OFF调用流程

640.png



6.1.3 CPU_ON调用流程

640.png


相关文章
|
8月前
|
SQL 前端开发 安全
详细介绍前后端分离必备的接口规范,包括命名规范、参数规范、错误处理规范等
详细介绍前后端分离必备的接口规范,包括命名规范、参数规范、错误处理规范等
1651 1
|
22天前
|
Java 数据处理
接口设计规范
接口设计规范
34 2
|
6月前
|
安全 API 数据安全/隐私保护
API 接口设计规范
API 接口设计规范
298 0
|
11月前
|
程序员
代码的规范
代码的规范
126 0
|
机器学习/深度学习 XML SQL
|
存储 JSON NoSQL
|
Go 开发工具 git
一文掌握 godoc的使用与规范
一文掌握 godoc的使用与规范
828 0
|
监控 安全 Linux
|
JSON 前端开发 JavaScript
前后端分离的接口规范
前后端分离的接口规范
前后端分离的接口规范
|
前端开发 JavaScript 算法
大漠:我认识的 W3C 规范
在接到邀请在团队分享有关于与 W3C 规范相关的话题时,就我个人而言还是很虚的。虽然从事 Web 前端开发已有近十年,接触 W3C 规范也有多年,但要出来聊与 W3C 规范相关话题,还是没有足够多的信心。在开始写 PPT 之前,我特意咨询了好好友 @小倩 小姐姐,并且参考了她分享的《走进W3C》。虽然对 W3C 没有全面的认识,但我还是想从我个人的角度来看和思考 W3C 规范。希望接下来的分享对初次接触 W3C 或想深入 W3C 的同学有所帮助。
350 0
大漠:我认识的 W3C 规范