D3cold 固件要求

从 Windows 8 开始,即使系统保持 S0 电源状态,设备也可以进入 D3cold 电源子状态。 本主题介绍实现嵌入式设备的 D3cold 支持的固件要求。 以下讨论旨在帮助固件开发人员使其嵌入式设备可靠地进入和退出 D3cold。

此外,还简要讨论了支持 D3cold 的设备驱动程序要求。 有关 D3cold 的设备驱动程序支持的详细信息,请参阅 驱动程序中的支持 D3cold。

介绍

设备电源状态 在 ACPI 规范和各种总线规范中定义。 PCI 总线规范自推出 PCI 电源管理以来,将 D3(关)设备电源状态拆分为两个子状态:D3hot 和 D3cold。 此区别已添加到 ACPI 3.0 中的 ACPI 规范,并在 ACPI 4.0 中扩展。 Windows 始终支持 D3 子状态,但 Windows 7 和早期版本的 Windows 仅在整个计算机退出 S0(工作)系统电源状态进入睡眠或休眠状态(通常是 S3 或 S4)时才支持 D3cold 子状态。 从 Windows 8 开始,即使系统保留在 S0 中,设备驱动程序也能允许其设备进入 D3cold 状态。

D3hot(通常称为“D3”)是设备的“软关闭”状态。 在此状态下,设备可以通过总线扫描检测到,发送到设备的命令可能导致设备再次开机。 在 D3cold 中,将删除所有电源,但可能存在少量电源以驱动设备的唤醒逻辑。 例如,对于 PCI Express(PCIe)设备,主设备电源 Vcc 在转换为 D3cold 时经常关闭。 关闭 Vcc 可以减少能耗,并延长移动硬件平台可以在电池充电时运行的时间。 当设备处于 D3cold 中时,总线扫描无法检测到该设备,并且无法接收命令。 还原 Vcc 电源会将设备移动到未初始化的状态,这通常相当于 D0 状态。 然后,软件必须重新初始化设备,使其进入工作状态。

将设备置于 D3cold 中并不一定意味着设备的所有电源都已删除,这意味着仅删除主电源 Vcc。 如果唤醒逻辑不需要辅助电源 Vaux,也可以将其删除。 但是,可能需要向处理器发出唤醒事件信号的设备才能绘制足够的电源来运行唤醒逻辑。 例如,删除主电源的以太网网络接口卡(NIC)可能会从以太网电缆中提取足够的电源。 或者,可以从 PCIe 接口外部的源提供 Wi-Fi NIC 的备用电源,在这种情况下,PCIe 接口可以完全关闭。

在以下讨论中,介绍了启用设备电源状态转换到 D3cold 的一组要求。 这些要求分为以下两类:

  • 固件和平台要求

  • 设备驱动程序要求

这两个类别中的第一个是讨论的主要焦点。 提供了第二个类别的简要概述。 有关设备驱动程序要求的详细信息,请参阅 驱动程序中的支持 D3cold。

固件和平台要求

在以下讨论中,针对这两种情况介绍了启用 D3cold 的固件和平台要求:

  • 在 ACPI 中枚举设备时。

  • 当设备由其父总线枚举时。

以下大多数讨论特定于 PCIe。 然而,此处介绍的一般原则也在很大程度上适用于其他公共汽车。

抽象化一些详细信息,将 Vcc 电源重新应用到嵌入式设备会触发从 D3cold 到 D0 的转换。 重新应用电源可有效地还原设备与总线的连接。 Windows 读取设备的标识符,以便区分以下两种情况:

  • 设备已被另一台设备删除并替换。

  • 删除了同一设备,然后重新插入。

如果标识符匹配,设备驱动程序将重新初始化设备。 如果标识符不匹配,Windows 会卸载设备驱动程序并为新设备生成新的驱动程序堆栈。 例如,PCIe 查询供应商 ID、设备 ID 和子系统 ID(这些 ID 在某些版本的规范中分为子设备和子供应商 ID)。 在重新应用电源后,这些标识符必须与以前附加的设备匹配(以及总线指定的等待期过):否则,Windows 会将新设备视为与上一个设备不同。

案例 1:ACPI 中枚举了嵌入式设备

