//------------------------------------------------------------------------ IMPLEMENTATION[(ia32,amd64) && mp]: #include <cstdio> #include "apic.h" #include "app_cpu_thread.h" #include "config.h" #include "cpu.h" #include "div32.h" #include "fpu.h" #include "globals.h" #include "ipi.h" #include "kernel_task.h" #include "processor.h" #include "per_cpu_data_alloc.h" #include "perf_cnt.h" #include "platform_control.h" #include "spin_lock.h" #include "utcb_init.h" int FIASCO_FASTCALL boot_ap_cpu() __asm__("BOOT_AP_CPU"); int FIASCO_FASTCALL boot_ap_cpu() { Cpu_number _cpu = Apic::find_cpu(Apic::get_id()); bool cpu_is_new = false; static Cpu_number last_cpu; // keep track of the last cpu ever appeared if (_cpu == Cpu_number::nil()) { _cpu = ++last_cpu; // 0 is the boot cpu, so pre increment cpu_is_new = true; } if (cpu_is_new && !Per_cpu_data_alloc::alloc(_cpu)) { extern Spin_lock<Mword> _tramp_mp_spinlock; printf("CPU allocation failed for CPU%u, disabling CPU.\n", cxx::int_value<Cpu_number>(_cpu)); _tramp_mp_spinlock.clear(); while (1) Proc::halt(); } if (cpu_is_new) Per_cpu_data::run_ctors(_cpu); Cpu &cpu = Cpu::cpus.cpu(_cpu); Idt::load(); if (cpu_is_new) { Kmem::init_cpu(cpu); Apic::init_ap(); Apic::apic.cpu(_cpu).construct(_cpu); Ipi::init(_cpu); } else { cpu.pm_resume(); Pm_object::run_on_resume_hooks(_cpu); } Timer::init(_cpu); if (cpu_is_new) { Apic::check_still_getting_interrupts(); Platform_control::init(_cpu); } if (Koptions::o()->opt(Koptions::F_loadcnt)) Perf_cnt::init_ap(); // create kernel thread Kernel_thread *kernel = App_cpu_thread::may_be_create(_cpu, cpu_is_new); main_switch_ap_cpu_stack(kernel, !cpu_is_new); return 0; }
//------------------------------------------------------------------------ IMPLEMENTATION[(ia32,amd64) && mp]: #include <cstdio> #include "apic.h" #include "app_cpu_thread.h" #include "config.h" #include "cpu.h" #include "div32.h" #include "fpu.h" #include "globals.h" #include "ipi.h" #include "kernel_task.h" #include "processor.h" #include "per_cpu_data_alloc.h" #include "perf_cnt.h" #include "spin_lock.h" #include "utcb_init.h" int FIASCO_FASTCALL boot_ap_cpu(unsigned _cpu) __asm__("BOOT_AP_CPU"); int FIASCO_FASTCALL boot_ap_cpu(unsigned _cpu) { if (!Per_cpu_data_alloc::alloc(_cpu)) { extern Spin_lock<Mword> _tramp_mp_spinlock; printf("CPU allocation failed for CPU%u, disabling CPU.\n", _cpu); _tramp_mp_spinlock.clear(); while (1) Proc::halt(); } Per_cpu_data::run_ctors(_cpu); Cpu &cpu = Cpu::cpus.cpu(_cpu); Kmem::init_cpu(cpu); Idt::load(); Utcb_init::init_ap(cpu); Apic::init_ap(); Ipi::cpu(_cpu).init(); Timer::init(); Apic::check_still_getting_interrupts(); // caution: no stack variables in this function because we're going // to change the stack pointer! cpu.print(); cpu.show_cache_tlb_info(""); if (Koptions::o()->opt(Koptions::F_loadcnt)) Perf_cnt::init_ap(); puts(""); // create kernel thread App_cpu_thread *kernel = new (Ram_quota::root) App_cpu_thread(); set_cpu_of(kernel, _cpu); check(kernel->bind(Kernel_task::kernel_task(), User<Utcb>::Ptr(0))); main_switch_ap_cpu_stack(kernel); return 0; }