1). acpi_early_init()何时执行
2.6.22中,start_kernel() > acpi_early_init() > rest_init()
> kernel_init(KERNEL THREAD) > do_basic_setup() > do_initcalls()
可见,acpi_early_init()比带有__init属性的函数执行得要早。 另外,注释说:acpi_early_init() is before LAPIC and SMP init.
SMP和LAPIC的初试化在哪里呢?答曰:
start_kernel() > rest_init() > kernel_init() > smp_prepare_cpus() > smp_ops.smp_prepare_cpus() [这个即是native_smp_prepare_cpus()] > smp_boot_cpus() > setup_local_APIC() > smpboot_setup_io_apic()
2). acpi_early_init()都干了些什么 ...
status = acpi_reallocate_root_table(); /* 在dynamic memory中申请ACPI tables的空间
,然后从别处把它们copy过来 */
...
status = acpi_initialize_subsystem(); /* 初试化所有ACPI相关的全局变量 */ ...
status = acpi_load_tables(); /* 从DSDT/SSDTs/PSDT表获取数据,构建ACPI namespace */ ...
3). 看看acpi_reallocate_root_table()函数 ...
struct acpi_table_desc *tables; acpi_size new_size; ...
new_size = (acpi_gbl_root_table_list.count +
ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc);
tables = ACPI_ALLOCATE_ZEROED(new_size); /*在linux下该宏的功能相当于kzalloc()函数*/
ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size); /* memcpy */ ...
4). PCI设备的IRQ Routing
有个带__init属性的pci_acpi_init()函数,它有这么2句:
pcibios_enable_irq = acpi_pci_irq_enable;
pcibios_disable_irq = acpi_pci_irq_disable;
而这两个函数指针类型的变量,其原型为:
int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL;
这两行赋值代码,其作用要等到PCI驱动程序调用pci_enable_device()和pci_disable_device()的 时候,才能真正发挥出来:
pci_enable_device() > pci_enable_device_bars() > do_pci_enable_device() > pcibios_enable_device() > pcibios_enable_irq() -- 在这里,调用的就是 acpi_pci_irq_enable()
Linux定义的PCI IRQ Routing Table:
struct acpi_prt_entry { struct list_head node; struct acpi_pci_id id; u8 pin; struct {
acpi_handle handle; u32 index; } link; u32 irq; };
struct acpi_prt_list { int count;
struct list_head entries; };
static struct acpi_prt_list acpi_prt;
struct acpi_pci_routing_table { u32 length; u32 pin;
acpi_integer address; u32 source_index; char source[4]; }; /*
* XXX *
* Type 1: Dynamic
* the 'source' field specifies the PCI interrupt link * device used to configure the IRQ assigned to this * slot|dev|pin. the 'source_index' field incicates which * resource descriptor in the resource templeate(of the * link device) this interrupt is allocated from. * *
* Type 2: Static
* The 'source' field is NULL, and the 'source_index' field * specifies the IRQ value, which is hardwired to specific * interrupt inputs on the interrupt controller.
*/
参考acpi_pci_irq_add_entry()函数。
/*}}}*/
51.1) ACPI和Linux设备驱动模型的集成//FIXME: 我还不理解!!
/*{{{*/
static struct acpi_driver acpi_pci_root_driver = { .name = \
.class = ACPI_PCI_ROOT_CLASS, .ids = ACPI_PCI_ROOT_HID, .ops = {
.add = acpi_pci_root_add, .remove = acpi_pci_root_remove, .start = acpi_pci_root_start, }, };
struct acpi_driver { char name[80]; char class[20];