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.6.3. 使用通用串行总线协议

本节提供有关如何使用每个 GenericSerialBus 协议访问AML中的 GenericSerialBus 设备的信息和示例。

快速读/写 (AttribQuick)

GenericSerialBus 读/写快速协议 (AttribQuick) 通常用于使用设备特定的二进制命令(例如ON和OFF)来控制简单设备。该协议不使用命令值,因此只能在字段定义中指定单个元素(位于偏移 0 处)。该协议不传输任何数据。

以下ASL代码说明了如何访问支持读/写快速协议的设备:

OperationRegion (TOP1, GenericSerialBus, 0x00, 0x100)
  // GenericSerialBus device at command value offset 0
Field (TOP1, BufferAcc, NoLock, Preserve)
{
    Connection (I2CSerialBusV2 (0x5a,,100000,,"\\_SB.I2C",,,,,RawDataBuffer (){1,6})),
    AccessAs (BufferAcc, AttribQuick),
                               // Use the GenericSerialBus Read/Write Quick protocol
    FLD0, 8                    // Virtual register at command value 0.
}

/* Create the GenericSerialBus data buffer */

Name (BUFF, Buffer (2){})          // Create GenericSerialBus data buffer as BUFF
CreateByteField (BUFF, 0x00, STAT) // STAT = Status (Byte)

/* 信号设备(例如OFF)*/

BUFF = FLD0                        // Invoke Read Quick transaction
If (STAT == 0x00)                  // Was the transactions successful?
{
    ...
}

/* Signal device (e.g. ON) */

FLD0 = FLD0 // Invoke Write Quick transaction

在此示例中,偏移量 0 处的单个字段元素 (FLD0) 被定义为表示协议的读/写位。访问FLD0将导致设备发生 GenericSerialBus 事务。读取字段会导致“快速读取”,写入字段会导致“快速写入”。在这两种情况下,数据都不会被传输——对寄存器的访问只是用作调用事务的机制。

发送/接收字节 (AttribSendReceive)

GenericSerialBus 发送/接收字节协议 (AttribSendReceive) 传输单个字节的数据。与快速读/写一样,该协议不使用命令值,因此只能在字段定义中指定单个元素(偏移量为 0)。

以下ASL代码说明了如何访问支持发送/接收字节协议的设备:

OperationRegion (TOP1, GenericSerialBus, 0x00, 0x100)
    // GenericSerialBus device at command value offset 0
Field (TOP1, BufferAcc, NoLock, Preserve)
{
    Connection (I2CSerialBusV2 (0x5a,,100000,,"\\_SB.I2C",,,,,RawDataBuffer (){1,6})),
    AccessAs(BufferAcc, AttribSendReceive),
        // Use the GenericSerialBus Send/Receive Byte protocol
    FLD0, 8 // Virtual register at command value 0.
}

// Create the GenericSerialBus data buffer

Name (BUFF, Buffer (3){})              // Create GenericSerialBus data buffer as BUFF
CreateByteField (BUFF, 0x00, STAT)     // STAT = Status (Byte)
CreateByteField (BUFF, 0x02, DATA)     // DATA = Data (Byte)

// Receive a byte of data from the device

BUFF = FLD0 // Invoke a Receive Byte transaction
If (STAT == 0x00)                      // Successful?
{
                                       // DATA = Received byte...
}

// Send the byte '0x16' to the device

DATA = 0x16                            // Save 0x16 into the data buffer
FLD0 = BUFF                            //Invoke a Send Byte transaction

在此示例中,偏移量 0 处的单个字段元素 (FLD0) 被定义为表示协议的数据字节。访问FLD0将导致设备发生 GenericSerialBus 事务。读取该字段会产生一个接收字节,写入该字段会产生一个发送字节。

读/写字节 (AttribByte)

GenericSerialBus 读/写字节协议 (AttribByte) 也传输单个字节的数据。但与发送/接收字节不同,该协议使用命令值来引用最多 256 字节大小的虚拟寄存器。

以下ASL代码说明了如何访问支持读/写字节协议的设备:

