片上系统(SoC)集成电路广泛使用通用输入/输出(GPIO)引脚。 对于基于 SoC 的平台,Windows 为 GPIO 硬件定义一个常规抽象,并且此抽象需要高级配置和 Power Interface (ACPI) 命名空间的支持。
本文中列出的 ACPI 5.0 规范定义支持 GPIO 抽象。
若要验证 GPIO 控制器是否满足所有 Windows 平台要求,请参阅 GPIO 控制器要求清单。
GPIO 控制器设备
Windows 支持 GPIO 控制器。 GPIO 控制器为外围设备提供各种功能,包括中断、输入信号和输出信号。 GPIO 功能在命名空间中作为 GPIO 控制器设备进行建模。 GPIO 框架扩展(GpioClx)将 GPIO 控制器设备建模为由若干引脚组组成。 每个引脚库具有 64 个或更少的可配置引脚。 GPIO 控制器中的引脚组根据其在控制器相对 GPIO 引脚空间中的位置进行排序。 例如,bank 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 仿真,需要满足以下硬件要求:
支持 ActiveBoth 中断的 GPIO 控制器必须支持电平模式中断,并且必须支持在运行时动态对中断的极性重新编程。
为了最大程度地降低 I/O 错误的风险,Windows 更喜欢使用内存映射的 GPIO 控制器,而不是 SPB 连接的 GPIO 控制器。 事实上,对于 Windows 按钮阵列设备(PNP0C40),此设备的 ActiveBoth GPIO 中断连接到内存映射的 GPIO 控制器,而不是连接到 SPB 连接的控制器。 若要确定哪个按钮中断必须是 ActiveBoth,请参阅“其他 ACPI 命名空间对象”主题中的“按钮设备”部分。
若要为 ActiveBoth 中断信号建立确定性初始状态,Windows GPIO 设备堆栈保证驱动程序连接后生成的第一个中断将始终用于信号的断言状态。 堆栈进一步假定所有 ActiveBoth 中断线的断言状态默认为低逻辑级别(ActiveLow edge)。 如果平台上不存在这种情况,可以通过在控制器的命名空间中包含 GPIO 控制器 Device-Specific 方法(_DSM)来替代默认值。 有关此方法的详细信息,请参阅 GPIO 控制器 Device-Specific 方法(_DSM)。
上述列表中的第三项要求意味着,如果 GPIO 引脚上的信号处于断言状态,则使用 ActiveBoth 的设备驱动程序在初始化(连接到)中断后可能会立即收到中断。 对于某些设备(例如耳机),这是可能的,甚至很可能,并且必须在驱动程序中支持。
为了支持模拟 ActiveBoth,GPIO 控制器驱动程序必须通过实现 CLIENT_ReconfigureInterrupt 回调函数,并在驱动程序的 CLIENT_QueryControllerBasicInformation 回调函数中提供给 GpioClx 的基本信息结构中设置 EmulateActiveBoth 标志,从而启用 ActiveBoth 仿真。 有关详细信息,请参阅 General-Purpose 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 连接描述符,用于连接所有 GPIO I/O 和中断引脚。 如果一个连接的中断可以用来唤醒系统(能够从低功耗空闲状态唤醒系统),则必须将其配置为 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-Signaled ACPI 事件”。
对于 SoC 平台,GPIO 中断用于向平台事件发出信号。 使用 ASL Notify 操作符向驱动程序发出事件信号的任何命名空间设备(“ACPI 事件源”设备)都需要具备以下条件:
ACPI 事件信号连接到的 GPIO 控制器的命名空间节点必须在其 ACPI 事件信息(_AEI)对象中包含该引脚的 GpioInt 资源(请参阅下面的“ACPI 事件信息(_AEI)对象”第 2.4.2.3.1 节)。 GpioInt 资源必须配置为非共享资源(独占)。
控制器的节点还必须包含_AEI对象中列出的每个引脚的 Edge(_Exx)、级别(_Lxx)或事件(_EVT)控制方法。
ACPI 驱动程序处理列出的 GPIO 中断并分析其边缘、级别或事件的控制方法。 控制方法在必要时会静止硬件事件,并在事件源设备的命名空间节点上执行所需的 Notify 运算符。 然后,Windows 会将通知发送到设备的驱动程序。 如果事件控制方法可以查询硬件以确定发生哪个事件,则可以在同一 GpioInt 资源上发出多个事件信号。 然后,该方法必须使用正确的通知代码通知正确的设备。
ACPI 事件信息 (_AEI) 对象 如前所述,GPIO 控制器的命名空间必须包含 _AEI 对象才能支持 ACPI 事件。 _AEI 对象(请参阅 ACPI 5.0 规范中的第 5.6.5.2 节)返回一个资源模板缓冲区,该缓冲区仅包含通过此 GPIO 控制器向 ACPI 发出事件信号的 GpioInt 描述符。 每个描述符对应于一个 ACPI 事件源设备,专用于该设备(未在设备之间共享)。
通用输入输出操作区域(OpRegions)
平台固件通常使用 GPIO 控制器来支持任意数量的平台硬件功能,例如控制电源和时钟,或在设备上设置模式。 为了支持使用 ASL 控件方法中的 GPIO I/O,ACPI 5.0 定义了新的 OpRegion 类型“GeneralPurposeIO”。
GeneralPurposeIO 操作区域(请参阅 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) 方法(请参阅 ACPI 5.0 规范的第 6.5.4 部分)来跟踪 OpRegion 处理程序的状态。 此外,OpRegion 依赖项(_DEP)对象(请参阅 ACPI 5.0 规范的第 6.5.8 节)可以在具有访问 GPIO OpRegion 字段的方法的任何设备下使用(如果需要)。 有关何时使用_DEP的讨论,请参阅设备管理命名空间对象主题中的“设备依赖项”部分。 请务必不向驱动程序分配也分配给 GeneralPurposeIO OpRegions 的 GPIO I/O 资源。 Opregion 用于 ASL 控制方法的专用。