summaryrefslogtreecommitdiffstats
path: root/sys/amd64/amd64/vm_machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/amd64/amd64/vm_machdep.c')
-rw-r--r--sys/amd64/amd64/vm_machdep.c89
1 files changed, 88 insertions, 1 deletions
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index 78f16ae..7e3b32a 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -38,7 +38,7 @@
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- * $Id: vm_machdep.c,v 1.105 1998/03/23 19:52:42 jlemon Exp $
+ * $Id: vm_machdep.c,v 1.106 1998/05/16 14:44:11 kato Exp $
*/
#include "npx.h"
@@ -87,6 +87,13 @@
#include <i386/isa/isa.h>
#endif
+static void cpu_reset_real __P((void));
+#ifdef SMP
+static void cpu_reset_proxy __P((void));
+static u_int cpu_reset_proxyid;
+static volatile u_int cpu_reset_proxy_active;
+#endif
+
#ifdef BOUNCE_BUFFERS
static vm_offset_t
vm_bounce_kva __P((int size, int waitok));
@@ -838,9 +845,89 @@ vunmapbuf(bp)
/*
* Force reset the processor by invalidating the entire address space!
*/
+
+#ifdef SMP
+static void
+cpu_reset_proxy()
+{
+ u_int saved_mp_lock;
+
+ cpu_reset_proxy_active = 1;
+ while (cpu_reset_proxy_active == 1)
+ ; /* Wait for other cpu to disable interupts */
+ saved_mp_lock = mp_lock;
+ mp_lock = 1;
+ printf("cpu_reset_proxy: Grabbed mp lock for BSP\n");
+ cpu_reset_proxy_active = 3;
+ while (cpu_reset_proxy_active == 3)
+ ; /* Wait for other cpu to enable interrupts */
+ 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
+ if (smp_active == 0) {
+ cpu_reset_real();
+ /* NOTREACHED */
+ } else {
+
+ u_int map;
+ int cnt;
+ printf("cpu_reset called on cpu#%d\n",cpuid);
+
+ map = other_cpus & ~ stopped_cpus;
+
+ if (map != 0) {
+ printf("cpu_reset: Stopping other CPUs\n");
+ stop_cpus(map); /* Stop all other CPUs */
+ }
+
+ if (cpuid == 0) {
+ DELAY(1000000);
+ cpu_reset_real();
+ /* NOTREACHED */
+ } else {
+ /* We are not BSP (CPU #0) */
+
+ cpu_reset_proxyid = cpuid;
+ cpustop_restartfunc = cpu_reset_proxy;
+ 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");
+ __asm __volatile("cli" : : : "memory");
+ cpu_reset_proxy_active = 2;
+ cnt = 0;
+ while (cpu_reset_proxy_active == 2 && cnt < 10000000)
+ cnt++; /* Do nothing */
+ if (cpu_reset_proxy_active == 2) {
+ printf("cpu_reset: BSP did not grab mp lock\n");
+ cpu_reset_real(); /* XXX: Bogus ? */
+ }
+ cpu_reset_proxy_active = 4;
+ __asm __volatile("sti" : : : "memory");
+ while (1);
+ /* NOTREACHED */
+ }
+ }
+#else
+ cpu_reset_real();
+#endif
+}
+
+static void
+cpu_reset_real()
+{
#ifdef PC98
/*
OpenPOWER on IntegriCloud