操作区域(TOP1、GenericSerialBus、0x00、0x100) // GenericSerialBus device at command value offset Field (TOP1, BufferAcc, NoLock, Preserve) { Connection (I2CSerialBusV2 (0x5a,,100000,,"\_SB.I2C",,,,,RawDataBuffer (){1,6})), AccessAs(BufferAcc, AttribByte), // Use the GenericSerialBus Read/Write Byte protocol FLD0, 8, // Virtual register at command value 0. FLD1, 8, // Virtual register at command value 1. FLD2, 8 // Virtual register at command value 2. }

// Create the GenericSerialBus data buffer

Name (BUFF, Buffer (3){})

// Create GenericSerialBus data buffer as BUFF

CreateByteField (BUFF, 0x00, STAT)   // STAT = Status (Byte)
CreateByteField (BUFF, 0x02, DATA)   // DATA = Data (Byte)

// Read a byte of data from the device using command value 1

BUFF = FLD1                          // Invoke a Read Byte transaction
If (STAT == 0x00)                    // Successful?
{
                                     // DATA = Byte read from FLD1...
}

// Write the byte '0x16' to the device using command value 2

DATA = 0x16                          // Save 0x16 into the data buffer
FLD2 = BUFF                          // Invoke a Write Byte transaction

在此示例中,定义了三个字段元素(FLD0、FLD1和FLD2)来表示命令值 0、1 和 2 的虚拟寄存器。访问任何字段元素都会导致设备发生 GenericSerialBus 事务。读取FLD1会产生命令值为 1 的读字节,写入FLD2会产生命令值为 2 的写字节。

读/写字(AttribWord)

GenericSerialBus 读/写字协议 (AttribWord) 传输 2 个字节的数据。该协议还使用命令值来引用最多 256 个字大小的虚拟设备寄存器。

以下ASL代码说明了如何访问支持读/写字协议的设备:

OperationRegion (TOP1, GenericSerialBus, 0x00, 0x100)
    // GenericSerialBus device at command value offset 0
Field (TOP1, BufferAcc, NoLock, Preserve)
{
    Connection (I2CSerialBusV2 (0x5a,,100000,,"\\_SB.I2C",,,,,RawDataBuffer (){1,6})),
    AccessAs (BufferAcc, AttribWord),
               // Use the GenericSerialBus Read/Write Word protocol
    FLD0, 8,   // Virtual register at command value 0.
    FLD1, 8,   // Virtual register at command value 1.
    FLD2, 8    // Virtual register at command value 2.
}

// Create the GenericSerialBus data buffer

Name(BUFF, Buffer(6){})            // Create GenericSerialBus data buffer as BUFF
CreateByteField(BUFF, 0x00, STAT)  // STAT = Status (Byte)
CreateWordField(BUFF, 0x02, DATA)  // DATA = Data (Word)

/* Read two bytes of data from the device using command value 1 */

BUFF = FLD1                        // Invoke a Read Word transaction
If (STAT == 0x00)                  // Was the transaction successful?
{
                                   // DATA = Word read from FLD1...
}

/* Write the word '0x5416' to the device using command value 2 */

DATA = 0x5416                      // Save 0x5416 into the data buffer
FLD2 = BUFF                        // Invoke a Write Word transaction

在此示例中,定义了三个字段元素(FLD0、FLD1和FLD2)来表示命令值 0、1 和 2 的虚拟寄存器。访问任何字段元素都会导致设备发生 GenericSerialBus 事务。读取FLD1会产生命令值为 1 的读字,写入FLD2会产生命令值为 2 的写字。

请注意,虽然访问每个字段元素会传输一个字(16 位)数据,但每个字段都列为 8 位。实际数据大小由协议决定。每个字段元素都声明为 8 位长度,以便命令值和字节偏移量相等。

读/写块(AttribBlock)

GenericSerialBus 读/写块协议 (AttribBlock) 传输可变大小的数据。该协议使用命令值来引用最多 256 个块大小的虚拟寄存器。

以下ASL代码说明了如何访问支持读/写块协议的设备:

