3.2执行模式
3.2.1初始化
ACPICA子系统的初始化完全由主操作系统驱动。由于可能在不同的时间点初始化ACPICA子系统的不同部分(取决于主操作系统的要求),初始化被分为多步进行。下面是四个主要步骤。
- 全局初始化ACPICA子系统——初始化全局数据和其他部分。
- 初始化表管理功能,加载ACPI表——在可以构建内部命名空间之前,FADT,FACS,DSDT和SSDT表必须被实现并被映射。这些表项可以从固件中被加载、从输入buffer中被加载或者以固件和输入buffer两者的组合形式被加载。RSDT/XSDT,FADT,FACS和DSDT表是必须被实现的。所有SSDT表都是可选的。ACPICA子系统不会直接使用在ACPI协议中定义的其他所有的表,但是ACPI相关的设备驱动会通过表管理(table manager)的外部接口来使用。像这样的表有MADT,ECDT等等。
- 创建内部命名空间——这回使ACPICA通过解析DSDT和所有SSDT中的对象来创建命名空间。
使能设备的ACPI模式。在ACPI事件(ACPI events)发生前,设备必须进入ACPI模式。ACPICA子系统为SCI(SCIs)中断注册中断handler,并将硬件由legacy模式转为ACPI模式。
3.2.2 内存分配
有两种内存分配模式。第一种,由ACPICA子系统的调用者预先分配需要的内存。这种方式为调用者提供了最大的灵活性,因为,只有调用者知道从哪个内存池分配比较合适、是动态分配还是静态分配等等。第二种,调用者可以通过使用AcpiOsAllocate接口来让ACPICA子系统来分配,尽管这种方式不太灵活,但是这种方式比较容易使用,并且大部分环境中都适用这种方式。内存分配模式描述如下.
3.2.2.1调用者分配所有buffer
对于这种模式,调用者预先分配足够大的buffers,并将这些buffers作为ACPI_BUFFER类型的数据提供给ACPICA子系统。
通常,调用者和ACPICA子系统都不知道需要的buffer的大小。得等到确定对象(evaluation of an object)和控制方法执行完成才行。因此,通过独立的接口获取需要的缓存大小的模式是不行的。相反,需要一个允许调用者提前分配足够大的buffer的模式,这个模式如下。
对于使用ACPI_BUFFER作为返回参数类型的ACPI接口,下面的步骤能够用于确定需要的缓存的大小:
- 将ACPI_BUFFER数据结构的长度域设置为零,或者设置为本环境下的缓存的大小,这个大小应该足够大。
- 调用ACPI接口。
- 如果异常返回值为AE_BUFFER_OVERFLOW,则ACPI_BUFFER 的长度域被接口设置为实际需要的大小。
- 分配一个缓存,并初始化ACPI_BUFFER的长度域和缓存指针。
- 使用具有有效长度值和有效缓存的ACPI_BUFFER数据结构再一次调用Acpi 接口。
如果调用者知道需要的缓存的大小,那么,可以直接使用这个大小来调用Acpi接口。如果调用返回失败,则需要分配一个更大的缓存。参考6.2.6小节——“ACPI_BUFFER – Input and Output Memory Buffers”来获取更多关于如何使用ACPI_BUFFER数据结构的信息。
3.2.2.2 ACPICA子系统分配需要返回的缓存的大小
对于这种模式,调用者让ACPICA子系统分配需要返回的缓存的大小。调用者需要释放这些缓存。
对于使用ACPI_BUFFER作为返回参数类型的ACPI接口,下面的步骤用于ACPICA子系统分配需要返回的缓存:
- 设置ACPI_BUFFER结构的长度域为ACPI_ALLOCATE_BUFFER。
- 调用Acpi接口。
- 如果返回的异常值为AE_OK,表明接口返回正常并且分配了一个缓存。缓存的大小保存在ACPI_BUFFER结构中。
- 使用ACPI_BUFFER中的缓存指针调用AcpiOsFree来释放缓存(不要使用ACPI_FREE)。
3.2.3 参数有效性
传递到ACPICA子系统的所有的输入参数,需要进行有限项的有效性检查。因此,在将参数传递到ACPICA子系统的代码中之前,主操作系统应该对缓存指针、字符串和其他输入参数限度和范围进行检查。
有限项的有效性检查包括空指针检查、数据超过数据类型能够表示的范围检查。其他参数的有效性(例如缓存长度有效性检查)必须在调用ACPICA代码之前完成。