电源按钮

2019-07-13 22:15发布

电源按钮电源按钮逻辑可以用在两个模型中的一个:单按钮或双按钮在单-按钮模型用户按钮作为一个电源按钮G0之间转换系统
G2状态和一个睡眠按钮用于转换G0G1状态之间的系统这个动作
用户按下按钮是由软件策略或用户设置决定的在双重-按钮模型有单独的按钮用于睡觉和电源控制虽然按钮仍然生成导致软件采取行动的事件按钮的功能现在是专用的:睡眠
按钮为OSPM生成一个睡眠请求而电源按钮会生成一个唤醒请求 对电源按钮的支持是由PWR_BUTTON标志和电源按钮组合而成的
设备对象如下所示:  电源按钮支持电源按钮还可以有额外的能力无条件地从a过渡到系统
将工作状态挂在G2软关闭状态OSPM事件处理程序不再能够使用的情况下
响应电源按钮事件电源按钮覆盖功能提供一个备份机制
无条件地将系统过渡到软关闭状态 这个功能可以在平台上使用
没有机械关闭按钮也可以提供这个功能。ACPI定义了持有
电源按钮激活4秒或更长的时间将产生一个电源按钮覆盖事件 固定电源按钮固定硬件电源按钮在PM1x_EVT_BLK中有其事件编程模型这个逻辑由单一的启用位和粘性状态位组成当用户按下电源按钮时电源按钮状态位(PWRBTN_STS)是无条件设置的如果电源按钮启用位(PWRBTN_EN)。
设置和电源按钮状态位设置(PWRBTN_STS)由于一个按钮按下系统在
G0状态然后生成一个SCI。OSPM通过清除PWRBTN_STS位来响应事件电源按钮逻辑提供了一个debounce逻辑它将PWRBTN_STS位设置在按钮按边缘 当系统处于G1G2全局状态(S1、S2、S3、S4S5状态)任何进一步的电源按钮
按下按钮按下系统进入休眠状态时无条件设置电源按钮状态位并唤醒系统无论电源按钮启用位值多少。OSPM通过清除电源按钮状态位和唤醒系统来响应 控制方法电源按钮power按钮编程模型也可以使用通用硬件编程模型这允许power按钮驻留在任何通用硬件地址空间(例如嵌入式控制器)而不是固定的空间如果电源按钮是使用通用的硬件然后OEM需要将power按钮定义为带有_HID对象值的设备
“PNP0C0C”,然后将该设备标识为OSPM的电源按钮然后是AML事件处理程序
生成一个Notify命令通知OSPM一个电源按钮事件生成而系统在工作状态下电源按钮按下是用户请求将系统转换为睡眠(G1)或软化状态(G2)。在这些情况下,power按钮事件处理程序会发出通知
命令与设备特定代码0x80。这指示OSPM将控制权传递给power。
按钮驱动程序(PNP0C0C),其知识是请求从G0状态过渡
在从G1休眠状态中醒来时,AML事件处理程序会生成一个带有代码的notify命令
0x2表明它负责唤醒系统 power按钮设备需要在平台的ACPI名称空间中声明为一个设备
只需要一个_HID。定义一个例子这个示例ASL代码执行以下操作:·  创建一个名为“PWRB”的设备并将插入和播放标识符(通过_HID对象)“PNP0C0C”关联·  该插件和播放标识符将这个设备对象与power按钮驱动程序关联起来·  为控制方法电源按钮的编程模型创建一个操作区域:
  系统I/O空间在0x200。·  未被访问的字段被写为0。这些状态在写11的时候就清楚了
  因此在这种情况下它们的位位置会失败·  在操作区域内为power按钮状态位(称为PBP)创建一个字段  在这个情况下,power按钮状态位是通用事件状态位0的子元素  当这个位是设置的它是asl代码的职责来清除它(OSPM清除通用状态位)。  状态位的地址是0x200.0(地址0x200的位0)。·  power按钮尾流事件创建一个名为PBW的附加状态位  这是下一个位和它的物理地址是0x200.1(地址0x200的位1)。·  为连接到一般的位0的电源按钮生成一个事件处理程序
  目的事件状态寄存器0。事件处理程序执行以下操作:·  在硬件中清除电源按钮状态位(写入一个到它)。·  通过调用传递电源按钮对象的Notify命令通知事件的OSPM。
  以及设备特定的事件指示器0x80 // 定义一个控制方法电源按钮 Device(\_SB.PWRB){     Name(_HID, EISAID(“PNP0C0C”))     Name(_PRW, Package(){0, 0x4}) OperationRegion(PHO, SystemIO, 0x200, 0x1)     Field(PHO, ByteAcc, NoLock, WriteAsZeros){         PBP, 1,     // 睡眠/断开请求         PBW, 1     // 睡眠请求     } } // 结束电源按钮设备对象 Scope(\_GPE){ // 根级别事件处理     Method(_L00){ // 使用 GP0_STS 寄存器的位0         If(PBP){             Store(One, PBP) // 清除电源按钮状态             Notify(\_SB.PWRB, 0x80) // 通知系统事件 }         If(PBW){             Store(One, PBW)             Notify(\_SB.PWRB, 0x2)         }     } // 结束_L00 处理 } // 结束\_GPE scope