OperationRegion (TOP1, GenericSerialBus, 0x00, 0x100)
Field (TOP1, BufferAcc, NoLock, Preserve)
{
    Connection (I2CSerialBusV2 (0x5a,,100000,,"\\_SB.I2C",,,,,RawDataBuffer(){1,6})),
    Offset(0x0),
    AccessAs(BufferAcc, AttribBlock),
    TFK1, 8,
    TFK2, 8
}

// Create the GenericSerialBus data buffer

Name (BUFF, Buffer (34){})         // Create SerialBus buf as BUFF
CreateByteField (BUFF, 0x00, STAT) // STAT = Status (Byte)
CreateBytefield (BUFF, 0x01, LEN)  // LEN = Length (Byte)
CreateWordField (BUFF, 0x03, DATW) // DATW = Data (Word - Bytes 2 & 3, or 16 bits)
CreateField (BUFF, 16, 256, DBUF)  // DBUF = Data (Bytes 2-33)
CreateField (BUFF, 16, 32, DATD)   // DATD = Data (DWord)

/* Read block of data from the device using command value 0 */

BUFF = TFK1
If (STAT != 0x00)
{
    Return (0)
}

/* Read block of data from the device using command value 1 */

BUFF = TFK2
If (STAT != 0x00)
{
    Return (0)
}

在此示例中,定义了两个字段元素(TFK1和TFK2)来表示命令值 0 和 1 的虚拟寄存器。访问任何字段元素都将导致设备发生 GenericSerialBus 事务。

写入数据块需要类似的语义,例如以下示例:

Store (16, LEN)       // In bits, so 4 bytes
LEN = 16
BUFF = (TFK1 = BUFF)
If (STAT == 0x00)     // Was the transaction successful?
{
    ...
}

此访问器对于某些 SPB 不可行,因为总线可能不支持适当的功能。如果需要可变长度缓冲区但总线不支持块访问器,请参阅 SerialBytes 协议。

字进程调用(AttribProcessCall)

GenericSerialBus 进程调用协议 (AttribProcessCall) 双向传输 2 个字节的数据(执行写入字,然后执行读取字作为原子事务)。该协议使用命令值来引用最多 256 个字大小的虚拟寄存器。

以下ASL代码说明了如何访问支持进程调用协议的设备:

操作区域(TOP1、GenericSerialBus、0x00、0x100) // GenericSerialBus device at slave address 0x42 Field (TOP1, BufferAcc, NoLock, Preserve) { Connection (I2CSerialBusV2 (0x5a,,100000,,"\_SB.I2C",,,,,RawDataBuffer(){1,6})), AccessAs (BufferAcc, AttribProcessCall), // Use the GenericSerialBus Process Call protocol FLD0, 8, // Virtual register at command value 0. FLD1, 8, // Virtual register at command value 1. FLD2, 8 // Virtual register at command value 2. }

// Create the GenericSerialBus data buffer

Name (BUFF, Buffer (6){})             // Create GenericSerialBus data buffer as BUFF
CreateByteField (BUFF, 0x00, STAT)    // STAT = Status (Byte)
CreateWordField (BUFF, 0x02, DATA)    // DATA = Data (Word)

/* Process Call with input value '0x5416' to the device using command value 1 */

DATA = 0x5416                         // Save 0x5416 into the data buffer

BUFF = (FLD1 = BUFF)                  // Invoke a Process Call transaction
If (STAT == 0x00)                     // Was the transaction successful?
{
    // DATA = Word returned from FLD1...
}

在此示例中,定义了三个字段元素(FLD0、FLD1和FLD2)来表示命令值 0、1 和 2 的虚拟寄存器。访问任何字段元素都会导致设备发生 GenericSerialBus 事务。读取或写入FLD1会导致命令值为 1 的“进程调用”。请注意,与其他协议不同,“进程调用”涉及单个原子事务中的写入和读取操作。这意味着 GenericSerialBus 数据缓冲区的数据元素在调用事务之前设置有输入值,并在事务成功完成后保存输出值。

