summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlmuHS <liberamenso10000@gmail.com>2018-07-07 13:56:08 +0200
committerAlmuHS <liberamenso10000@gmail.com>2018-07-07 13:56:08 +0200
commit9df303866d9a1516fa9ac8ce6c9e61187ad2fcbe (patch)
treeea61424706ec31cdeb9b8052aa30f1df033e54ec
parentedd71a6891d0c2e4686f3e64b27a9d9840f47a1a (diff)
parent659b91ba1539dd239e4fbf40905349732277c1ba (diff)
Merge remote-tracking branch 'refs/remotes/origin/smp' into smp
upload changes
-rw-r--r--i386/i386/intel_startCPU.c68
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;
+ }
+}