summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2001-07-14 21:37:57 +0000
committermjacob <mjacob@FreeBSD.org>2001-07-14 21:37:57 +0000
commit59f5dd5135d5edc0d56edc7ed6ad44f0583a7298 (patch)
tree9550dc6c244a1c87efdba8561a1f4b653b8f2376
parent6018882d627ba921cc74d5c9c151097e2e26038b (diff)
downloadFreeBSD-src-59f5dd5135d5edc0d56edc7ed6ad44f0583a7298.zip
FreeBSD-src-59f5dd5135d5edc0d56edc7ed6ad44f0583a7298.tar.gz
Fix reboot hangs that have happened with multiple processors
on Alpha 4100s. Basically, if you're halting or you're rebooting, you should tell all other processors to halt first. Define IPI_HALT- IPI_STOP is not what we want for this purpose, which will call prom_halt(0) on receipt. The processor running the halt or reboot wil send an IPI_HALT to all other processors, delay a bit, then continue to do what what it was planning on doing (prom_halt({0|1})).
-rw-r--r--sys/alpha/alpha/machdep.c14
-rw-r--r--sys/alpha/alpha/mp_machdep.c3
-rw-r--r--sys/alpha/alpha/vm_machdep.c11
-rw-r--r--sys/alpha/include/smp.h1
4 files changed, 26 insertions, 3 deletions
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c
index 856334f..b94b64a 100644
--- a/sys/alpha/alpha/machdep.c
+++ b/sys/alpha/alpha/machdep.c
@@ -239,8 +239,9 @@ static vm_offset_t pager_sva, pager_eva;
static void
alpha_srm_shutdown(void *junk, int howto)
{
- if (howto & RB_HALT)
- alpha_pal_halt();
+ if (howto & RB_HALT) {
+ cpu_halt();
+ }
}
static void
@@ -1615,7 +1616,14 @@ cpu_boot(int howto)
void
cpu_halt(void)
{
- /*alpha_pal_halt(); */
+#ifdef SMP
+ printf("sending IPI_HALT to other processors\n");
+ DELAY(1000000);
+ ipi_all_but_self(IPI_HALT);
+ DELAY(1000000);
+ printf("Halting Self\n");
+ DELAY(1000000);
+#endif
prom_halt(1);
}
diff --git a/sys/alpha/alpha/mp_machdep.c b/sys/alpha/alpha/mp_machdep.c
index 414a1bc..74500b8 100644
--- a/sys/alpha/alpha/mp_machdep.c
+++ b/sys/alpha/alpha/mp_machdep.c
@@ -472,6 +472,9 @@ smp_handle_ipi(struct trapframe *frame)
atomic_clear_int(&started_cpus, cpumask);
atomic_clear_int(&stopped_cpus, cpumask);
break;
+ case IPI_HALT:
+ prom_halt(1);
+ /* NOTREACHED */
}
}
diff --git a/sys/alpha/alpha/vm_machdep.c b/sys/alpha/alpha/vm_machdep.c
index 195a934..87b0335 100644
--- a/sys/alpha/alpha/vm_machdep.c
+++ b/sys/alpha/alpha/vm_machdep.c
@@ -95,6 +95,9 @@
#include <vm/vm_extern.h>
#include <sys/user.h>
+#ifdef SMP
+#include <machine/smp.h>
+#endif
/*
* quick version of vm_fault
@@ -388,6 +391,14 @@ vunmapbuf(bp)
void
cpu_reset()
{
+#ifdef SMP
+ printf("sending IPI_HALT to other processors\n");
+ DELAY(1000000);
+ ipi_all_but_self(IPI_HALT);
+ DELAY(1000000);
+ printf("Rebooting Self\n");
+ DELAY(1000000);
+#endif
prom_halt(0);
}
diff --git a/sys/alpha/include/smp.h b/sys/alpha/include/smp.h
index 05af7f4..981647b 100644
--- a/sys/alpha/include/smp.h
+++ b/sys/alpha/include/smp.h
@@ -23,6 +23,7 @@
#define IPI_AST 0x0004
#define IPI_CHECKSTATE 0x0008
#define IPI_STOP 0x0010
+#define IPI_HALT 0x1000
#ifndef LOCORE
OpenPOWER on IntegriCloud