Skip the shitty e1000s on c89
[akaros.git] / kern / arch / x86 / smp_boot.c
index 103f601..f08b997 100644 (file)
@@ -62,10 +62,30 @@ static void init_smp_call_function(void)
 
 void smp_final_core_init(void)
 {
+       /* It is possible that the non-0 cores will wake up before the broadcast
+        * ipi.  this can be due to spurious IRQs or some such.  anyone other than
+        * core 0 that comes in here will wait til core 0 has set everything up */
+       static bool wait = TRUE;
+       if (get_os_coreid(hw_core_id()) == 0)
+               wait = FALSE;
+       while (wait)
+               cpu_relax();
 #ifdef CONFIG_FAST_COREID
        /* Need to bootstrap the rdtscp MSR with our OS coreid */
        int coreid = get_os_coreid(hw_core_id());
        write_msr(MSR_TSC_AUX, coreid);
+
+       /* Busted versions of qemu bug out here (32 bit) */
+       int rdtscp_ecx;
+       asm volatile ("rdtscp" : "=c"(rdtscp_ecx) : : "eax", "edx");
+       if (read_msr(MSR_TSC_AUX) != rdtscp_ecx) {
+               printk("Broken rdtscp detected!  Rebuild without CONFIG_FAST_COREID\n");
+               if (coreid)
+                       while(1);
+               /* note this panic may think it is not core 0, and core 0 might not have
+                * an issue (seems random) */
+               panic("");
+       }
 #endif
        setup_default_mtrrs(&generic_barrier);
        smp_percpu_init();
@@ -224,11 +244,7 @@ uintptr_t smp_main(void)
        hw_coreid_lookup[my_hw_id] = my_hw_id;
 
        // Get a per-core kernel stack
-       page_t *my_stack;
-       if (kpage_alloc(&my_stack))
-               panic("Unable to alloc a per-core stack!");
-       memset(page2kva(my_stack), 0, PGSIZE);
-       uintptr_t my_stack_top = (uintptr_t)page2kva(my_stack) + PGSIZE;
+       uintptr_t my_stack_top = get_kstack();
 
        /* This blob is the GDT, the GDT PD, and the TSS. */
        unsigned int blob_size = sizeof(segdesc_t) * SEG_COUNT +
@@ -242,7 +258,7 @@ uintptr_t smp_main(void)
         * to smp_percpu_init(), but we can't trust our coreid (since they haven't
         * been remapped yet (so we can't write it directly to per_cpu_info)).  So
         * we use the bottom of the stack page... */
-       *(uintptr_t*)page2kva(my_stack) = (uintptr_t)gdt_etc;
+       *kstack_bottom_addr(my_stack_top) = (uintptr_t)gdt_etc;
 
        // Build and load the gdt / gdt_pd
        memcpy(my_gdt, gdt, sizeof(segdesc_t)*SEG_COUNT);
@@ -262,6 +278,9 @@ uintptr_t smp_main(void)
        // Loads the same IDT used by the other cores
        asm volatile("lidt %0" : : "m"(idt_pd));
 
+#ifdef CONFIG_ENABLE_MPTABLES
+       apiconline();
+#else
        // APIC setup
        // set LINT0 to receive ExtINTs (KVM's default).  At reset they are 0x1000.
        write_mmreg32(LAPIC_LVT_LINT0, 0x700);
@@ -270,6 +289,7 @@ uintptr_t smp_main(void)
        mask_lapic_lvt(LAPIC_LVT_LINT0);
        // and then turn it on
        lapic_enable();
+#endif
 
        // set a default logical id for now
        lapic_set_logid(lapic_get_id());
@@ -284,7 +304,7 @@ uintptr_t smp_main(void)
  * to call it on too deep of a stack frame. */
 void __arch_pcpu_init(uint32_t coreid)
 {
-       uintptr_t my_stack_bot;
+       uintptr_t *my_stack_bot;
        struct per_cpu_info *pcpui = &per_cpu_info[coreid];
 
        /* Flushes any potentially old mappings from smp_boot() (note the page table
@@ -303,9 +323,9 @@ void __arch_pcpu_init(uint32_t coreid)
                pcpui->tss = &ts;
                pcpui->gdt = gdt;
        } else {
-               my_stack_bot = ROUNDDOWN(read_sp(), PGSIZE);
-               pcpui->tss = (taskstate_t*)(*(uintptr_t*)my_stack_bot);
-               pcpui->gdt = (segdesc_t*)(*(uintptr_t*)my_stack_bot +
+               my_stack_bot = kstack_bottom_addr(ROUNDUP(read_sp() - 1, PGSIZE));
+               pcpui->tss = (taskstate_t*)(*my_stack_bot);
+               pcpui->gdt = (segdesc_t*)(*my_stack_bot +
                                          sizeof(taskstate_t) + sizeof(pseudodesc_t));
        }
 #ifdef CONFIG_X86_64