如果嵌入式设备无法通过总线规范(如 PCIe 或 USB)定义的机制来发现,但设备已永久连接(或至少连接专用于已知设备),则 ACPI _HID和/或_CID对象可以在平台固件中描述此设备。 这些对象使设备可由 OSPM 枚举。 (“OSPM”是 ACPI 规范中定义的术语。这意味着,松散地说,“不是固件的软件”。仅当没有总线枚举器可以检测设备 ID 时,OSPM 才会枚举设备。 例如,ISA 总线上的设备由 OSPM 枚举。 此外,芯片上的系统(SoC)上的设备通常由 ACPI 枚举,因为它们位于不可枚举构造上。 此类设备的示例包括 USB 和 SD 主机控制器。

平台固件(在 ACPI 中枚举)

OSPM 使用 \_SB._OSC 将平台范围的 OSPM 功能传达给平台固件。 平台固件必须在 \_SB._OSC 返回值中设置位 2,以指示设备支持_PR3的 OSPM。 有关详细信息,请参阅 ACPI 5.0 规范中的 6.2.10.2 部分“平台范围的 OSPM 功能”。

嵌入式设备(仅通过 ACPI 发现)

为了支持 D3cold,平台固件应为嵌入式设备实现以下 ACPI 电源资源对象:

  • _PR0:此对象评估设备电源状态为 D0(完全打开)的设备电源要求。 返回值是设备需要处于 D0 状态的电源资源列表。

  • _PR2:此对象评估 D2 设备电源状态中的设备电源要求。 返回值是设备需要处于 D2 状态的电源资源列表。 请注意,出于历史原因,每当存在_PR0时,Windows 都希望_PR2存在。 如果在硬件中实现了 D2,_PR2会列出 D2 所需的电源资源。 如果未实现 D2,_PR2会列出与_PR0相同的资源。

  • _PR3:此对象评估 D3hot 设备电源状态中的设备电源要求。 返回值是设备在 D3hot 状态下所需的电源资源列表。

  • 对于任何_PRx对象中标识的每个电源资源,必须实现以下控制方法:

    • _OFF:将电源资源设置为 关闭 状态(关闭资源)。

    • _ON:将电源资源设置为 “开机 ”状态(电源资源)。

    • _STA:此对象评估为电源资源的当前 打开关闭 状态(0:关,1:打开)。

当 ACPI 对_PR3中列出的电源资源运行_OFF控制方法时,会发生转换为 D3cold。 请注意,如果设备函数驱动程序指示对 D3cold 的支持,则此支持并不意味着所有转换到 D3 都会导致快速转换为 D3cold。 设备可以进入 D3hot 并长时间留在 D3hot,然后返回 D0,而无需进入 D3cold,或稍后进入 D3cold。

父设备(ACPI 中枚举)

父设备无需能够进行电源管理。 但是,如果父设备是电源管理的,则 Windows 不会关闭此设备(如果任何子设备(依赖设备)不在 D3 中。

示例(ACPI 中枚举)

以下方块图显示了系统总线上的嵌入式设备(标记为 EMBD)。 主要电源(Vcc)和辅助电源(Vaux)可通过标记为 “电源逻辑”的块独立打开和关闭设备。

an acpi-enumerated embedded device.

以下 ASL 代码示例描述了上图中嵌入式设备使用的电源资源。 此示例以描述设备驱动程序功能的_OSC控件方法的声明开头。 接下来,将声明设备的两个电源资源-资源名称 PVCC 和 PVAX 分配给设备的主电源和辅助电源、 VccVaux。 最后,列出了设备支持的每个设备电源状态的电源资源要求,并描述了设备的唤醒功能。

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

案例 2:嵌入式设备是总线枚举的

如果嵌入式设备符合常见的总线规范(如 PCIe 或 USB),则可以通过总线定义的机制发现此设备,并且可以通过总线部分或完全通过总线提供电源。 如果此设备未由其他侧带电源资源供电,则设备的主要电源是将设备连接到父总线控制器的链接。 总线枚举设备可由嵌入式设备定义中的_ADR对象标识。 _ADR对象用于向 OSPM 提供嵌入式设备父总线上设备的地址。 此地址用于将总线的设备表示形式(由总线硬件看到)与平台的设备表示形式(如 ACPI 固件所示)。 (_ADR地址编码特定于总线。 有关详细信息,请参阅 ACPI 5.0 规范中的“_ADR(地址)”第 6.1.1 节。 使用此机制时,必须与父总线驱动程序协调 D3cold 支持。

如果嵌入式设备的主电源是将此设备连接到其父总线的链接,则将设备置于 D3cold 中的关键要求是关闭该链路。 有关转换为 D3cold 的详细信息,请参阅设备电源状态中的状态图。

平台固件(总线枚举)

OSPM 使用 \_SB._OSC 将平台范围的 OSPM 功能传达给平台固件。 平台固件必须在 \_SB._OSC 返回值中设置位 2,以指示设备支持_PR3的 OSPM。 有关详细信息,请参阅 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,请提供一个_PR3对象,其中包含子设备(嵌入式)设备对 D3hot(例如 Vcc 和 Vaux)所需的电源资源。 如果 D0、D2 和 D3hot 需要相同的电源,则_PR0、_PR2和_PR3都指定相同的电源资源。 仅当子设备进入 D3cold 时,才会关闭这些资源。

    出于历史原因,Windows 预计每当存在_PR0时,_PR2就会存在。 如果在硬件中实现了 D2,_PR2会列出 D2 所需的电源资源。 如果未实现 D2,_PR2会列出与_PR0相同的资源。

  • 实现_PR0。 父总线_PR0对象中的资源列表应包括为链接提供支持的资源,该链接将父总线连接到子设备(嵌入式)设备。

示例(总线枚举)

以下方块图中的示例硬件配置显示了为 PCIe 设备启用 D3cold 的两种不同的方式。 首先,终结点(标记 的 ENDP)连接到 PCIe 根端口(RP01),并通过 PCIe 链接从其父设备接收辅助电源。 其次, 关系图中的 HD 音频 设备没有与其父设备(已标记 PCI0 的 PCI 控制器)的标准链接,因此建模方式与 ACPI 枚举事例类似。

a bus-enumerated embedded device.

此图中的 RP01 设备具有主电源 Vcc1 和辅助电源 Vaux1。 同样,HD 音频设备具有主电源 Vcc2 和辅助电源 Vaux2

以下 ASL 代码描述了父总线控制器(PCI0)以及上图中显示的 ENDPHD 音频设备所需的电源资源。

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 文件中提供此信息。 或者,驱动程序可以在运行时调用 SetD3ColdSupport 例程,以动态启用或禁用设备的转换到 D3cold。 通过使设备能够进入 D3cold,驱动程序可以保证以下行为:

  • 当计算机保持 S0 时,设备可以容忍从 D3hot 到 D3cold 的转换。

  • 当设备从 D3cold 返回到 D0 时,设备将正常工作。

如果设备无法满足任一要求,则在计算机重启或进入睡眠状态之前,输入 D3cold 后可能不可用。 如果设备必须能够从进入的任何低功率 Dx 状态发出唤醒事件信号,则除非驱动程序确定设备的唤醒信号在 D3cold 中正常工作,否则不得启用 D3cold 条目。

有关详细信息,请参阅在驱动程序中支持 D3cold