可通过ASL声明来描述Power Resource Object, 定义如下所示:
PowerResource(PIDE, 0, 0) {
Methold(_STA){
Return (Xor (GIO.IDEI, One, Zero))
Methold(_ON){
Methold(_OFF){
Return (Xor (GIO.IDEI, One, Zero))
从上可知,上述代码声明了一个Power Resource Object PIDE,这个Power Resource Object定义了三个电源控制方法_STA/_ON/_OFF。
下面定义了几种Power Resource的控制方法,其中_ON/_OFF/_STA对每个Power Resource是必要的。_RST则用于共享Power Resource的设备的reset。
Object | Description |
---|
_OFF | Set the resource off. |
_ON | Set the resource on. |
_RST | Object that excutes a platform level reset of all devices that list this resources in there _PRR object |
_STA | Object that evaluates to the current on or off state of the power resource |
某些平台上设备和处理器之间共享Power Resource,这就要求关闭Power Resource之前让两者都进入某种低功耗状态。对于这种情况,平台可以通过LPI来管理Power Resource,OSPM可通过LPI状态来决定是否关闭Power Resource。这种情况下_STA/_ON/_OFF是多余的。
多个设备可以共享Power Resource。系统软件通过决定在ON情况下需要那些Power Resource来自动处理设备的控制,需要考虑Power Resource所连接的所有设备状态。OSPM需要保证系统OFF时Power Resource不再被任何设备引用。
另外需要满足如下规则:
- 设备的D状态不能比其父设备更深
- 如果存在设置设备D0状态,对应的Dx状态也需要被定义
- 如果控制电源的Object存在,那么至少要定义D0和D3状态
- 如果_PSx和_PRx方法都定义,那么通过_PSx支持的设备状态和_PRx支持的设备状态意思相同
设备电源管理Object
Object | Description |
---|
_PSx | Control method that puts the device in the Dx device state |
_PSC | Object that evaluates to the device’s current power state |
_PRx | Object that evaluates to the device’s power requirements in the Dx device state. |
_DSW | Control method can be used to enable or disable the device’s ability to wake a sleeping system. |
_IRC | indicates that this device can cause a significant in-rush current when transitioning to state D0 |
如下代码:
PowerResource(PWRA, 0, 0) {
Method(_ON) {...}
Method(_OFF) {...}
Method(_STA) {...}
Device (FOO) {
Name(_PR0, Package(){PWRA,PWRB,PWRC})
Name(_PR1, Package(){PWRA,PWRB})
Name(_PR3, Package(){PWRA})
如上定义设备FOO,存在D0/D1/D3状态,其中进入状态D0时要求PWRA/PWRB/PWRC三个电源都为ON,进入D1时要求PWRA/PWRB为ON,而PWRC为OFF;进入D3时仅PWRA为ON,其他都为OFF.
对于简单的电源和状态关系,同时也可以采用_PSC/_PSx来定义,比如SAS控制器只支持两种状态D0和D3cold,对其下电时未D3cold,对其上电时为D0,可定义如下:
Method(_PS3) {
Store(0x7ffffff, RST) // reset
sleep(1)
Store(0x7ffffff, ICGD) // disable clk
sleep(1)
Method(_PS0) {
Store(0x7ffffff, DRST) // de-reset
sleep(1)
Store(0x7ffffff, ICGE) // enable clk
sleep(1)
Methold(_PSC) {
// return 0 when PS0, return 4 when PS3
也可基于Power Resource进行定义:
PowerResource(PWRA, 0, 0) {
Method(_OFF) {
Store(0x7ffffff, RST) // reset
sleep(1)
Store(0x7ffffff, ICGD) // disable clk
sleep(1)
Method(_ON) {
Store(0x7ffffff, DRST) // de-reset
sleep(1)
Store(0x7ffffff, ICGE) // enable clk
sleep(1)
Method(_STA) {
// return 1 whn ON, return 0 when OFF
Device (SAS0) {
Name(_PR0, Package() {PWRA})
Name(_PR3, Package() {})
本节主要讨论PCI框架对PCIE设备的电源切换接口pci_set_power_state()流程梳理,它包括PCI相关的设置以及platform相关的设置两方面。
对于PCI相关的设置的部分,无论切换到D0还是D3COLD或其他状态,接口pci_set_power_state()调用pci_raw_set_power_state()来完成。唯一不同的是切换到D0时,先进行platform部分的设置,再进行PCI相关的设置。主要完成如下内容:
- 设置PCI电源管理相关的寄存器PCI_PM_CTRL;
- 恢复BAR寄存器pci_restore_bars();
- ASPM相关状态改变pcie_aspm_pm_state_change()
PCI相关的部分设置是否能够完成PCI设备的状态切换主要看硬件是否支持,且最多能切换到D3HOT,对于D3cold必须依赖于platform相关的设置。
对于platform相关的设置,主要通过函数pci_platform_power_transition()来完成。platform部分这里主要考虑的是ACPI部分,主要的工作是由ACPI代码实现,主要涉及代码有:
drivers/pci/pci-acpi.c
drivers/acpi/device_pm.c
drivers/acpi/power.c
函数acpi_bus_get_power_flags()对ACPI设备电源管理的能力做获取,根据BIOS中是否设置来决定电源管理能力,主要做如下:
- 填充了_PS0或_PR0至少一个才具备电源管理能力device->flags.power_manageable;
- 填充了_PSC才具备精确获取电源状态的能力device->flags.explicit_get;
- 定义了_PRx时注册对应的Power Resource;
- 定义了_PSx时具备精确设置电源状态的能力device->flags.explicit_set;
- 若定义了_PR3 表示D3cold支持;
注:所谓Dx状态所对应的Power Resource指的是对应的电源状态,如例子1.5所示D1对应电源PWRA/POWRB ON,电源PWRC OFF.
调用路径如下:
pci_platform_power_transition()
platform_pci_set_power_state()
acpi_device_set_power()
acpi_dev_pm_explicit_set()
acpi_power_transition()
最终会调用电源管理的精确设置acpi_dev_pm_explicit_set()和基于Power Resource的设置acpi_power_transition()。这两种方式至少要定义一种,对于例子1.5中,一种电源状态和多个电源之间存在关系的,需要定义Power Resource关系,对于清晰的电源状态,则可以采用精确设置方式。
电源按钮电源按钮逻辑可以用在两个模型中的一个:单按钮或双按钮。在单-按钮模型,用户按钮作为一个电源按钮,在G0之间转换系统。G2状态和一个睡眠按钮,用于转换G0和G1状态之间的系统。这个动作用户按下按钮是由软件策略或用户设置决定的。在双重-按钮模型,有单独的按钮用于睡觉和电源控制。虽然按钮仍然生成。导致软件采取行动的事件按钮的功能现在是专用的:睡眠。按钮为OSPM生成一个睡眠请求,而电源按钮会生成...
浏览器打开
本文介绍ACPICA debugger tools,acpidbg和acpidump、acpiexec等;并演示如何使用这些工具,配合initrd,在不重新加载firmware的情况下,修改ACPI table。
一、ACPICA debugger acpidbg
acpidbg是一个runtime调试AML code的工具,不过Linux kernel 4.13中才引入。
1.1 how to ...
浏览器打开
memory@memory-153:~$ cat /boot/System.map-3.16.0 | grep pci | grep __initcall
ffffffff81e5bba0 t __initcall_pcibus_class_init2
ffffffff81e5bba8 t __initcall_pci_driver_init2
ffffffff81e5bc5...
浏览器打开
一、PCI总线描述
PCI是CPU和外围设备通信的高速传输总线。普通PCI总线带宽一般为132MB/s(在32bit/33Mhz下)或者264MB/s(在32bit/66Mhz下)...
浏览器打开
ACPI 电源管理的6个状态:S0: 主机正常工作状态S1: CPU停止工作,wakeup时间为:0sS2: CPU关闭,wakeup时间为:0.1sS3: 主机中除了内存以外其他所有部件都停止工 作,wakeup时间为:0.5sS4: 主机将内存中的信息写入到硬盘中,之后关闭所有组件,wakeup时间为:30sS5: 关机
浏览器打开
ACPI (Advanced Configuration and Power Interface) 是由业界一些软硬件公司共同开发的开放式工业规范。它能使软、硬件、操作系统(OS),主机板和外围设备,依照一定的方式管理用电情况,系统硬件产生的 Hot-Plug 事件,让操作系统从用户的角度上直接支配即插即用设备,不同于以往直接通过基于 BIOS 的方式的管理。
一.ACPI 热拔插的
浏览器打开