summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2004-12-27 06:15:03 +0000
committernjl <njl@FreeBSD.org>2004-12-27 06:15:03 +0000
commite8a219f1fc996fe9cbf8c594c0ee92e8477acd22 (patch)
tree213e64517b35070187718ba508ca0667820c598a /sys/i386
parentc69ef42c38a5e40e4c797481f931a8b907fd43e1 (diff)
downloadFreeBSD-src-e8a219f1fc996fe9cbf8c594c0ee92e8477acd22.zip
FreeBSD-src-e8a219f1fc996fe9cbf8c594c0ee92e8477acd22.tar.gz
Restore the cpu_reset proxy code. It is needed if you want to reset the
system from an AP at runtime (i.e., calling cpu_reset from ddb). Someday, if we move to an NMI for stopping cpus instead, we can do away with this. Requested by: jhb
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/vm_machdep.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index 10e2623..06da6e3 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -100,6 +100,11 @@ __FBSDID("$FreeBSD$");
#endif
static void cpu_reset_real(void);
+#ifdef SMP
+static void cpu_reset_proxy(void);
+static u_int cpu_reset_proxyid;
+static volatile u_int cpu_reset_proxy_active;
+#endif
static void sf_buf_init(void *arg);
SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL)
@@ -474,11 +479,26 @@ kvtop(void *addr)
return (pa);
}
+#ifdef SMP
+static void
+cpu_reset_proxy()
+{
+
+ cpu_reset_proxy_active = 1;
+ while (cpu_reset_proxy_active == 1)
+ ; /* Wait for other cpu to see that we've started */
+ stop_cpus((1<<cpu_reset_proxyid));
+ printf("cpu_reset_proxy: Stopped CPU %d\n", cpu_reset_proxyid);
+ DELAY(1000000);
+ cpu_reset_real();
+}
+#endif
+
void
cpu_reset()
{
#ifdef SMP
- u_int map;
+ u_int cnt, map;
if (smp_active) {
map = PCPU_GET(other_cpus) & ~stopped_cpus;
@@ -486,6 +506,26 @@ cpu_reset()
printf("cpu_reset: Stopping other CPUs\n");
stop_cpus(map);
}
+
+ if (PCPU_GET(cpuid) != 0) {
+ cpu_reset_proxyid = PCPU_GET(cpuid);
+ cpustop_restartfunc = cpu_reset_proxy;
+ cpu_reset_proxy_active = 0;
+ printf("cpu_reset: Restarting BSP\n");
+ started_cpus = (1<<0); /* Restart CPU #0 */
+
+ cnt = 0;
+ while (cpu_reset_proxy_active == 0 && cnt < 10000000)
+ cnt++; /* Wait for BSP to announce restart */
+ if (cpu_reset_proxy_active == 0)
+ printf("cpu_reset: Failed to restart BSP\n");
+ enable_intr();
+ cpu_reset_proxy_active = 2;
+
+ while (1);
+ /* NOTREACHED */
+ }
+
DELAY(1000000);
}
#endif
OpenPOWER on IntegriCloud