x86: decouple call to print_cpu_info from smp_store_cpu_info
[sfrench/cifs-2.6.git] / arch / x86 / kernel / smpboot_64.c
index ca3a3c5b64fea453ff8c7bb21925a9a4426922d6..1da28c6c1f5fbb15417af7d4930f383322323c40 100644 (file)
 /* Set when the idlers are all forked */
 int smp_threads_ready;
 
-/*
- * Trampoline 80x86 program as an array.
- */
-
-extern const unsigned char trampoline_data[];
-extern const unsigned char trampoline_end[];
-
 /* State of each CPU */
 DEFINE_PER_CPU(int, cpu_state) = { 0 };
 
@@ -92,20 +85,6 @@ struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
 #define set_idle_for_cpu(x,p)   (idle_thread_array[(x)] = (p))
 #endif
 
-
-/*
- * Currently trivial. Write the real->protected mode
- * bootstrap into the page concerned. The caller
- * has made sure it's suitably aligned.
- */
-
-static unsigned long __cpuinit setup_trampoline(void)
-{
-       void *tramp = __va(SMP_TRAMPOLINE_BASE); 
-       memcpy(tramp, trampoline_data, trampoline_end - trampoline_data);
-       return virt_to_phys(tramp);
-}
-
 /*
  * The bootstrap kernel entry code has set these up. Save them for
  * a given CPU
@@ -118,7 +97,13 @@ static void __cpuinit smp_store_cpu_info(int id)
        *c = boot_cpu_data;
        c->cpu_index = id;
        identify_cpu(c);
-       print_cpu_info(c);
+}
+
+static inline void wait_for_init_deassert(atomic_t *deassert)
+{
+       while (!atomic_read(deassert))
+               cpu_relax();
+       return;
 }
 
 static atomic_t init_deasserted __cpuinitdata;
@@ -138,8 +123,7 @@ void __cpuinit smp_callin(void)
         * our local APIC.  We have to wait for the IPI or we'll
         * lock up on an APIC access.
         */
-       while (!atomic_read(&init_deasserted))
-               cpu_relax();
+       wait_for_init_deassert(&init_deasserted);
 
        /*
         * (This works even if the APIC is not enabled.)
@@ -296,8 +280,8 @@ static void inquire_remote_apic(int apicid)
                        printk(KERN_CONT
                               "a previous APIC delivery may have failed\n");
 
-               apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
-               apic_write(APIC_ICR, APIC_DM_REMRD | regs[i]);
+               apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
+               apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]);
 
                timeout = 0;
                do {
@@ -330,12 +314,12 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
        /*
         * Turn INIT on target chip
         */
-       apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
+       apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
 
        /*
         * Send IPI
         */
-       apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT
+       apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT
                                | APIC_DM_INIT);
 
        Dprintk("Waiting for send to finish...\n");
@@ -346,10 +330,10 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
        Dprintk("Deasserting INIT.\n");
 
        /* Target chip */
-       apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
+       apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
 
        /* Send IPI */
-       apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
+       apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
 
        Dprintk("Waiting for send to finish...\n");
        send_status = safe_apic_wait_icr_idle();
@@ -359,6 +343,14 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
 
        num_starts = 2;
 
+       /*
+        * Paravirt / VMI wants a startup IPI hook here to set up the
+        * target processor state.
+        */
+       startup_ipi_hook(phys_apicid, (unsigned long) start_secondary,
+                       (unsigned long) init_rsp);
+
+
        /*
         * Run STARTUP IPI loop.
         */
