diff options
author | mjacob <mjacob@FreeBSD.org> | 2001-07-14 21:37:57 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2001-07-14 21:37:57 +0000 |
commit | 59f5dd5135d5edc0d56edc7ed6ad44f0583a7298 (patch) | |
tree | 9550dc6c244a1c87efdba8561a1f4b653b8f2376 /sys | |
parent | 6018882d627ba921cc74d5c9c151097e2e26038b (diff) | |
download | FreeBSD-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})).
Diffstat (limited to 'sys')
-rw-r--r-- | sys/alpha/alpha/machdep.c | 14 | ||||
-rw-r--r-- | sys/alpha/alpha/mp_machdep.c | 3 | ||||
-rw-r--r-- | sys/alpha/alpha/vm_machdep.c | 11 | ||||
-rw-r--r-- | sys/alpha/include/smp.h | 1 |
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 |