summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2007-04-24 20:06:36 +0000
committerjhb <jhb@FreeBSD.org>2007-04-24 20:06:36 +0000
commitcafaaf6a395869780ffefbd420ab2cc885b4852f (patch)
tree125f21de6a619815da3512ae18146ae3997ea7d4 /sys
parent9ff5fd9d6ae00497b5a2a13523d677de06d4a213 (diff)
downloadFreeBSD-src-cafaaf6a395869780ffefbd420ab2cc885b4852f.zip
FreeBSD-src-cafaaf6a395869780ffefbd420ab2cc885b4852f.tar.gz
MFi386: Attempt to reset the machine using the Reset Control register and
Fast A20 and Init register if the keyboard reset doesn't work before resorting to a triple fault.
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/vm_machdep.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index afe70a0..0bc3604 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -457,6 +457,9 @@ cpu_reset()
static void
cpu_reset_real()
{
+ int b;
+
+ disable_intr();
/*
* Attempt to do a CPU reset via the keyboard controller,
@@ -465,7 +468,33 @@ cpu_reset_real()
*/
outb(IO_KBD + 4, 0xFE);
DELAY(500000); /* wait 0.5 sec to see if that did it */
- printf("Keyboard reset did not work, attempting CPU shutdown\n");
+
+ /*
+ * Attempt to force a reset via the Reset Control register at
+ * I/O port 0xcf9. Bit 2 forces a system reset when it is
+ * written as 1. Bit 1 selects the type of reset to attempt:
+ * 0 selects a "soft" reset, and 1 selects a "hard" reset. We
+ * try to do a "soft" reset first, and then a "hard" reset.
+ */
+ outb(0xcf9, 0x2);
+ outb(0xcf9, 0x6);
+ DELAY(500000); /* wait 0.5 sec to see if that did it */
+
+ /*
+ * Attempt to force a reset via the Fast A20 and Init register
+ * at I/O port 0x92. Bit 1 serves as an alternate A20 gate.
+ * Bit 0 asserts INIT# when set to 1. We are careful to only
+ * preserve bit 1 while setting bit 0. We also must clear bit
+ * 0 before setting it if it isn't already clear.
+ */
+ b = inb(0x92);
+ if (b != 0xff) {
+ if ((b & 0x1) != 0)
+ outb(0x92, b & 0xfe);
+ outb(0x92, b | 0x1);
+ DELAY(500000); /* wait 0.5 sec to see if that did it */
+ }
+ printf("No known reset method worked, attempting CPU shutdown\n");
DELAY(1000000); /* wait 1 sec for printf to complete */
/* Force a shutdown by unmapping entire address space. */
OpenPOWER on IntegriCloud