常规用途 I/O (GPIO)

芯片上的系统 (SoC) 集成电路广泛使用通用 I/O (GPIO) 引脚。 对于基于 SoC 的平台,Windows 定义 GPIO 硬件的一般抽象,并且此抽象需要高级配置和电源接口 (ACPI) 命名空间的支持。

本文中列出的 ACPI 5.0 规范定义支持 GPIO 抽象。

若要验证 GPIO 控制器是否满足所有 Windows 平台要求,请参阅 GPIO 控制器要求清单

GPIO 控制器设备

Windows 支持 GPIO 控制器。 GPIO 控制器为外围设备提供各种功能,包括中断、输入信号和输出信号。 GPIO 功能在命名空间中建模为 GPIO 控制器设备。 GPIO 框架扩展 (GpioClx) 将 GPIO 控制器设备建模为分区成一些数量的引脚库。 每个引脚库具有 64 个或更少的可配置引脚。 GPIO 控制器中的库相对于其引脚在控制器相对 GPIO 引脚空间中的位置进行排序。 例如,在控制器上,库 0 包含引脚 0-31,库 1 包含引脚 32-63 等。 除最后一个库外,所有库的引脚数都相同,可能更少。 库对于 ACPI 固件非常重要,因为固件必须报告系统中断资源到库的映射,如下面的“GPIO 命名空间对象”部分所述。

库上的每个引脚都有一组参数(例如,输出、级别敏感中断、解除输入等),用于描述如何配置引脚。

GPIO 控制器和 ActiveBoth 中断

某些 GPIO 控制器的一项功能是在信号的两个边缘(上升或 ActiveHigh 边缘以及下降或 ActiveLow 边缘)生成中断。 这在各种应用程序中非常有用,包括按钮界面,其中按钮按下事件(一个边缘)和按钮放开事件(另一个边缘)都有意义。 此功能称为“ActiveBoth”。

从逻辑上讲,ActiveBoth 信号同时具有断言和未断言状态,无论是瞬间断言(例如,pushbuttons),还是无限长断言(例如耳机插孔插入)。 ActiveBoth 中断边缘检测可以在 GPIO 控制器硬件(硬件 ActiveBoth)中实现,也可以在 GPIO 驱动程序软件(模拟 ActiveBoth)中模拟。 Windows 要求实现 ActiveBoth 的 GPIO 控制器必须使用模拟 ActiveBoth。 这需要确保所有方案都进行双边缘中断的可靠处理。 为了支持 ActiveBoth 仿真,需要满足以下硬件要求:

  1. 支持 ActiveBoth 中断的 GPIO 控制器必须支持级别模式中断,并且必须支持在运行时动态对中断的极性重新编程。

  2. 为了最大程度地降低 I/O 错误的风险,Windows 更喜欢使用内存映射的 GPIO 控制器,而不是 SPB 连接的 GPIO 控制器。 事实上,对于 Windows Button Array 设备 (PNP0C40),此设备的 ActiveBoth GPIO 中断连接到内存映射的 GPIO 控制器,而不是 SPB 连接的控制器。 若要确定哪个按钮中断必须是 ActiveBoth,请参阅“其他 ACPI 命名空间对象”主题中的“按钮设备”部分。

  3. 若要为 ActiveBoth 中断信号建立确定性初始状态,Windows GPIO 设备堆栈保证驱动程序中断连接后生成的第一个中断将始终用于信号的断言状态。 堆栈进一步假设所有 ActiveBoth 中断行的断言状态默认为低逻辑级别(ActiveLow 边缘)。 如果平台上不是这种情况,可以通过在控制器的命名空间中包含 GPIO 控制器特定于设备的方法 (_DSM) 来替代默认值。 有关此方法的详细信息,请参阅 GPIO 控制器特定于设备的方法 (_DSM)

上述列表中的第三项要求意味着,如果当时 GPIO 引脚上的信号处于断言状态,则使用 ActiveBoth 的设备驱动程序在初始化(连接到)中断后可能会立即收到中断。 这是不可能的,即使对于某些设备(例如耳机)有这种可能,也必须在驱动程序中受支持。

若要支持模拟 ActiveBoth,GPIO 控制器驱动程序必须通过实现 CLIENT_ReconfigureInterrupt 回调函数来启用(“选择加入”)ActiveBoth 仿真,并在驱动程序的 CLIENT_QueryControllerBasicInformation 回调函数提供给 GpioClx 的基本信息结构中设置 EmulateActiveBoth 标志。 有关详细信息,请参阅常规用途 I/O (GPIO) 驱动程序

GPIO 命名空间对象

ACPI 枚举 GPIO 控制器和连接的外围设备。 使用 GPIO 连接资源描述符来描述它们之间的连接。 有关详细信息,请参阅 ACPI 5.0 规范第 6.4.3.8 节“连接描述符”。

设备标识和配置对象

GPIO 控制器设备的 ACPI 命名空间包括:

  • 供应商分配的符合 ACPI 的硬件 ID (_HID) 对象。
  • 一组资源消耗的 (_CRS) 对象。
  • 一个唯一 ID (_UID) 对象,如果命名空间中有多个 GPIO 控制器实例(即两个或多个具有相同设备标识对象的命名空间节点)。

GPIO 控制器的 _CRS 包含 GPIO 控制器中所有库消耗的所有资源(寄存器的地址空间、系统中断等)。 中断资源到库映射以中断资源在 _CRS 中列出的顺序表示,即列出的第一个中断分配给库 0,下一个列出的中断分配给库 1,依此类推。 库可以共享中断资源,在这种情况下,每个资源连接的库(按库顺序)列出中断一次,并配置为“共享”。

