void cpu_wakeup_aps(void) { int i; struct cpu_info *cpu; unsigned cpuid = cpu_number_from_lapic(); cmos_write(0xf, 0xa); // Shutdown causes warm reset. for (i = 0; i < number_cpus; i++) { if (i == cpuid) continue; cpu = cpuinfo_get(i); printf("Waking up CPU %02d...", i); /* Setup AP bootstrap page */ memcpy((void *) (UKERNBASE + UKERN_APBOOT(i)), &_ap_start, (size_t) & _ap_end - (size_t) & _ap_start); /* Setup Warm Reset Vector */ *(volatile uint16_t *) (UKERNBASE + 0x467) = UKERN_APBOOT(i) & 0xf; *(volatile uint16_t *) (UKERNBASE + 0x469) = UKERN_APBOOT(i) >> 4; /* INIT-SIPI-SIPI sequence. */ lapic_ipi(cpu->phys_id, APIC_DLVR_INIT, 0); _delay(); lapic_ipi(cpu->phys_id, APIC_DLVR_START, UKERN_APBOOT(i) >> 12); _delay(); lapic_ipi(cpu->phys_id, APIC_DLVR_START, UKERN_APBOOT(i) >> 12); _delay(); printf(" done\n"); } }
void cpu_nmi(int cpu) { struct cpu_info *ci = cpuinfo_get(cpu); if (ci == NULL) return; lapic_ipi(ci->phys_id, APIC_DLVR_NMI, 0); }
void cpu_ipi(int cpu, uint8_t vct) { struct cpu_info *ci = cpuinfo_get(cpu); if (ci == NULL) return; lapic_ipi(ci->phys_id, APIC_DLVR_FIX, vct); }
void *sched_bsp_idle_thread (void *notused) { interrupts_disable(); clockeventer_subsystem_init(); pit_timer_init(); lapic_bsp_pre_init(); pci_init(); rtc_init(); keyboard_init(); lapic_common_init(); #ifdef CONFIG_ACPICA acpica_sub_system_init (); pci_scan_devices(); #endif clockcounter_subsystem_init(); timerchain_subsystem_init(); real_wall_time_init(); tick_eventer_init(); lapic_bsp_post_init(); interrupts_enable(); thread_create_test(); lapic_ipi(1, 0, INTR_LAPIC_RESCHEDULE); cpu_heart_beat(this_cpu()); }