文档详情

Linux ACPI处理流程

jiups****uk12
实名认证
店铺
PDF
360.88KB
约26页
文档ID:39118631
Linux ACPI处理流程_第1页
1/26

Linux2.6.6 内核下 ACPI PCI Hot-Plug 的实现机制(上) Linux2.6.6 内核下 ACPI PCI Hot-Plug 的实现机制(上) ACPI (Advanced Configuration and Power Interface) 是由业界一些软硬件公 司共同开发的开放式工业规范它能使软、硬件、操作系统(OS),主机板和外 围设备,依照一定的方式管理用电情况,系统硬件产生的 Hot-Plug 事件,让操 作系统从用户的角度上直接支配即插即用设备,不同于以往直接通过基于 BIOS 的方式的管理 一.ACPI 热拔插的简介 一.ACPI 热拔插的简介 由 INTEL,MICROSOFT 及 TOSHIBA 所共同开发而成的 ACPI(Advanced Configuration 4. ACPI 中 AML 的翻译器翻译和执行 AML 编码流过程 阅读下文的时候请对照 Linux ACPI 的源代码一同阅读: 五. 例子.执行型 ACPI 命令模式 五. 例子.执行型 ACPI 命令模式 例子 :ACPI 的核心层调用接口:status = acpi_evaluate_object (func->handle, “_EJ0“, ... ... 这里回调函数 acpi_ev_save_method_info 在扫描名字空间的时候被调用,按照 名字空间中针对 GPE 的描述,找到当前的需要实现响应的 GPE 节点初 始化 gpe_block 中有关 GPE 寄存器状态位的结构--event_info acpi_ev_save_method_info 回调函数找到_GPE 通用事件寄存器的描述节点,并 为在名字空间中通用事件寄存器的每个位安排相应的响 应,在 acpi_gpe_block_info 中有一个字段 event_info(事件消息描述结构)包含了每 个位所对应的名字空间中所执行的方法节点 (method_node 字段),如下: struct acpi_gpe_event_info { struct acpi_namespace_node *method_node; /* 当前GPE事件所需要在执 行的名字空间的方法节点,如上面例中的 Method(_L01)*/ acpi_gpe_handler handler; /* 执行的上层程序(驱动 程序层)句柄,例如某些时候在 PCI 设备进行热拔插的时候需要在插入后, 对资源进行重新分配,例如访问 ECDT 表(ACPI 嵌入式控制器专用),重新定义 PCI 配置空间并不需要再重新定义 Notify 的操作就直接通过这个句柄直接执行,例如某些 ACPI 嵌入式控制器的驱动中就 提供了 acpi_install_gpe_ handler 的接口来安装这个句柄*/ void *context; /* 代入的参数 */ struct acpi_gpe_register_info *register_info; /*指向当前 GPE 寄存器 组 */ u8 flags; /*响应的电平(边沿触发或 者是电平触发)*/ u8 bit_mask; /* GPEx_STS 的掩码 */ }; 例 1-4 GPE 寄存器在 Linux 中的数据描述结构 从上图看到通过 acpi_gpe_event_info 这个数据结构就把硬件上的状态寄存器 和名字空间中的方法节点对应起来了。

GPE 的事件响应机制:通常当事件寄存器有某个位发生变化的时候,如果相应的 使能寄存器的位表示这个位使能 (使能寄存器在 event_info 的 GPE 寄存器组 字 段 enable_address 寄存器表示),那么表示当前的事件响应会有效,然后引发 SCI 中断,任何 ACPI 中断都会引发 SCI 中断,它一般是一个普通 的 CPU 电平中 断(这个和 x86 系统的特征相关),低电平有效 在 ACPI 模块中函数 acpi_ev_handler_initialize 对 SCI 的中断句柄进行初始 化,通常在 Linux 的 ACPI 驱动中有每个中断一般会对应两个 GPE Block(对应 于两个不同的寄存器 GPE0_STS 和 GPE1_STS) ,另外还包括 gpe_block_list_head 和 acpi_gbl_gpe_xrupt_list_head 队列负责处理 SMP 的情况,它们的关系如下 图: 在 linux 的 ACPI 处理机制中 acpi_ev_sci_xrupt_handler 函数就是 SCI 中断处 理的句柄,所有 GPE 共享这个 SCI 中断句柄,在 acpi_ev_gpe_detect 函数中扫 描 acpi_gbl_gpe_xrupt_list_head 全局队列上挂的 GPE Block 检查事件状态, 并且分发到相关的事件的处理进程, 并根据当前使能状态寄存器来确定是否响应 当前事件,然后调用 acpi_os_queue_for_execution 这个 ACPI OS 层的执行过 程把当前的所需要执行的进程 acpi_ev_asynch_execute_gpe_method 放入当前 的 OS 中的执行队列中异步执行, 这个执行过程首先会检查当前寄存器合法性, 然后执行 GPE 的对应方法节点并清零 GPEx_STS,(调用 acpi_ns_evaluate_by_handle 执行)其过程和前面的执行型 ACPI 命令的处理过 程相同。

b.Notify 的方法执行/初始化过程:b.Notify 的方法执行/初始化过程: 在热拔插入的处理过程的名字空间中可以看到当一个 GPE 事件发生之后, 所调用 的方法节点通常会调用“NOFITY“操作符,通知 OSPM 进行处理: 通常一个 ASL 的通告操作表示如下: Notify(\_SB.PCI0.P2P2,0) \_SB.PCI0.P2P2 表示当 Hot Plug 阶段的该设备接收响应事件,0 表示 ACPI 向 OSPM 通告消息 BUS Check 通告, 通知 PCI 总线驱动层进行枚举 在热拔插中要用到以下的几个系统级别的通告消息如下(另外 0x80 以上是针对 具体设备对象通告,例如电池,温度控制,热拔插等设备): 表 1-1 设备对象的 OSPM 通告类型 通告值: 描述: 0 总线检查:设备对象出现,通知 OSPM,完成“Plug and Play“ 的枚举操作当收到通知时,OSPM 执行这个操作,在热拔插 的时候,由 ACPI AML 通过 Notify 的方式通知该值到 OSPM 1 设备检查:用于通知 OSPM,设备或出现或消失如果设备出 现,OSPM 将从设备节点的父节点“重新枚举(re-enumerate)“。

如果设备拔出,OSPM 将使设备的状态定为无效OSPM 可以优 化重新枚举的过程 2 设备唤醒: 用于通知 OSPM 设备发出了它的睡眠事件信号, OSPM 需要通知 OSPM 的本地设备驱动,此情况仅用于支持_PRW 的设 备 3 拔出要求:用以通知 OSPM 设备应被弹出,同时 OSPM 需要执行 “Plug and Play 弹出操作“,与此同时 OSPM 将运行_Ejx 方法 6 总线模式错配:用以通知 OSPM 设备被插入一个非当前操作模 式的槽或背板中例如:当用户试图将一个 PCI 设备热插入一 个运行在 PCI-X 模式下的总线的槽中 7 电源故障:用以通知 OSPM,设备由于电源故障不能从 D3 状态 下转出 前 面说了,执行对象节点方法和前面的执行型的 ACPI 命令的处理过程相同,这 里只详细介绍 Notify 操作,这个操作是底层(ACPI 层)向上层(驱动层) 通 告当前消息,它和普通的命令形操作没有本质上的区别,但由于向操作系统层通 告消息,所以要调用一些 ACPI OS 部分的 API;和上面介绍的_EJ0 方法一样,最 后会根据操作符的描述集合 op_info 执行句柄 acpi_ex_opcode_2A_0T_0R, 在 这个执行例程中会进一步根据 NOTIFY 的通告值分发到处理过程,相关的处理过 程是异步执行的,因为最终而言,会调用到 acpi_os_queue_for_execution 这 个 ACPI OS 层的执行接口,它在 Linux 中执行方式就是把需要执行的任务(而 acpi_ev_notify_ dispatch 调用 NOTIFY 节点对象的实际执行者)插入任务队列 中,不过在某些采用实时的 Linux 系统场合,有一些人会把它插入到立即队列中 (Immediate Task Queue),两者实现的效果是相同的。

对于一个 NOTIFY 节点来说,其节点对象类型是 struct acpi_object_notify_common common_notify 类型,通常它的内部关键的字段如 下表示: ... union acpi_operand_object *system_notify; /* 系统的消息通告 */ union acpi_operand_object *device_notify; /* 设备消息通告*/ union acpi_operand_object *handler; /* 地址空间中的中的执 行句柄 */ ... acpi_operand_object 这个结构内都包含一个代表消息执行句柄的 acpi_object_notify_handler 结构,其中的 handler,node,context 字 段分 别表示针对当前通告的执行句柄,当前执行句柄所对应设备的名字空间节点,以 及执行句柄带入的参数; common_notify 结构会在驱动程序初始化时候安装 acpi_object_notify_handler 中对应事件操作句柄,操作系统驱动程序会调用 ACPI 提供的接口 acpi_install_notify_handler 完成这个的动作,使用这个接 口可以屏蔽掉一些作为驱动设计者无须知道的硬件和 ACPI 层的细节: 在下面是该函数在 Linux 中的原型: acpi_status acpi_install_notify_handler ( acpi_handle device, u32 handler_type, acpi_notify_handler handler, void *context ) 1. 第一个参数 acpi_handle 是需要接收通告的设备句柄; 2. 第二个参数 handler_type 表示当前设备可以处理的消息号类型,分成设备 类型和系统类型两种; 3. acpi_notify_handler 表示执行消息的回调函数; 4. 回调函数的带入参数。

--详见 acpi_install_notify_handler 的源代码,它的流程和结构都非常简单, 这里就不再详叙了 七. Linux 操作系统驱动程序如何调用 ACPI 核心层接口以及 Hot Plug 事件的 执行过程 七. Linux 操作系统驱动程序如何调用 ACPI 核心层接口以及 Hot Plug 事件的 执行过程 a.系统初始化阶段: 在 上电阶段在 PCI 设备的扫描节点,。

下载提示
相似文档
正为您匹配相似的精品文档