+#if CONFIG_AP_IN_SIPI_WAIT == 1
+/**
+ * Normally this function is defined in lapic.h as an always inline function
+ * that just keeps the CPU in a hlt() loop. This does not work on all CPUs.
+ * I think all hyperthreading CPUs might need this version, but I could only
+ * verify this on the Intel Core Duo
+ */
+void stop_this_cpu(void)
+{
+ int timeout;
+ unsigned long send_status;
+ unsigned long lapicid;
+
+ lapicid = lapic_read(LAPIC_ID) >> 24;
+
+ printk_debug("CPU %d going down...\n", lapicid);
+
+ /* send an LAPIC INIT to myself */
+ lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(lapicid));
+ lapic_write_around(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_INT_ASSERT | LAPIC_DM_INIT);
+
+ /* wait for the ipi send to finish */
+#if 0
+ // When these two printk_spew calls are not removed, the
+ // machine will hang when log level is SPEW. Why?
+ printk_spew("Waiting for send to finish...\n");
+#endif
+ timeout = 0;
+ do {
+#if 0
+ printk_spew("+");
+#endif
+ udelay(100);
+ send_status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
+ } while (send_status && (timeout++ < 1000));
+ if (timeout >= 1000) {
+ printk_err("timed out\n");
+ }
+ mdelay(10);
+
+ printk_spew("Deasserting INIT.\n");
+ /* Deassert the LAPIC INIT */
+ lapic_write_around(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(lapicid));
+ lapic_write_around(LAPIC_ICR, LAPIC_INT_LEVELTRIG | LAPIC_DM_INIT);
+
+ printk_spew("Waiting for send to finish...\n");
+ timeout = 0;
+ do {
+ printk_spew("+");
+ udelay(100);
+ send_status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
+ } while (send_status && (timeout++ < 1000));
+ if (timeout >= 1000) {
+ printk_err("timed out\n");
+ }
+
+ while(1) {
+ hlt();
+ }
+}
+#endif
+