ARM64 AP核MAILBOX地址的初始化和启动过程(Parking protocol)
start_kernel
-> setup_arch
-> smp_init_cpus
-> acpi_table_parse_madt( ACPI_MADT_TYPE_GENERIC_INTERRUPT,acpi_parse_gic_cpu_interface, 0);
-> acpi_table_parse_entries(ACPI_SIG_MADT)
-> acpi_parse_entries
-> 遍历ACPI中标明的所有CORE,对每个core调用handler(entry, table_end) 也就是acpi_parse_gic_cpu_interface
acpi_parse_gic_cpu_interface
-> acpi_map_gic_cpu_interface
-> arm64_cpu_parking_addr[cpu_count] = processor->parked_address; //将当前处理器的mailbox地址初始化为parked_address;
在smp_init中,会对每个AP核调用boot_secondary
boot_secondary
-> cpu_ops[cpu]->cpu_boot(cpu); //对于Parking protocol,调用smp_parking_protocol_cpu_boot
-> mailbox = ioremap_cache(arm64_cpu_parking_addr[cpu], sizeof(*mailbox)); //得到mailbox映射的虚拟地址
writeq(__pa(secondary_entry), &mailbox->entry_point); //写入AP核启动地址
writel(cpu, &mailbox->cpu_id); // 写入目标AP核
__smp_boot_wakeup(cpu);//对于GICV3 在gic_smp_init中初始化为 gic_wakeup_parked_cpu,也就是调用gic_wakeup_parked_cpu
gic_wakeup_parked_cpu
-> gic_raise_softirq(cpumask_of(cpu), 0); //发送软中断,通知AP核启动
start_kernel
-> setup_arch
-> smp_init_cpus
-> acpi_table_parse_madt( ACPI_MADT_TYPE_GENERIC_INTERRUPT,acpi_parse_gic_cpu_interface, 0);
-> acpi_table_parse_entries(ACPI_SIG_MADT)
-> acpi_parse_entries
-> 遍历ACPI中标明的所有CORE,对每个core调用handler(entry, table_end) 也就是acpi_parse_gic_cpu_interface
acpi_parse_gic_cpu_interface
-> acpi_map_gic_cpu_interface
-> arm64_cpu_parking_addr[cpu_count] = processor->parked_address; //将当前处理器的mailbox地址初始化为parked_address;
在smp_init中,会对每个AP核调用boot_secondary
boot_secondary
-> cpu_ops[cpu]->cpu_boot(cpu); //对于Parking protocol,调用smp_parking_protocol_cpu_boot
-> mailbox = ioremap_cache(arm64_cpu_parking_addr[cpu], sizeof(*mailbox)); //得到mailbox映射的虚拟地址
writeq(__pa(secondary_entry), &mailbox->entry_point); //写入AP核启动地址
writel(cpu, &mailbox->cpu_id); // 写入目标AP核
__smp_boot_wakeup(cpu);//对于GICV3 在gic_smp_init中初始化为 gic_wakeup_parked_cpu,也就是调用gic_wakeup_parked_cpu
gic_wakeup_parked_cpu
-> gic_raise_softirq(cpumask_of(cpu), 0); //发送软中断,通知AP核启动