GPIO 连接资源描述符

外围设备与连接到的 GPIO 引脚之间的关系由 GPIO 连接资源描述符描述到操作系统。 这些资源描述符可以定义两种类型的 GPIO 连接:GPIO 中断连接和 GPIO I/O 连接。 外围设备在 _ CRS 中包含所有连接的 GPIO I/O 和中断引脚的 GPIO 连接描述符。 如果连接的中断支持唤醒(能够从低功率空闲状态唤醒系统),则必须将其配置为 ExclusiveAndWake 或 SharedAndWake。 有关详细信息,请参阅设备电源管理

描述符在 ACPI 5.0 规范的第 6.4.3.8.1 节“GPIO 连接描述符”中定义。 ACPI 5.0 规范的第 19.5.53 节“GPioInt(GPIO 中断连接资源描述符宏)”中介绍这些描述符的 ASL 资源模板宏。

发出 GPIO 信号的 ACPI 事件

ACPI 定义一个平台事件模型,该模型使平台中的硬件事件能够发出信号并将其传达给 ACPI 驱动程序。 Windows 提供通知服务,用于将平台事件传达给设备驱动程序。 许多收件箱驱动程序依赖此服务来为 ACPI 定义的设备提供支持,例如控制方法电源按钮、LID 设备、控制方法电池、热区域等。 有关通知的详细信息,请参阅 ACPI 规范的第 5.6.5 节“发出 GPIO 信号的 ACPI 事件”。

对于 SoC 平台,GPIO 中断用于向平台事件发出信号。 使用 ASL Notify 运算符向驱动程序发出事件信号的任何命名空间设备(“ACPI 事件源”设备)都需要以下各项:

  • ACPI 事件信号所连接的 GPIO 控制器的命名空间节点必须在其 ACPI 事件信息 (_AEI) 对象中包含该引脚的 GpioInt 资源(请参阅下面的第 2.4.2.3.1 节“ACPI 事件信息 (_AEI) 对象”)。 GpioInt 资源必须配置为非共享资源(独占)。

  • 控制器的节点还必须包含 _AEI 对象中列出的每个引脚的 Edge (_Exx)、Level (_Lxx) 或 Event (_EVT) 控制方法。

ACPI 驱动程序处理列出的 GPIO 中断并评估 Edge、Level 或 Event 控制方法。 控制方法在必要时会静止硬件事件,并在事件源设备的命名空间节点上执行所需的 Notify 运算符。 然后,Windows 会将通知发送到设备的驱动程序。 如果事件控制方法可以查询硬件以确定发生的事件,则可以在同一 GpioInt 资源上发出多个事件信号。 然后,该方法必须使用正确的通知代码通知正确的设备。

ACPI 事件信息 (_AEI) 对象 如前所述,GPIO 控制器的命名空间必须包含 _AEI 对象才能支持 ACPI 事件。 _AEI 对象(请参阅 ACPI 5.0 规范中的第 5.6.5.2 节)返回一个资源模板缓冲区,该缓冲区仅包含通过此 GPIO 控制器向 ACPI 事件发出信号的 GpioInt 描述符。 每个描述符对应于一个 ACPI 事件源设备并专用于该设备(未在设备之间共享)。

GeneralPurposeIO 操作区域 (OpRegions)

平台固件通常使用 GPIO 控制器来支持任意数量的平台硬件功能,例如控制电源和时钟,或在设备上设置模式。 为了支持使用 ASL 控制方法中的 GPIO I/O,ACPI 5.0 定义了新的 OpRegion 类型“GeneralPurposeIO”。

GeneralPurposeIO OpRegions(请参阅 ACPI 5.0 规范第 5.5.2.4.4 节)在驱动程序将处理 I/O GPIO 的控制器设备的命名空间范围内声明。 GeneralPurposeIO 字段声明(请参阅 ACPI 5.0 规范第 5.5.2.4.4.1 节)将名称分配给将在 GeneralPurposeIO OpRegion 中访问的 GPIO 引脚。 GpioIO 连接资源(请参阅 ACPI 5.0 规范第 19.5.53 节)用于在字段声明中指定引脚号和特定字段引用的配置。 连接描述符后面的命名字段位总数必须等于描述符中列出的引脚数。

OpRegion 中的字段可以声明命名空间中的任意位置,并从命名空间中的任何方法访问。 对 GeneralPurposeIO OpRegion 的访问方向由第一个访问(读取或写入)决定,无法更改。

由于 OpRegion 访问由 GPIO 控制器设备驱动程序(“OpRegion 处理程序”)提供,因此在驱动程序可用之前,方法必须注意不访问 OpRegion。 ASL 代码可以通过在 GPIO 控制器设备下包括 Region (_REG) 方法来跟踪 OpRegion 处理程序的状态(请参阅 ACPI 5.0 规范第 6.5.4 节)。 此外,OpRegion 依赖项 (_DEP) 对象(请参阅 ACPI 5.0 规范第 6.5.8 节)可以在具有访问 GPIO OpRegion 字段的方法的任何设备下使用(如果需要)。 有关何时使用 _DEP 的讨论,请参阅设备管理命名空间对象主题中的设备依赖项部分。 重要的是,分配给 GeneralPurposeIO OpRegions 的 GPIO I/O 资源不要分配给驱动程序。 Opregion 用于独占使用 ASL 控制方法。