块进程调用(AttribBlockProcessCall)

GenericSerialBus 块写入-读取块进程调用协议 (AttribBlockProcessCall) 双向传输数据块(执行写入块,然后执行读取块作为原子事务)。该协议使用命令值来引用最多 256 个块大小的虚拟寄存器。

以下ASL代码说明了如何访问支持进程调用协议的设备:

OperationRegion (TOP1, GenericSerialBus, 0x00, 0x100)
    // GenericSerialBus device at slave address 0x42
Field (TOP1, BufferAcc, NoLock, Preserve)
{
    Connection (I2CSerialBusV2 (0x5a,,100000,,"\\_SB.I2C",,,,,RawDataBuffer(){1,6})),
    AccessAs (BufferAcc, AttribBlockProcessCall),
        // Use the Block Process Call protocol
    FLD0, 8,                   // Virtual register representing a command value of 0
    FLD1, 8                    // Virtual register representing a command value of 1
}

// Create the GenericSerialBus data buffer as BUFF

Name (BUFF, Buffer (35){})          // Create GenericSerialBus data buffer as BUFF
CreateByteField (BUFF, 0x00, STAT)  // STAT = Status (Byte)
CreateByteField (BUFF, 0x01, LEN)   // LEN = Length (Byte)
CreateField (BUFF, 0x10, 256, DATA) // Data (Block)

/* Process Call with input value "ACPI" to the device using command value 1 */

DATA = "ACPI" // 填写传出数据 LEN = 4 // Length of the valid data not including status (STAT) // and length (LEN) bytes. BUFF = (FLD1 = BUFF)

If (STAT == 0x00) // Test the status
{
   // BUFF now contains information returned from PC
   // LEN now equals size of data returned
}

读/写 N 字节 (AttribBytes)

GenericSerialBus 读/写 N 字节协议 (AttribBytes) 传输可变大小的数据。指定为 AccessAs 属性一部分的双向调用的读取传输字节长度。

以下ASL代码说明了如何访问支持读/写 N 字节协议的设备:

OperationRegion (TOP1, GenericSerialBus, 0x00, 0x100)
Field (TOP1, BufferAcc, NoLock, Preserve)
{
    Connection (I2CSerialBusV2 (0x5a,,100000,,"\\_SB.I2C",,,,,RawDataBuffer(){1,6})),
    AccessAs (BufferAcc, AttribBytes (4)),
    TFK1, 8, //TFK1 at command value 0
    TFK2, 8, //TFK2 at command value 1
    Connection (I2CSerialBus (0x5b,,100000,,"\\_SB.I2C",,,,RawDataBuffer (){2,9})),
        // same connection attribute, but different vendor data passed to driver
    AccessAs (BufferAcc, AttribByte),
    TM1, 8 //TM1 at command value 2
}

// Create the GenericSerialBus data buffer

Name (BUFF, Buffer(34) {})          // Create SerialBus buf as BUFF
CreateByteField (BUFF, 0x00, STAT)  // STAT = Status (Byte)
CreateBytefield (BUFF, 0x01, LEN)   // LEN = Length (Byte)
CreateWordField (BUFF, 0x02, DATW)  // DATW = Data (Word - Bytes 2 & 3, or 16 bits)
CreateField (BUFF, 16, 256, DBUF)   // DBUF = Data (Bytes 2-34)
CreateField (BUFF, 16, 32, DATD)    // DATD = Data (DWord)

// Read block of data from the device using command value 0

BUFF = TFK1
If (STAT != 0x00)
{
    Return (0)
}

// Write block of data to the device using command value 1

BUFF = (TFK2 = BUFF)
If (STAT != 0x00)
{
    Return (0)
}

在此示例中,定义了两个字段元素(TFK1和TFK2)来表示命令值 0 和 1 的虚拟寄存器。访问任何字段元素都将导致在 AccessAttributes 中指定长度的设备上发生 GenericSerialBus 事务。

原始读/写 N 字节 (AttribRawBytes)

