中科院云平台架构师,专注于数字化、智能化,技术方向:云、Linux内核、AI、MES/ERP/CRM/OA、物联网、传感器、大数据、ML、微服务。
分类: 云计算
2020-09-04 12:58:35
从 Windows 8 开始,设备可以进入 D3cold 电源子状态,即使当系统处于 S0 电源状态。本主题介绍实现 D3cold 支持嵌入式设备的固件要求。下面的讨论旨在帮助固件开发人员实现其嵌入式设备可靠进入和退出 D3cold。
此外,简单讨论了支持 D3cold 的设备驱动程序要求。有关设备驱动程序支持 D3cold 的详细信息,请参阅。
在 ACPI 规范中和各种总线规范中定义。由于 PCI 总线规范引入了 PCI 电源管理,因此它已将 D3(关)设备电源状态拆分为两个子状态:D3hot 和 D3cold。这种区分已添加到 ACPI 3.0 中的 ACPI 规范,并在 ACPI 4.0 中扩展。Windows 始终支持这两个 D3 子状态,但仅当整个计算机退出 S0(工作)系统电源状态进入睡眠或休眠状态(通常 S3 或 S4)时,Windows 7 及早期版本的 Windows 才支持 D3cold 子状态。从 Windows 8 开始,即使当系统保持为 S0 状态时,设备驱动程序可以允许其设备进入 D3cold 状态。
D3hot(通常只称作“D3”)是设备的“软关闭”状态。在此状态下,总线扫描可以检测到设备,并且发送给设备的命令可能会导致它再次打开电源。在 D3cold 中,将切断所有电源,只保留少量电源以驱动设备的唤醒逻辑。例如,对于 PCI Express (PCIe) 设备,转换到 D3cold 后,经常关闭主要设备电源 Vcc。关闭 Vcc 可减少耗电量,并延长移动硬件平台在一定的电池电量下可运行的时间。当设备处在 D3cold 时,总线扫描将无法检测到该设备,并且该设备不能接收命令。恢复 Vcc 电源会将设备置于未初始化状态,通常相当于 D0 状态。然后,软件必须重新初始化该设备以将其置于工作状态。
将设备置于 D3cold 并不意味着已切断供给设备的所有电源 — 它仅表示切断了主电源 Vcc。如果唤醒逻辑不需要辅助电源 Vaux,也可能会将其切断。但是,可能需要将唤醒事件通知给处理器的设备必须能够获取足够电源,以便操作唤醒逻辑。例如,切断其主电源的以太网接口卡 (NIC) 可能从以太网电缆获取足够电源。或者,供给 Wi-Fi NIC 的待机电源可能从 PCIe 接口之外的电源提供,在这种情况下,可能会完全关闭 PCIe 接口。
在下面的讨论中,描述了实现将设备电源状态转换到 D3cold 的一组要求。这些要求分为以下两类:
这两类中的第一个类别是此次讨论的重点。将简要概述第二个类别。有关设备驱动程序要求的详细信息,请参阅。
在下面的讨论中,实现 D3cold 的固件和平台要求将针对这两种情况:
下面的大部分讨论针对 PCIe。然而,此处描述的一般原则同样在很大程度上适用于其他总线。
介绍一些细节,将 Vcc 电源重新供给嵌入式设备会触发 D3cold 转换到 D0 。重新供给电源将有效恢复设备与总线的连接。Windows 读取设备的标识符,以便区分以下两种情况:
如果标识符匹配,设备驱动程序将重新初始化设备。如果标识符不匹配,Windows 将卸载该设备驱动程序,并生成新设备的新驱动程序堆栈。例如,PCIe 查询供应商 ID、设备 ID 和子系统 ID(在某些版本的规范中,其分解成子设备和子供应商 ID)。重新供给电源(且特定于总线的等待时间到期)后,这些标识符必须匹配之前已连接设备的标识符;否则,Windows 将认为新设备不同于以前的设备。
如果由总线规范(例如 PCIe 或 USB)定义的机制未发现嵌入式设备,但已固定连接该设备(或至少该连接专用于已知设备),则此设备在平台固件中由 ACPI _HID 和/或 _CID 对象描述。这些对象使设备可以由 OSPM 进行枚举。(“OSPM”是在 ACPI 规范中定义的术语。这大致意味着“不是固件的软件”。)仅当总线枚举器未能检测到设备 ID 时,OSPM 才会枚举设备。例如,OSPM 枚举 ISA 总线上的设备。此外,系统单芯片 (SoC) 上的设备通常由 ACPI 进行枚举,因为他们处在不可枚举的结构上。此类设备的示例包括 USB 和 SD 主控制器。
平台固件
OSPM 使用 \_SB._OSC 将平台范围的 OSPM 功能传达给平台固件。平台固件必须在 \_SB._OSC 返回值中设置位 2,以向 OSPM 表明该设备支持 _PR3。有关详细信息,请参阅 ACPI 5.0 规范的第 6.2.10.2 节“平台范围的 OSPM 功能”。
嵌入式设备 – 仅可通过 ACPI 发现
若要支持 D3cold,平台固件应针对嵌入式设备实现以下 ACPI 电源对象:
_PR0:此对象对 D0(完全打开)设备电源状态中的设备电源要求求值。返回值是该设备处于 D0 状态时所需电源资源的列表。
_PR2:此对象对 D2 设备电源状态中的设备的电源要求求值。返回值是该设备处于 D2 状态时所需电源资源的列表。请注意,由于历史原因,Windows 需要 _PR2 伴随 _PR0 存在。如果 D2 在硬件中实现,则 _PR2 列出 D2 所需的电源资源。如果未实现 D2,则 _PR2 列出与 _PR0 相同的资源。
_PR3:此对象对 D3hot 设备电源状态中的设备的电源要求求值。返回值是该设备处于 D3hot 状态时所需电源资源的列表。
对于任何 _PRx 对象中标识的每个电源资源,必须实现以下控制方法:
ACPI 在 _PR3 中列出的电源资源上运行 _OFF 控制方法时,会发生到 D3cold 的转换。请注意,如果设备功能驱动程序表明支持 D3cold,此支持并不意味着所有对 D3 的转换都将导致立即转换到 D3cold。很可能该设备进入和保留在 D3hot 中一段时间,然后未曾进入 D3cold 就返回到 D0 或以后进入 D3cold。
父设备
对父设备是否可以进行电源管理没有要求。但是,如果父设备可以进行电源管理,如果任何其子设备(取决于设备)未处于 D3 中,则 Windows 从不会关闭此设备。
示例
以下框图显示系统总线上的嵌入式设备(标记为 EMBD)。供给设备的主电源 (Vcc) 和辅助电源 (Vaux) 可以通过标记为 Power logic 的块独立地打开和关闭。
以下 ASL 代码示例介绍了在前面的图中的嵌入式设备所使用的电源资源。本示例以声明描述设备驱动程序的功能的 _OSC 控制方法开始。接下来,将声明设备的两个电源资源 — 将资源名称 PVCC 和 PVAX 分配给设备的主要和辅助电源:Vcc 和 Vaux。最后,针对设备支持的每个设备电源状态列出电源资源要求,并且描述了设备的唤醒功能。
点击(此处)折叠或打开
- Scope (\_SB)
- {
- Method(_OSC, 4, NotSerialized) // Platform-wide Capabilities Check.
- {
- ... // This must indicate support for _PR3.
- }
- PowerResource(PVCC,0,0) // Power resource representing the main power for the device.
- // Required for the device to be fully functional (D0).
- {
- Name(_STA,VAR1) // Return the state of the power resource.
- Method(_ON,0x0) {...} // Turn on the power resource and set VAR1 to 1.
- Method(_OFF,0x0) {...} // Turn off the power resource and set VAR1 to 0.
- }
- PowerResource(PVAX,0,0) // Power resource representing the auxiliary power for the device.
- // Required for low-power, less-functional states (e.g., D3hot).
- {
- Name(_STA,VAR2)
- Method(_ON,0x0) {...}
- Method(_OFF,0x0) {...}
- }
- Device(EMBD) // An ACPI-enumerated device on the processor bus that supports D3Cold
- {
- Name(_HID, ...)
- ... // Other (non-power) objects for this device
- // Indicate support for D0.
- Name(_PR0, Package() {PVCC, PVAX}) // Power resources required for D0
- // Indicate support for D1 (optional)...
- // Indicate support for D2.
- Name(_PR2, Package() {PVCC, PVAX}) // If D2 is implemented in the hardware,
- // list the power resources needed by D2.
- // If D2 is not implemented, list the same
- // resources as _PR3.
- // Indicate support for D3Cold.
- Name(_PR3, Package() {PVCC, PVAX}) // Power resource for D3. These will be
- // turned off ONLY if drivers opt-in to D3cold.
- // Indicate support for wake. Required for entry into D3cold, even if the device doesn't
- // need or have a wake mechanism.
- Name(_S0W, 4) // The existence of this object indicates that the platform is
- // capable of handling wake events from this device while in S0.
- // The value of this object indicates the lowest D-state this device
- // can be in to trigger wake events that can be handled while the
- // platform is in S0.
- // Enable wake events (optional)
- // If this device actually does generate wake events, there must be a way for OSPM to
- // enable and disable them. The mechanism for this depends on the platform hardware:
- /*
- Name(_PRW, ...) // If the event is signaled via a GPE bit (SCI) OR
- // if there are power resources required only for wake.
- Name(_CRS, ...) // If the event is signaled via a wake-capable interrupt.
- Method(_DSW, 3) {...) // Can be used with either of the above, if wake enablement
- // varies depending on the target S-state and D-state.
- */
- } // End of Device EMBD
- } End Scope \_SB
如果嵌入式设备符合通用总线规范(如 PCIe 或 USB),可通过总线定义的机制发现此设备,并且可以通过总线部分或完全提供电源。如果此设备未由其他边带电源资源供电,则该设备的主电源是将该设备连接到父总线控制器的链接。可以通过嵌入式设备的定义中的 _ADR 对象标识总线枚举的设备。_ADR 对象用于将嵌入式设备的父总线上的设备地址提供给 OSPM。此地址用于将总线的设备表示形式(如总线硬件所见)关联到平台的设备表示形式(如 ACPI 固件所见)。(_ADR 地址编码是特定于总线的。有关详细信息,请参阅 ACPI 5.0 规范的第 6.1.1 节“_ADR(地址)”。)当采用这种机制时,则 D3cold 支持必须与父总线驱动程序协同使用。
如果嵌入式设备的主电源是将此设备连接到其父总线的链接,则将该设备置于 D3cold 中的关键要求是关闭该链接的电源。有关转换到 D3cold 的详细信息,请参阅中的状态图。
平台固件
OSPM 使用 \_SB._OSC 将平台范围的 OSPM 功能传达给平台固件。平台固件必须在 \_SB._OSC 返回值中设置位 2,以向 OSPM 表明该设备支持 _PR3。有关详细信息,请参阅 ACPI 5.0 规范的第 6.2.10.2 节“平台范围的 OSPM 功能”。
嵌入式设备
不需要特定于 D3cold 的 ACPI 更改。在此情况下,只要设备驱动程序和平台已表明支持 D3cold,当父总线退出 D0 并进入低功耗状态 Dx 时,可以关闭将电源提供给嵌入式设备的总线链接。当从该链接切断电源时,将发生嵌入式设备从 D3hot 到 D3cold 的转换。父总线进入的 Dx 状态可以是将会导致链接电源关闭的任何状态。
父设备
父总线的 ACPI 描述符必须执行以下操作:
实现 _S0W(Dx)。此对象将 Dx 指定为当系统处于 S0 状态时可以从其唤醒子(嵌入式)设备的最低能耗 D 状态。
定义电源资源来表示将子(嵌入式)设备连接到父总线的链接。此外,应为此电源资源定义 _ON、_OFF 和 _STA 对象。遵循此列表的 ASL 代码示例将链接电源描述为两个资源:PVC1 和 PVX1。对于每个资源,将定义 _ON、_OFF 和 _STA 对象。
如果“Dx”(最低能耗 D 状态;请参阅第一个列表项)是 D3cold,将为 D3hot(例如,Vcc 和 Vaux)提供一个包含子(嵌入式)设备所需电源资源的 _PR3 对象。如果 D0、D2 和 D3hot 需要相同的电源,那么 _PR0、_PR2 和 _PR3 全部指定相同的电源资源。仅当子设备进入 D3cold 时,才关闭这些资源。
由于历史原因,Windows 需要 _PR2 伴随 _PR0 存在。如果 D2 在硬件中实现,则 _PR2 列出 D2 所需的电源资源。如果未实现 D2,则 _PR2 列出与 _PR0 相同的资源。
实现 _PR0。用于父总线的 _PR0 对象中的资源列表应包括为将父总线连接到子(嵌入式)设备的链接提供电源的资源。
示例
以下框图中的示例硬件配置介绍了针对 PCIe 设备启用 D3cold 的两种不同方法。第一种方法,端点(标记为 ENDP)连接到 PCIe 根端口 (RP01),并通过 PCIe link 从其父设备接收辅助电源。第二种方法,该图中的 HD Audio 设备没有到其父设备的标准链接(标记为 PCI0 的 PCI 控制器),并因此类似模拟 ACPI 枚举的情况。
此图中的 RP01 设备具有主电源 Vcc1 和辅助电源 Vaux1。同样,HD Audio 设备具有主电源 Vcc2 和辅助电源 Vaux2。
以下 ASL 代码描述父总线控制器 (PCI0) 和显示于上图中的 ENDP 和 HD Audio 设备所需的电源资源。
点击(此处)折叠或打开
- Scope (\_SB)
- {
- Method(_OSC, 4, NotSerialized) // Platform-wide Capabilities Check.
- {
- ... // This must indicate support for _PR3.
- }
- PowerResource(PVC1,0,0) // Power resource representing Vcc1 for the RP01 device.
- // Required for the device(s) to be fully functional (D0).
- {
- Name(_STA,VAR0)
- Method(_ON,0x0) {...}
- Method(_OFF,0x0) {...}
- }
- PowerResource(PVX1,0,0) // Power resource representing Vaux1 for the RP01 device.
- // Required for low-power, less-functional states (e.g., D3hot).
- {
- Name(_STA,VAR1)
- Method(_ON,0x0) {...}
- Method(_OFF,0x0) {...}
- }
- PowerResource(PVC2,0,0) // Power resource representing Vcc2 for the HD device.
- // Required for the device(s) to be fully functional (D0).
- {
- Name(_STA,VAR2)
- Method(_ON,0x0) {...}
- Method(_OFF,0x0) {...}
- }
- PowerResource(PVX2,0,0) // Power resource representing Vaux2 for the HD device.
- // Required for low-power, less-functional states (e.g., D3hot).
- {
- Name(_STA,VAR3)
- Method(_ON,0x0) {...}
- Method(_OFF,0x0) {...}
- }
- ... // Power resources for other child devices
- Device(PCI0) // The PCI root complex
- {
- Name(_HID, EISAID("PNP0A08")) // ACPI enumerated
- Method(_OSC, 4, NotSerialized) // PCIe-specific Capabilities Check.
- {
- ... // This must support hand-off of PCIe control to the OS.
- }
- ... // Other (non-power) objects for this device
- Device(RP01) // PCIe Root Port 1
- {
- Name(_ADR, "...") // Bus enumerated
- ... // Other (non-power) objects for this device
- // Indicate support for D0.
- Name(_PR0, Package() {PVC1, PVX1}) // Power resources required for D0.
- // Includes the Link Power for ENDP.
- // Indicate support for D1 (optional)...
- // Indicate support for D2.
- Name(_PR2, Package(){PVC1, PVX1})
- // Indicate support for wake. Required for entry into D3cold, even if the
- // device doesn't need or have a wake mechanism.
- Name(_S0W, 4) // The existence of this object indicates the platform
- // is capable of handling wake events from this device
- // while the platform is in S0.
- // The value of this object indicates the lowest D-state
- // this device can be in to trigger wake events that
- // can be handled while the platform is in S0.
- // Enable wake events (optional)
- // If this device actually does generate wake events, there must be a way
- // for OSPM to enable and disable them. The mechanism for this depends on
- // the platform hardware:
- /*
- Name(_PRW, ...) // If the event is signaled via a GPE bit (SCI) OR
- // if there are power resources required only for wake.
- Name(_CRS, ...) // If the event is signaled via a wake-capable interrupt.
- Method(_DSW, 3) {...) // Can be used with both of the above, if wake
- // enablement varies depending on the target
- // S-state and D-state.
- */
- Device(ENDP) // This device supports D3cold. No power-related objects
- // are required.
- {
- Name(_ADR, "...") // Bus enumerated
- ... // Other (non-power) objects
- } // End of Device ENDP
- } // End of Device RP01
- Device(HD) // A PCIe Bus0 device (HD Audio) that supports D3cold. Note that
- // this case is modeled similar to the ACPI-enumerated case
- // because device HD has no standard link to its parent.
- {
- Name(_ADR, "...") // Bus enumerated
- ... // Other (non-power) objects for this device
- // Indicate support for D0.
- Name(_PR0, Package() {PVC2, PVX2}) // Power resources required for D0
- // Indicate support for D1 (optional)...
- // Indicate support for D2.
- Name(_PR2, Package(){PVC2, PVX2})
- // Indicate support for D3Cold.
- Name(_PR3, Package() {PVC2, PVX2}) // Power resource for D3; These will
- // be turned off ONLY if drivers
- // opt-in to D3cold.
- // Indicate support for wake. Required for entry into D3cold, even if the
- // device doesn't need or have a wake mechanism.
- Name(_S0W, 4) // The existence of this object indicates that the platform
- // is capable of handling wake events from this device
- // while the platform is in S0.
- // The value of this object indicates the lowest D-state
- // this device can be in to trigger wake events that can
- // be handled while the platform is in S0.
- // Enable wake events (optional).
- // If this device actually does generate wake events, there must be a way for
- // OSPM to enable and disable them. The mechanism for this depends on the HW:
- /*
- Name(_PRW, ...) // If the event is signaled via a GPE bit (SCI) OR
- // if there are power resources required only for wake.
- Name(_CRS, ...) // If the event is signaled via a wake-capable interrupt.
- Method(_DSW, 3) {...) // Can be used with both of the above, if wake
- // enablement varies depending on the target
- // S-state and D-state.
- */
- } // End Device HD
- ... // Device objects for other child devices
- } // End Device PCI0
- } // End Scope \_SB
可以结合使用前面两个示例中所示的技术以支持使用总线电源和边带电源的配置。
设备的电源策略所有者(通常是功能驱动程序)告知操作系统是否将设备从 D3hot 转换为 D3cold。驱动程序可以在安装设备的 INF 文件中提供此信息。或者,驱动程序可以调用运行时的 例程以动态启用或禁用设备到 D3cold 的转换。通过使设备进入 D3cold,驱动程序可保证以下行为:
未能满足任一要求的设备可能(进入 D3cold 后)无法使用,直到计算机重新启动,或者进入休眠状态。如果该设备必须能够从其进入任何低能耗 Dx 状态用信号通知唤醒事件,则必须禁止进入 D3cold,除非驱动程序确定该设备的唤醒信号将适用于 D3cold。
有关详细信息,请参阅。