diff options
author | AlmuHS <liberamenso10000@gmail.com> | 2018-07-07 13:56:08 +0200 |
---|---|---|
committer | AlmuHS <liberamenso10000@gmail.com> | 2018-07-07 13:56:08 +0200 |
commit | 9df303866d9a1516fa9ac8ce6c9e61187ad2fcbe (patch) | |
tree | ea61424706ec31cdeb9b8052aa30f1df033e54ec | |
parent | edd71a6891d0c2e4686f3e64b27a9d9840f47a1a (diff) | |
parent | 659b91ba1539dd239e4fbf40905349732277c1ba (diff) |
Merge remote-tracking branch 'refs/remotes/origin/smp' into smp
upload changes
-rw-r--r-- | i386/i386/intel_startCPU.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/i386/i386/intel_startCPU.c b/i386/i386/intel_startCPU.c new file mode 100644 index 00000000..279721b8 --- /dev/null +++ b/i386/i386/intel_startCPU.c @@ -0,0 +1,68 @@ +#include <kern/kmutex.h> +#include <kern/cpu_number.h> +#include <i386/gdt.h> +#include <i386/ldt.h> +#include <i386/i386/pcb.h> +#include <i386/i386/tss.h> + +kern_return_t intel_startCPU( + int slot_num) +{ + int lapic = cpu_to_lapic[slot_num]; + int eFlagsRegister; + + assert(lapic != -1); + + DBGLOG_CPU_INIT(slot_num); + + DBG("intel_startCPU(%d) lapic_id=%d\n", slot_num, lapic); + DBG("IdlePTD(%p): 0x%x\n", &IdlePTD, (int) (uintptr_t)IdlePTD); + + /* + * Initialize (or re-initialize) the descriptor tables for this cpu. + * Propagate processor mode to slave. + */ + cpu_desc_init64(cpu_datap(slot_num)); + + /* Serialize use of the slave boot stack, etc. */ + kmutex_lock(&mp_cpu_boot_lock); + + /*istate = ml_set_interrupts_enabled(FALSE);*/ + cpu_intr_save(&eFlagsRegister); + if (slot_num == cpu_number()) { + /*ml_set_interrupts_enabled(istate);*/ + cpu_intr_restore(eFlagsRegister); + lck_mtx_unlock(&mp_cpu_boot_lock); + return KERN_SUCCESS; + } + + start_info.starter_cpu = cpu_number(); + start_info.target_cpu = slot_num; + start_info.target_lapic = lapic; + tsc_entry_barrier = 2; + tsc_exit_barrier = 2; + + /* + * Perform the processor startup sequence with all running + * processors rendezvous'ed. This is required during periods when + * the cache-disable bit is set for MTRR/PAT initialization. + */ + mp_rendezvous_no_intrs(start_cpu, (void *) &start_info); + + start_info.target_cpu = 0; + + /*ml_set_interrupts_enabled(istate);*/ + cpu_intr_restore(eFlagsRegister); + lck_mtx_unlock(&mp_cpu_boot_lock); + + if (!cpu_datap(slot_num)->cpu_running) { + kprintf("Failed to start CPU %02d\n", slot_num); + printf("Failed to start CPU %02d, rebooting...\n", slot_num); + delay(1000000); + halt_cpu(); + return KERN_SUCCESS; + } else { + kprintf("Started cpu %d (lapic id %08x)\n", slot_num, lapic); + return KERN_SUCCESS; + } +} |