ACPI 中文文档ACPI 中文文档
首页
第 1 章
第 2 章
第 3 章
第 4 章
第 5 章
第 6 章
第 7 章
第 8 章
第 9 章
第 10 章
第 11 章
第 12 章
第 13 章
第 14 章
第 15 章
第 16 章
第 17 章
第 18 章
第 19 章
第 20 章
第 21 章
附录 A
首页
第 1 章
第 2 章
第 3 章
第 4 章
第 5 章
第 6 章
第 7 章
第 8 章
第 9 章
第 10 章
第 11 章
第 12 章
第 13 章
第 14 章
第 15 章
第 16 章
第 17 章
第 18 章
第 19 章
第 20 章
第 21 章
附录 A
  • 第 5 章

    • 总览
    • 5.1. 系统描述表架构概述
    • 5.2. ACPI 系统描述表
      • 5.2.1. 保留位和字段
      • 5.2.2. 兼容性
      • 5.2.3. 地址格式
      • 5.2.4. 通用唯一标识符 (UUID)
      • 5.2.5. 根系统描述指针 (RSDP)
      • 5.2.6. 系统描述表头
      • 5.2.7. 根系统描述表 (RSDT)
      • 5.2.8. 扩展系统描述表 (XSDT)
      • 5.2.9. 固定 ACPI 描述表 (FADT)
      • 5.2.10. 固件 ACPI 控制结构 (FACS)
      • 5.2.11. 定义块
      • 5.2.12. 多个APIC描述表(MADT)
      • 5.2.13. 全局系统中断
      • 5.2.14. 智能电池表 (SBST)
      • 5.2.15. 嵌入式控制器启动资源表 (ECDT)
      • 5.2.16. 系统资源关联表 (SRAT)
      • 5.2.17. 系统局部性信息表 (SLIT)
      • 5.2.18. 更正平台错误轮询表 (CPEP)
      • 5.2.19. 最大系统特性表 (MSCT)
      • 5.2.20. ACPI RAS 功能表 (RASF)
      • 5.2.21. 内存电源状态表 (MPST)
      • 5.2.22. 启动图形资源表 (BGRT)
      • 5.2.23. 固件性能数据表 (FPDT)
      • 5.2.24. 通用定时器描述表 (GTDT)
      • 5.2.25. NVDIMM 固件接口表 (NFIT)
      • 5.2.26. 安全设备 (SDEV) ACPI 表
      • 5.2.27. 异构内存属性表(HMAT)
      • 5.2.28. 平台调试触发器表 (PDTT)
      • 5.2.29. 处理器属性拓扑表 (PPTT)
      • 5.2.30. 平台健康评估表 (PHAT)
    • 5.3. ACPI 命名空间
    • 5.4. 定义块编码
    • 5.5. 控制方法和 ACPI 源语言 (ASL)
      • 5.5.1. ASL 报表
      • 5.5.2. 控制方法执行
        • 5.5.2.1. 论点
        • 5.5.2.2. 方法调用约定
        • 5.5.2.3. 局部变量和本地创建的数据对象
        • 5.5.2.4. 进入运营区域
          • 5.5.2.4.1. 运营地区
          • 5.5.2.4.2. CMOS 协议
          • 5.5.2.4.3. PCI 设备 BAR 目标协议
          • 5.5.2.4.4. 声明IPMI运营区域
          • 5.5.2.4.5. 声明 GeneralPurposeIO 操作区域
          • 5.5.2.4.6. 声明 GenericSerialBus 操作区域
            • 5.5.2.4.6.1. 声明 GenericSerialBus 字段
            • 5.5.2.4.6.2. 声明和使用 GenericSerialBus 数据缓冲区
            • 5.5.2.4.6.3. 使用通用串行总线协议
          • 5.5.2.4.7. 声明PCC运营区域
    • 5.6. ACPI 事件编程模型
      • 5.6.1. ACPI 事件编程模型组件
      • 5.6.2. ACPI 事件类型
      • 5.6.3. 固定事件处理
      • 5.6.4. 通用事件处理
      • 5.6.5. GPIO 信号 ACPI 事件
      • 5.6.6. 设备对象通知
      • 5.6.7. 设备类特定对象
      • 5.6.8. 对象、方法和资源的预定义ACPI名称
      • 5.6.9. 中断信号ACPI事件
      • 5.6.10. 使用设备 _PRW 对象管理唤醒事件
    • 5.7. 预定义对象
    • 5.8. 系统配置对象

5.5.2.4.4. 声明IPMI运营区域

本节介绍智能平台管理接口 (IPMI) 地址空间以及如何使用该地址空间与 AML 中的底板管理控制器 (BMC) 硬件进行通信。

与 SMBus 类似,IPMI操作区域是基于命令的,其中IPMI地址空间内的每个偏移量代表一个IPMI命令和响应对。鉴于这种独特性,IPMI操作区域对其字段定义进行了限制,并要求所有事务使用IPMI特定的数据缓冲区。本节中介绍的IPMI接口旨在与任何与IPMI规范兼容的硬件实现一起使用,无论系统接口类型如何。

