/* * Activate a secondary processor. */ static void __init start_secondary(void *unused) { /* * Dont put anything before smp_callin(), SMP * booting is too fragile that we want to limit the * things done here to the most necessary things. */ cpu_init(); smp_callin(); while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) rep_nop(); setup_secondary_APIC_clock(); if (nmi_watchdog == NMI_IO_APIC) { disable_8259A_irq(0); enable_NMI_through_LVT0(NULL); enable_8259A_irq(0); } enable_APIC_timer(); /* * low-memory mappings have been cleared, flush them from * the local TLBs too. */ local_flush_tlb(); cpu_set(smp_processor_id(), cpu_online_map); /* We can take interrupts now: we're officially "up". */ local_irq_enable(); wmb(); cpu_idle(); }
void switch_ipi_to_APIC_timer(void *cpumask) { cpumask_t mask = *(cpumask_t *)cpumask; int cpu = smp_processor_id(); if (cpu_isset(cpu, mask) && cpu_isset(cpu, timer_bcast_ipi)) { cpu_clear(cpu, timer_bcast_ipi); enable_APIC_timer(); } }
/* * Activate a secondary processor. */ void __init start_secondary(void) { /* * Dont put anything before smp_callin(), SMP * booting is too fragile that we want to limit the * things done here to the most necessary things. */ cpu_init(); smp_callin(); /* otherwise gcc will move up the smp_processor_id before the cpu_init */ barrier(); Dprintk("cpu %d: waiting for commence\n", smp_processor_id()); while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) rep_nop(); Dprintk("cpu %d: setting up apic clock\n", smp_processor_id()); setup_secondary_APIC_clock(); Dprintk("cpu %d: enabling apic timer\n", smp_processor_id()); if (nmi_watchdog == NMI_IO_APIC) { disable_8259A_irq(0); enable_NMI_through_LVT0(NULL); enable_8259A_irq(0); } enable_APIC_timer(); /* * low-memory mappings have been cleared, flush them from * the local TLBs too. */ local_flush_tlb(); Dprintk("cpu %d eSetting cpu_online_map\n", smp_processor_id()); cpu_set(smp_processor_id(), cpu_online_map); wmb(); cpu_idle(); }