ACPICA User Guide and Programmer Reference 翻译8
2.4异常处理
任何在处理ACPICA子系统请求时发生的异常都会被以ACPI_STATUS作为返回码反馈给调用者。每一个由ACPICA引发的异常都将以'AE_'的形式出现
所有异常处理都通过ACPICA子系统接口进行整合。对于以Acpi和AcpiOs开头的调用不具备相应的异常处理功能。
3.2.5 多任务和可重入
ACPICA子系统的各个组件均应具备可复用性,并且支持多线程功能。为了达到可复用性和多线程的目标,在OSL的设计中必须参考特定主操作系统的操作原语来构建互斥访问接口,并以此为基础确保同步与异常处理的有效运行。尽管在构建互斥访问接口的过程中存在挑战,
但ACPICA子系统的各个组件仍具备可复用性和多线 thread的支持能力。
AML翻译器是一个例外。
解释如下。
受ACPI协议规定,在任何时间段内最多允许单一控制方法运行;当某个控制方法在其运行过程中遇到障碍(在特定条件下可能发生)时,则应允许其他所有主控模块继续进行操作;无论如何而言,该协议均阻碍了多线程处理能力的发展;基于上述分析,在ACPICA子系统的所有组件中,默认情况下AML编译器实现并行性受到严格限制;对于来自不同主控模块的内部或外部请求处理顺序的问题,则应由系统的前置处理逻辑进行协调安排
3.2.6 事件处理
'事件处理'这一术语具体涵盖在ACPICA子系统执行过程中的异步事件。这些具体包括实时响应机制以及状态转换流程。
- 由ACPI固定的以及通用事件被SCI所触发。
- 在执行ASL中的Notify关键字所代表的控制方法时所导致的通知事件。
- 在执行控制方法的过程中因访问地址空间或操作域而触发的相关事件。
对每个事件的描述和ACPICA子系统对此类事件的支持情况,请具体说明。
3.2.6.1 固定事件
固定事件由ACPICA子系统的默认事件处理handler负责处理,并针对每个具体事件可配置独立的handler。仅当涉及设备驱动或系统服务时才需配置此类特定类型的handler
3.2.6.2通用事件
通用事件通常主要通过触发相关控制方法来实现响应。根据ACPI协议规定,在不同级别上都会有对应的控制方法可供使用。其中采用_Exx命名的属于边沿触发方式而采用_Lxx命名的则是电平触发方式这些命名方式均基于十六进制编号系统(具体细节可见ACPI协议说明)。该特定控制方法无法在SCI中断handler所在的上下文中进行处理但会在主操作系统被入队列后延迟处理。
除了该机制之外,
不同等级别的GPE可各自配备专用handler,
并非强制要求每个设备都必须配备独立的手动器,
具体来说,
现在仅需配备独立的手动器的是ACPI EC类型,
通过EC驱动系统,在其管理范围内将所有属于该EC类别的GPE配置上专用的手动器。
当GPE安装了handler时,该handler将采用优先级机制,无需依赖Exx/Lxx接口
此外支持GPE块设备(GPE Block Devices)。根据需求灵活配置的这些块能够被动态地进行安装与卸载。ACPICA子系统负责对所有运行中的GPE进行集中处理与资源分配,并通过提供相应的接口实现了对新增或已有的GPE块设备的动态安装与卸载功能。
3.2.6.3 通知事件
在执行控制方法的过程中,当Notify操作码被执行时会触发一个ACPI通知事件。这个通知事件基于一个特定的ACPI对象(必须是某个设备或者热区)。如果对该设备安装了相应的notification handler,在Execute Notify操作码的过程中,请注意该handler将在同一线程中处理该控制方法的上下文。
由设备驱动的handler被安装,并且这些系统服务能够识别相关设备及其对应的热区以触发相应的通知事件。
3.2.7 地址空间和操作域
ASL源代码和相应的AML代码能够采用地址空间机制来操作不属于ASL scope的数据。例如,这些地址空间被用来执行CMOS RAM和ACPI EC的操作。这些预先配置好的地址空间区域同时支持用户根据需求创建自己的地址空间区域。
该系统支持通过带有AML翻译器的ASL架构管理多个内存区域。当配置OpRegion时, ASL程序员设置为能够处理的内存范围及其相关地址空间。随后, 在窗口内的所有内存位置都通过字段中的字符串进行标识.
3.2.7.1 安装地址空间handler
当运行时,在完成对地址空间的handler配置后, ASL/AML代码方能访问该地址空间. ACPICA用户可选择配置默认位置的地址空间handler, 并可通过AcpiInstallAddressSpaceHandler接口自定义设置其位置.
每个地址空间均被特定设备拥有,在其对应的设备范围内对这些地址空间引用的行为将由其对应的handler进行处理。该机制允许多个类别的地址空间或操作域通过不同的handler实现管理。基于预定义的范围规则(Scope Rules),每个handler都是独立且互不干扰的。考虑两个SMBus设备:一个采用EC接口配置而另一个采用PCI总线配置的情况。每一个SMBus设备都会向其父系统(ASL)声明自身的地址空间范围,并与对方互不干扰。在这种情况下,则需要分别针对每种类型配置相应的驱动程序和多个独立的手动处理器(handlers)。同样地,在PCI总线范围内创建操作域时也会遵循这一原则。
地址空间handler必须被命名为对象或位于ACPI_ROOT_OBJECT。
为了维持命名空间的有效范围规则而设立。
地址handler的作用对象是在具有地址空间的对象上。
每个ASL规则都需要对相应域进行操作。
ACPICA使用者需要枚举命名空间并根据需要安装地址handler。
3.2.7.2ACPI相关的地址空间
ACPI协议会为如下类型地址定义地址空间:
1. 系统I/O接口
2. PCI总线配置空间
3. 系统管理总线(SMBus)
4. 嵌入式控制器
5. CMOS
6. PCI条带目标点
7. IPMI协议(ACPI 4.0)
8. 通用目的I/O(ACPI 5.0)
9..
ACPICA子系统会为下面的地址空间实现默认的地址空间handler:
- System Memory
- System I/O
- PCI Configuration Space
在调用AcpiInstallAddressSpaceHandler接口时,建议将ACPI_DEFAULT_HANDLER指定为handler地址,并支持采用默认的地址空间handler。
除了预先定义的标准地址空间(如EC和SMBus)外,在没有默认配置的情况下,默认不会为这些标准地址空间分配一个地址空间handler。因此,在这种情况下,默认情况下未被操作系统支持的这些标准地址空间无法被正确操作。通常情况下,默认配置下的这些标准地址空间handler由来自EC、SMBus以及与 ACPI相关的设备驱动程序生成。
3.2.7.3 设备驱动和AML共享资源
在特定场景下,由API接口(API interface)指导的驱动程序与相应的相关代码库需共同利用设备寄存器、内存等系统资源。
该机制由ACPICA实现,并赋予设备驱动单元对内存和寄存器的访问权限。当AML执行相关操作时将导致进入该驱动状态以完成相关功能。自定义地址空间handler则负责处理共享资源的分配与管理。
这些代码都能赋予每个设备独立的地址空间handler以实现互斥访问需求。该方案确保了在ACPI命名空间下每个设备都能获得唯一的地址空间映射。当设备运行ASL指令并操作寄存器或内存时(通过操作域),系统将自动切换至该设备的独立地址空间映射以完成相关操作。从而实现对该共享资源的全面控制。
注释表明,在配置了特定自定义地址空量 handler后
3.2.7.3.1 ASL共享资源实例
该代码片段定义并执行了输入输出域以及一组共享I/O寄存器(COST和VREG)。
Scope (_SB)
{
Device (PCI0)
{
Name (_HID, EisaId ("PNP0A08")) // _HID: Hardware ID
Device (PS2K)
{
Name (_HID, EisaId ("PNP0303")) // _HID: Hardware ID
OperationRegion (PKBS, SystemIO, 0x60, 0x05)
Field (PKBS, WordAcc, Lock, Preserve)
{
COST, 16,
VREG, 16
}
Method (_AC0, 0, NotSerialized)
{
And (COST, 0xFFFF, COST)
Store (0x1234, VREG)
Or (COST, 0xFFF6, COST)
Store (COST, Debug)
Return (COST)
}
}
}
}
3.2.7.3.2自定义地址空间handler安装
为了深入并行操作上例中定义的寄存器,设备驱动必须访问ACPI命名空间中的设备,并为其配置一个自定义地址空间handler。一旦为该设备配置了一个自定义地址空间handler,ASL/AML中所有通过COST和VREG I/O端口所涉及的操作将被转移到驱动内部进行处理。
Status = AcpiGetHandle (NULL, "\ _SB.PCI0.PS2K", &ObjHandle);
Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_IO,
RegionHandler, RegionInit, MyContext);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Could not install an OpRegion handler for PS2K device (%p)",
ObjHandle));
}
通过acpiexec工具运行‘handlers’命令后可以看到对_SB_.PCI0.PS2K自定义handler已经被成功安装
- handlers
Operation Region Handlers at the namespace root:
SystemMemory (00) : User (00422A30) /* default acpiexec handler */
SystemIO (01) : User (00422A30) /* default acpiexec handler */
Operation Region Handlers for specific devices:
SystemIO (01) : User (00422280) Device Name: _SB_.PCI0.PS2K
采用该方法能够进行操作于处于该操作域内的I/O寄存器。通过观察可以发现相关自定义系统端口控制器被频繁调用。
- evaluate _SB_.PCI0.PS2K._AC0
Evaluating _SB_.PCI0.PS2K._AC0
ACPI: PCI0.PS2K SystemIO request at: 0x0000000000000060 [READ]
ACPI: PCI0.PS2K SystemIO request at: 0x0000000000000060 [WRITE]
ACPI: PCI0.PS2K SystemIO request at: 0x0000000000000062 [WRITE]
ACPI: PCI0.PS2K SystemIO request at: 0x0000000000000060 [READ]
ACPI: PCI0.PS2K SystemIO request at: 0x0000000000000060 [WRITE]
ACPI: PCI0.PS2K SystemIO request at: 0x0000000000000060 [READ]
[ACPI Debug] Integer 0x0000000000000000
ACPI: PCI0.PS2K SystemIO request at: 0x0000000000000060 [READ]
Evaluation of _SB_.PCI0.PS2K._AC0 returned object 00323EC8, buffer length 10
[Integer] = 0000000000000000
