x86: smp_boot no longer uses smp_call_*
authorBarret Rhoden <brho@cs.berkeley.edu>
Sat, 20 Jul 2013 01:05:17 +0000 (18:05 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sat, 20 Jul 2013 01:17:42 +0000 (18:17 -0700)
Instead, we have a dedicated IRQ vector that does nothing but return.
This is enough to break the non-core0s out of their hlt.

Other than it being nice to not need the ancient smp_callsi_ (which
might go away), this is needed if you run with FAST_COREID.  Before,
smp_call_ would trigger a full irq_handler(), which increments pcpui
irq_depth, before core_id() is ready.  The other option would be to use
a core_id_early() call in irq_handler(), which I dislike.

Also, don't repurpose the POKE_HANDLER() without thinking about how it
might interact with abort_halt().

kern/arch/x86/smp_boot.c
kern/arch/x86/smp_entry32.S
kern/arch/x86/smp_entry64.S
kern/arch/x86/trapentry32.S
kern/arch/x86/trapentry64.S

index 2010a3e..103f601 100644 (file)
@@ -31,6 +31,7 @@
 extern handler_wrapper_t (RO handler_wrappers)[NUM_HANDLER_WRAPPERS];
 volatile uint32_t num_cpus = 0xee;
 uintptr_t RO smp_stack_top;
+barrier_t generic_barrier;
 
 #define DECLARE_HANDLER_CHECKLISTS(vector)                          \
        INIT_CHECKLIST(f##vector##_cpu_list, MAX_NUM_CPUS);
@@ -59,16 +60,16 @@ static void init_smp_call_function(void)
 
 /******************************************************************************/
 
-static void smp_final_core_init(struct hw_trapframe *hw_tf, void *data)
+void smp_final_core_init(void)
 {
 #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);
 #endif
-       setup_default_mtrrs(data);
+       setup_default_mtrrs(&generic_barrier);
        smp_percpu_init();
-       waiton_barrier(data);
+       waiton_barrier(&generic_barrier);
 }
 
 // this needs to be set in smp_entry too...
@@ -191,10 +192,10 @@ void smp_boot(void)
        init_smp_call_function();
 
        /* Final core initialization */
-       barrier_t generic_barrier;
        init_barrier(&generic_barrier, num_cpus);
        /* This will break the cores out of their hlt in smp_entry.S */
-       smp_call_function_all(smp_final_core_init, &generic_barrier, 0);
+       send_broadcast_ipi(254);
+       smp_final_core_init();  /* need to init ourselves as well */
 }
 
 /* This is called from smp_entry by each core to finish the core bootstrapping.
index dda7cc7..bdf5168 100644 (file)
@@ -87,6 +87,7 @@ here:
        lock decw       smp_semaphore - smp_entry + 0x1000  # show we are done
        sti                     # so we can get the IPI
        hlt                     # wait for the IPI to run smp_pcu_init()
+       call    smp_final_core_init
        call    smp_idle                # idle loop, will have interrupts turned on
        # smp_idle should never return
 spin:
index a0360ba..92fa62a 100644 (file)
@@ -96,6 +96,7 @@ non_trampoline:
        lock decw       smp_semaphore - smp_entry + 0x1000  # show we are done
        sti                     # so we can get the IPI
        hlt                     # wait for the IPI to run smp_pcu_init()
+       call    smp_final_core_init
        call    smp_idle                # idle loop, will have interrupts turned on
        # smp_idle should never return
 spin:
index 15e992a..d4ffdd7 100644 (file)
        .long name;                                                     \
        .long num
 
+/* Only used in the kernel during SMP boot.  Send a LAPIC_EOI and iret. */
+#define POKE_HANDLER(name, num)                        \
+       .text;                                                          \
+       .globl name;                                            \
+       .type name, @function;                          \
+       .align 2;                                                       \
+       name:;                                                          \
+       movl $0, (LAPIC_BASE + 0x0b0);      \
+       iret;                                                           \
+       .data;                                                          \
+       .long name;                                                     \
+       .long num
+
 /* Same as above, but takes a specific function to jump to.  See comments
  * below from _allirqs for details.
  */
@@ -173,7 +186,7 @@ IRQ_HANDLER(IRQ218, 250)
 IRQ_HANDLER(IRQ219, 251)
 IRQ_HANDLER(IRQ220, 252)
 IRQ_HANDLER(IRQ221, 253)
-IRQ_HANDLER(IRQ222, 254)
+POKE_HANDLER(IRQ222, 254)
 IRQ_HANDLER(IRQ223, I_KERNEL_MSG)
 
 /* Technically, these HANDLER entries do not need to be in numeric order */
index 880d0d7..d71678a 100644 (file)
        .quad name;                                                     \
        .long num
 
+/* Only used in the kernel during SMP boot.  Send a LAPIC_EOI and iret. */
+#define POKE_HANDLER(name, num)                        \
+       .text;                                                          \
+       .globl name;                                            \
+       .type name, @function;                          \
+       .align 2;                                                       \
+       name:;                                                          \
+       movl $0, (LAPIC_BASE + 0x0b0);      \
+       iretq;                                                          \
+       .data;                                                          \
+       .quad name;                                                     \
+       .long num
+
 .data
 .globl trap_tbl
 trap_tbl:
@@ -135,7 +148,7 @@ IRQ_HANDLER(IRQ218, 250)
 IRQ_HANDLER(IRQ219, 251)
 IRQ_HANDLER(IRQ220, 252)
 IRQ_HANDLER(IRQ221, 253)
-IRQ_HANDLER(IRQ222, 254)
+POKE_HANDLER(IRQ222, 254)
 IRQ_HANDLER(IRQ223, I_KERNEL_MSG)
 
 /* Technically, these HANDLER entries do not need to be in numeric order */