GenericSerialBus 原始读/写 N 字节协议 (AttribRawBytes) 传输可变大小的数据。指定为 AccessAs 属性一部分的双向事务的读取传输字节长度。原始访问将忽略操作区域定义中指定的初始命令值。

以下ASL代码说明了如何访问支持读/写 N 字节协议的设备:

OperationRegion (TOP1, GenericSerialBus, 0x00, 0x100)
Field (TOP1, BufferAcc, NoLock, Preserve)
{
    Connection (I2CSerialBusV2 (0x5a,,100000,,"\\_SB.I2C",,,,,RawDataBuffer(){1,6})),
    AccessAs(BufferAcc, AttribRawBytes (4)),
    TFK1, 8
}

/* Create the GenericSerialBus data buffer */

Name(BUFF, Buffer (34){}) // 创建 SerialBus buf 为 BUFF CreateByteField (BUFF, 0x00, STAT) // STAT = Status (Byte) CreateByteField (BUFF, 0x01, LEN) // LEN = Length (Byte) CreateWordField (BUFF, 0x02, DATW) // DATW = Data (Word - Bytes 2 & 3, or 16 bits) CreateField (BUFF, 16, 256, DBUF) // DBUF = Data (Bytes 2-34) CreateField (BUFF, 16, 32, DATD) // DATD = Data (DWord)

DATW = 0x0B // Store appropriate reference data for driver to interpret

/* Read from TFK1 */

BUFF = TFK1
If (STAT != 0x00)
{
    Return (0)
}

/* Write to TFK1 */

BUFF = (TFK1 = BUFF)
If (STAT != 0x00)
{
    Return(0)
}

对任何字段元素的访问都会导致在 AccessAttributes 中指定长度的设备上发生 GenericSerialBus 事务。

原始访问假设编写者了解访问所通过的总线以及正在访问的设备。该协议可能仅确保缓冲区被传输到适当的驱动程序,但驱动程序必须能够解释缓冲区以与寄存器进行通信。

原始块进程调用 (AttribRawProcessBytes)

GenericSerialBus 原始写入-读取块进程调用协议 (AttribRawProcessBytes) 双向传输数据块(执行写入块,然后执行读取块作为原子事务)。指定为 AccessAs 属性一部分的双向事务的读取传输字节长度。原始访问将忽略操作区域定义中指定的初始命令值。

以下ASL代码说明了如何访问支持进程调用协议的设备:

OperationRegion (TOP1, GenericSerialBus, 0x00, 0x100)
    // GenericSerialBus device at slave address 0x42
Field (TOP1, BufferAcc, NoLock, Preserve)
{
    Connection (I2CSerialBusV2 (0x5a,,100000,,"\\_SB.I2C",,,,,RawDataBuffer (){1,6})),
    AccessAs (BufferAcc, AttribRawProcessBytes (2)),
        // Use the Raw Bytes Process Call protocol
    FLD0, 8
}

// Create the GenericSerialBus data buffer as BUFF

Name (BUFF, Buffer (34){})          // Create GenericSerialBus data buffer as BUFF
CreateByteField (BUFF, 0x00, STAT)  // STAT = Status (Byte)
CreateByteField (BUFF, 0x01, LEN)   // LEN = Length (Byte)
CreateWordField (BUFF,0x02, DATW)   // Data (Bytes 2 and 3)
CreateField (BUFF, 0x10, 256, DATA) // Data (Block)

DATW = 0x0B              //Store appropriate reference data for driver to interpret

/* Process Call with input value "ACPI" to the device */

DATA = "ACPI"                      // Fill in outgoing data
LEN = 4                            // Length of the valid data

BUFF = (FLD0 = BUFF)               // Execute the PC
If (STAT == 0x00)                  // Test the status
{
    // BUFF now contains information returned from PC
    // LEN now equals size of data returned
}

原始访问假设编写者了解访问所通过的总线以及正在访问的设备。该协议可能仅确保缓冲区被传输到适当的驱动程序,但驱动程序必须能够解释缓冲区以与寄存器进行通信。

Prev
5.5.2.4.6.2. 声明和使用 GenericSerialBus 数据缓冲区