diff options
author | jhb <jhb@FreeBSD.org> | 2007-04-24 20:06:36 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2007-04-24 20:06:36 +0000 |
commit | cafaaf6a395869780ffefbd420ab2cc885b4852f (patch) | |
tree | 125f21de6a619815da3512ae18146ae3997ea7d4 /sys | |
parent | 9ff5fd9d6ae00497b5a2a13523d677de06d4a213 (diff) | |
download | FreeBSD-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.c | 31 |
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. */ |