与ACPI兼容的操作系统对IPMI通用地址空间的支持是可选的,并且取决于ACPI、IPMI设备的存在,即具有IPI0001即插即用ID的设备。如果存在,OSPM应根据设备下的_IFT(IPMI接口类型)控制方法指定的系统接口类型加载必要的驱动程序软件,并注册用于访问IPMI操作区域空间的处理程序。

如需了解更多信息,请参阅IPMI规范。

每个IPMI操作区域定义标识一个IPMI网络功能。仅针对需要从AML访问的IPMI网络功能定义操作区域。与其他区域一样,IPMI操作区域只能通过“字段”术语访问(请参阅声明IPMI字段)。

该接口将每个IPMI网络功能建模为具有 256 字节线性地址范围。此范围内的每个字节偏移对应一个命令值(例如,字节偏移 0xC1 等于命令值 0xC1),最多 256 个命令值。通过这样做,IPMI地址空间看起来是线性的,并且可以按照与其他地址空间类型类似的方式进行处理。

OperationRegion 术语的语法(来自 OperationRegion(声明操作区域))如下所述:

操作区域( RegionName, // NameString RegionSpace, // RegionSpaceKeyword Offset, // TermArg=>Integer Length // TermArg=>Integer )

其中:

  • RegionName 指定此 IPMI 网络功能的名称(例如,“POWR”)。

  • RegionSpace必须设置为IPMI(操作区域类型值0x07)。

  • 偏移量是一个字大小的值,指定目标设备的网络功能和初始命令值偏移量。高字节存储网络功能地址,低字节存储命令值偏移。例如,值 0x3000 将用于网络功能为 0x06 且初始命令值偏移为零 (0) 的设备。

  • 对于初始命令值偏移为零 (0) 的区域,长度设置为 0x100 (256),表示可能的命令值的最大数量。这两个值的差用于具有非零偏移的区域。例如,偏移值为 0x3010 的区域的相应长度将为 0xF0(0x100 减去 0x10)。

例如,底板管理控制器将支持网络功能 0x30 处的电能计量功能,以及用于查询网络功能 0x06 处BMC设备信息的IPMI命令。

以下ASL代码显示了如何使用OperationRegion术语来描述这些IPMI函数:

Device (IPMI)
{
    Name (_HID, "IPI0001")                       // IPMI device
    Name (_IFT, 0x1)                             // KCS system interface type
    OperationRegion (DEVC, IPMI, 0x0600, 0x100)  // Device info network function
    OperationRegion (POWR, IPMI, 0x3000, 0x100)  // Power network function
}

请注意,本例中的这些操作区域是在“拥有”IPMI设备的直接上下文中定义的。这可确保根据 _IFT 对象返回的值使用正确的操作区域处理程序。每个定义对应一个单独的网络功能,并且恰好使用零 (0) 的初始命令值偏移。

5.5.2.4.4.1. 声明IPMI字段

与其他区域一样,IPMI操作区域只能通过“字段”术语访问。每个字段元素都分配有一个唯一的命令值,并代表目标网络功能的虚拟命令。

字段术语(来自 Event(声明事件同步对象))的语法如下所述:

Field(
  RegionName,       // NameString=>OperationRegion
  AccessType,       // AccessTypeKeyword - BufferAcc
  LockRule,         // LockRuleKeyword
  UpdateRule        // UpdateRuleKeyword - ignored
) {FieldUnitList}

其中:

  • RegionName 指定之前为网络功能定义的操作区域名称。

  • AccessType 必须设置为 BufferAcc。这表明对字段元素的访问将使用区域特定的数据缓冲区来完成。对于这种访问类型,字段处理程序不知道数据缓冲区的内容可能是任何大小。当这种类型的字段用作操作中的源参数时,它的计算结果只是一个缓冲区。然而,当用作目标时,缓冲区会双向传递,以允许从写入操作返回数据。修改后的缓冲区将成为该命令的响应消息。这与执行结果与写入目标的值相同的正常情况略有不同。请注意,源永远不会改变,因为它仅代表特定IPMI命令的虚拟寄存器。

    • LockRule 指示访问该操作区域是否需要获取全局锁以进行同步。该字段应设置为锁定系统,其固件可以通过IPMI访问BMC,否则设置为“NoLock”。

    • UpdateRule 不适用于IPMI操作区域,因为每个虚拟寄存器都是完整访问的。所有 IPMI 字段定义都会忽略此字段。

IPMI操作区域要求所有字段元素都以命令值粒度声明。这意味着每个虚拟寄存器不能分解为字段定义中的各个位。

对虚拟寄存器的子部分的访问只能在字段定义之外进行。施加此限制既是为了简化IPMI接口,也是为了保持与IPMI规范定义的物理模型的一致性。

由于用于IPMI通信的系统接口由IPMI设备下的_IFT 对象确定,因此无需在字段定义中使用AccessAs 术语。事实上,它的使用将被操作处理程序忽略。

例如,电表网络功能的命令值 0xC1 处的寄存器可能表示设置BMC强制功率限制的命令,而同一网络功能的命令值 0xC2 处的寄存器可能表示当前配置的功率限制。同时,命令值 0xC8 处的寄存器可能代表最新的功率计测量结果。

以下ASL代码显示了使用OperationRegion、Field 和Offset 术语来表示这些虚拟寄存器:

OperationRegion(POWR, IPMI, 0x3000, 0x100) // Power network function
Field(POWR, BufferAcc, NoLock, Preserve)
{
    Offset(0xC1),             // Skip to command value 0xC1
    SPWL, 8,                  // Set power limit [command value 0xC1]
    GPWL, 8,                  // Get power limit [command value 0xC2]
    Offset(0xC8),             // Skip to command value 0xC8
    GPMM, 8                   // Get power meter measurement [command value 0xC8]
}

请注意,命令值相当于字段元素的字节偏移量(例如,SPWL=0xC1、GPWL=0xC2、GPMM=0xC8)。

5.5.2.4.4.2. 声明和使用IPMI请求和响应缓冲区

由于IPMI操作区域中的每个虚拟寄存器代表一个单独的IPMI命令,并且该操作依赖于双向缓冲区的使用,因此需要一个公共缓冲区结构来表示请求和响应消息。使用IPMI事务的数据缓冲区允许AML接收状态和数据长度值。

IPMI数据缓冲区被定义为固定长度的 66 字节缓冲区,如果使用“C”样式声明表示,则将建模如下:

typedef struct
{
  BYTE Status;    // Byte 0 of the data buffer
  BYTE Length;    // Byte 1 of the data buffer
  BYTE[64] Data;  // Bytes 2 through 65 of the data buffer
}

其中:

  • 状态(字节 0)表示给定IPMI命令的状态代码。有关详细信息,请参阅IPMI 状态代码。

  • 长度(字节1)指定数据缓冲区中存在的有效数据的字节数。有效长度值为 0 到 64。在执行操作之前,该值表示请求数据缓冲区的长度。之后,该值代表结果响应数据缓冲区的长度。

  • Data(字节65-2)代表一个64字节的缓冲区,是实际数据存储的位置。在执行操作之前,这代表实际的请求消息负载。此后,这表示IPMI命令返回的响应消息有效负载。

例如,以下ASL显示了如何使用IPMI数据缓冲区来执行幂函数命令。此代码基于声明IPMI字段中提供的示例ASL,其中列出了相关IPMI电能计量命令的操作区域和字段定义。

/* Create the IPMI data buffer */
Name(BUFF, Buffer(66){})            // Create IPMI data buffer as BUFF
CreateByteField(BUFF, 0x00, STAT)   // STAT = Status (Byte)
CreateByteField(BUFF, 0x01, LENG)   // LENG = Length (Byte)
CreateByteField(BUFF, 0x02, MODE)   // MODE = Mode (Byte)
CreateByteField(BUFF, 0x03, RESV)   // RESV = Reserved (Byte)

LENG = 0x2                          // Request message is 2 bytes long
MODE = 0x1                          // Set Mode to 1

BUFF = (GPMM = BUFF)                // Write the request into the GPMM command,
                                    // then read the results

CreateByteField (BUFF, 0x02, CMPC)  // CMPC = Completion code (Byte)
CreateWordField (BUFF, 0x03, APOW)  // APOW = Average power measurement (Word)

If ((STAT == 0x0) && (CMPC == 0x0)) // Successful?
{
    Return (APOW)                   // Return the average power measurement
}
Else
{
    Return (Ones)                   // Return invalid
}

请注意使用 CreateField 原语来访问数据缓冲区的子元素(状态、长度和数据),其中数据(字节 65-2)被“类型转换”到不同的字段(包括结果完成代码)。

上面的示例演示了如何使用 Store() 运算符和双向数据缓冲区来调用由虚拟寄存器表示的实际IPMI命令。内部Store()将请求消息数据缓冲区写入IPMI操作区域处理程序,并调用命令。外部 Store() 获取该命令的结果并将其写回数据缓冲区,这次代表响应消息。

5.5.2.4.4.3. IPMI 状态代码

每个IPMI命令都会产生一个状态代码,作为响应消息的第一个字节返回,包含在双向数据缓冲区中。此状态代码可以指示IPMI操作处理程序的成功、各种错误以及可能的超时。这是必要的,因为某些 IPMI 命令可能需要长达 5 秒的时间来执行,并且由于 AML Store() 操作本质上是同步的,因此必须确保 IPMI 操作及时返回,以免阻塞 OSPM 中的 AML 解释器。

  • 此状态代码与IPMI完成代码不同,后者作为数据缓冲区有效负载中响应消息的第一个字节返回。完整的IPMI规范中描述了完成代码。
表 5.150 IPMI 状态代码 状态代码姓名描述
00 点IPMI OK表示命令已成功完成。
07 点IPMI 未知故障表示由于未知IPMI错误而失败。
10 小时IPMI 命令操作超时表示操作超时。
Prev
5.5.2.4.3. PCI 设备 BAR 目标协议
Next
5.5.2.4.5. 声明 GeneralPurposeIO 操作区域