电源按钮强制关闭ACPI规范还允许如果用户在系统处于工作状态时按下电源按钮超过4就会生成一个硬件事件系统将过渡到软关闭状态这个硬件事件被称为电源按钮覆盖在对电源按钮覆盖事件的反应中硬件清除了电源按钮状态位(PWRBTN_STS)。 睡眠按钮当使用两个按钮模型时,ACPI支持第二个按钮当按下时将请求OSPM转换G0工作和G1睡眠状态之间的平台对睡眠按钮的支持是由SLEEP_BUTTON标记和sleep按钮设备对象的组合来表示的 睡眠按钮支持 固定硬件睡眠按钮固定的硬件睡眠按钮在PM1x_EVT_BLK中有它的事件编程模型该逻辑由一个单独的启用位和粘性状态位组成当用户按下睡眠按钮时按钮状态位(SLPBTN_STS)是无条件设置的此外如果睡眠按钮启用位(SLPBTN_EN)设置睡眠按钮状态位设置为(SLPBTN_STS由于按钮按下)而系统处于G0状态则生成SCI。OSPM通过清除SLPBTN_STS位来响应事件睡眠按钮逻辑提供了一种排除逻辑SLPBTN_STS位设置在按钮按边缘 在系统是睡觉时(S0,S1,S2,S3S4状态)任何进一步的睡眠按钮按下按钮按下后(导致系统进入睡眠状态)设置睡眠按钮状态位(SLPBTN_STS)和唤醒系统如果已经设置了SLP_EN。OSPM响应通过清算睡眠按钮状态和唤醒系统  控制方法睡眠按钮睡眠按钮编程模型也可以使用通用硬件编程模型这允许sleep按钮驻留在任何通用硬件地址空间(例如嵌入式控制器),而不是固定的空间如果sleep按钮是通过通用硬件实现的 那么OEM需要将sleep按钮定义为带有“PNP0C0E”_HID对象值的设备然后将该设备标识为OSPMsleep按钮然后,AML事件处理程序生成一个Notify命令通知OSPM一个睡眠按钮事件生成在工作状态下睡眠按钮按下是用户请求将系统转换为睡眠(G1)状态在这些情况下睡眠按钮事件处理程序会用设备特定的0x80代码发出通知命令这将指示OSPM将控制传递给睡眠按钮驱动程序(PNP0C0E),并知道用户正在请求从G0状态转换当从G1休眠状态中唤醒时,AML事件处理程序将生成一个带有tNotify命令并使用0x2的代码表示它负责唤醒系统 sleep按钮设备需要在平台的ACPI名称空间中声明为一个设备并且只需要一个_HID。下面显示了一个示例定义 AML代码如下:·  创一个名为“SLPB”的设备并将“PNP0C0E”的插入和播放标识符通过_HID对象关联起来·  插入和播放标识符将这个设备对象与睡眠按钮驱动程序关联起来·  创建一个操作区域用于控制方法sleep button的编程模型:System I/O空间在0x201·  未被访问的字段被写为“1s”(这些状态位在写“1”到它们的位置时很清楚因此在这种情况下保存会失败)。·  在操作区域内为睡眠按钮状态位称为PBP)创建一个字段当这个位被设置时,AML代码的职责就是清除它(OSPM清除了通用的状态位)。     状态位的地址是0x201.0(地址0x2010)·  sleep按钮唤醒事件创建一个名为PBW的附加状态位    这是下一个比特它的物理地址是0x201.1(地址0x201的位1)。 ·  为睡眠按钮生成一个事件处理程序该事件处理程序连接到通用状态寄存器0的位0。事件处理程序执行以下操作:·  在硬件中清除睡眠按钮状态位(写一个“1”到它)。·  通过调用Notify命令传递睡眠按钮对象和设备特定的事件指示器0x80,通知事件OSPM。// 定义一个控制方法睡眠按钮 Device(\_SB.SLPB){ Name(_HID, EISAID("PNP0C0E")) Name(_PRW, Package(){0x01, 0x04}) OperationRegion(Boo, SystemIO, 0x201, 0x1) Field(Boo, ByteAcc, Nolock, WriteAsZeros){ SBP, 1, //睡眠请求 SBW, 1 //唤醒请求 } } //结束电源按钮设备对象 Scope(\_GPE){ //根级别事件处理程序 Method(_L01){ //使用GP0_STS寄存器的位1 If(SBP){ Store(One, SBP) //清除睡眠按钮状态 Notify(\_SB.SLPB, 0x80) //通知操作系统事件 } If(SBW){ Store(One, SBW) Notify(\_SB.SLPB, 0x2) } } //结束 _L01 handler } //结束 \_GPE scope