summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2006-04-27 05:18:26 +0000
committersobomax <sobomax@FreeBSD.org>2006-04-27 05:18:26 +0000
commitb5181c79ef5de4668ea1ec8600fe88f53a4b1dc7 (patch)
tree2ccd6be5f6430e10f2e96313342d5b3c6b469343 /sys
parentfc73c0221180d0659186fc3cced07104d7b3c578 (diff)
downloadFreeBSD-src-b5181c79ef5de4668ea1ec8600fe88f53a4b1dc7.zip
FreeBSD-src-b5181c79ef5de4668ea1ec8600fe88f53a4b1dc7.tar.gz
In the case when reset via keyboard controller doesn't work for some reason
(i.e. no keyboard controller present), try two other common methods for resetting i386 machine - pci reset and port 0x92 fast reset. Only if neither works warn user and resort to "unmap entire address space and hope for good" hack. This makes my MacBook Pro rebooting just fine and should also help other legacy-free hardware out there. Also, disable interrupts unconditionally in cpu_reset_real(), since we don't want any interference. MFC after: 1 week
Diffstat (limited to 'sys')
-rw-r--r--sys/i386/i386/vm_machdep.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index b9161eb..daa98d7 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -590,7 +590,9 @@ cpu_reset()
static void
cpu_reset_real()
{
+ int b;
+ disable_intr();
#ifdef CPU_ELAN
if (elan_mmcr != NULL)
elan_mmcr->RESCFG = 1;
@@ -606,7 +608,6 @@ cpu_reset_real()
/*
* Attempt to do a CPU reset via CPU reset port.
*/
- disable_intr();
if ((inb(0x35) & 0xa0) != 0xa0) {
outb(0x37, 0x0f); /* SHUT0 = 0. */
outb(0x37, 0x0b); /* SHUT1 = 0. */
@@ -621,11 +622,26 @@ 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");
- DELAY(1000000); /* wait 1 sec for printf to complete */
#endif
+ /* Try the PCI reset */
+ outb(0xcf9, 0x2);
+ outb(0xcf9, 0x6);
+ DELAY(500000); /* wait 0.5 sec to see if that did it */
+
+ /* Try port 0x92 fast reset */
+ b = inb(0x92);
+ /* Check the the hardware actually has the port in question */
+ 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 */
+ }
#endif /* PC98 */
+ printf("No known reset method did work, attempting CPU shutdown\n");
+ DELAY(1000000); /* wait 1 sec for printf to complete */
+
/* Force a shutdown by unmapping entire address space. */
bzero((caddr_t)PTD, NBPTD);
OpenPOWER on IntegriCloud