@@ -368,6 +360,7 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
 
        for (j = 1; j <= num_starts; j++) {
                Dprintk("Sending STARTUP #%d.\n",j);
+               apic_read_around(APIC_SPIV);
                apic_write(APIC_ESR, 0);
                apic_read(APIC_ESR);
                Dprintk("After apic_write.\n");
@@ -377,11 +370,11 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
                 */
 
                /* Target chip */
-               apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
+               apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
 
                /* Boot on the stack */
                /* Kick the second */
-               apic_write(APIC_ICR, APIC_DM_STARTUP | (start_rip >> 12));
+               apic_write_around(APIC_ICR, APIC_DM_STARTUP | (start_rip>>12));
 
                /*
                 * Give the other CPU some time to accept the IPI.
@@ -401,6 +394,7 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
                 * Due to the Pentium erratum 3AP.
                 */
                if (maxlvt > 3) {
+                       apic_read_around(APIC_SPIV);
                        apic_write(APIC_ESR, 0);
                }
                accept_status = (apic_read(APIC_ESR) & 0xEF);
@@ -573,6 +567,8 @@ do_rest:
                if (cpu_isset(cpu, cpu_callin_map)) {
                        /* number CPUs logically, starting from 1 (BSP is 0) */
                        Dprintk("CPU has booted.\n");
+                       printk(KERN_INFO "CPU%d: ", cpu);
+                       print_cpu_info(&cpu_data(cpu));
                } else {
                        boot_error = 1;
                        if (*((volatile unsigned char *)phys_to_virt(SMP_TRAMPOLINE_BASE))
@@ -756,6 +752,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
         */
 
        setup_boot_clock();
+       printk(KERN_INFO "CPU%d: ", 0);
+       print_cpu_info(&cpu_data(0));
 }
 
 /*
@@ -836,84 +834,3 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
        setup_ioapic_dest();
        check_nmi_watchdog();
 }
-
-#ifdef CONFIG_HOTPLUG_CPU
-static void __ref remove_cpu_from_maps(void)
-{
-       int cpu = smp_processor_id();
-
-       cpu_clear(cpu, cpu_callout_map);
-       cpu_clear(cpu, cpu_callin_map);
-       clear_bit(cpu, (unsigned long *)&cpu_initialized); /* was set by cpu_init() */
-       clear_node_cpumask(cpu);
-}
-
-int __cpu_disable(void)
-{
-       int cpu = smp_processor_id();
-
-       /*
-        * Perhaps use cpufreq to drop frequency, but that could go
-        * into generic code.
-        *
-        * We won't take down the boot processor on i386 due to some
-        * interrupts only being able to be serviced by the BSP.
-        * Especially so if we're not using an IOAPIC   -zwane
-        */
-       if (cpu == 0)
-               return -EBUSY;
-
-       if (nmi_watchdog == NMI_LOCAL_APIC)
-               stop_apic_nmi_watchdog(NULL);
-       clear_local_APIC();
-
-       /*
-        * HACK:
-        * Allow any queued timer interrupts to get serviced
-        * This is only a temporary solution until we cleanup
-        * fixup_irqs as we do for IA64.
-        */
-       local_irq_enable();
-       mdelay(1);
-
-       local_irq_disable();
-       remove_siblinginfo(cpu);
-
-       /* It's now safe to remove this processor from the online map */
-       cpu_clear(cpu, cpu_online_map);
-       remove_cpu_from_maps();
-       fixup_irqs(cpu_online_map);
-       return 0;
-}
-
-void __cpu_die(unsigned int cpu)
-{
-       /* We don't do anything here: idle task is faking death itself. */
-       unsigned int i;
-
-       for (i = 0; i < 10; i++) {
-               /* They ack this in play_dead by setting CPU_DEAD */
-               if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
-                       printk ("CPU %d is now offline\n", cpu);
-                       if (1 == num_online_cpus())
-                               alternatives_smp_switch(0);
-                       return;
-               }
-               msleep(100);
-       }
-       printk(KERN_ERR "CPU %u didn't die...\n", cpu);
-}
-
-#else /* ... !CONFIG_HOTPLUG_CPU */
-
-int __cpu_disable(void)
-{
-       return -ENOSYS;
-}
-
-void __cpu_die(unsigned int cpu)
-{
-       /* We said "no" in __cpu_disable */
-       BUG();
-}
-#endif /* CONFIG_HOTPLUG_CPU */