From 4cc968cb95b524f1c4e2683f07fd94686839db1d Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 24 Apr 2007 20:06:36 +0000 Subject: [PATCH] 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. --- sys/amd64/amd64/vm_machdep.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index afe70a0f86a..0bc360482a6 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. */