> I have SoC machine (dmesg below) which hangs on reboot in most cases. It seems that the problem was resolved by just commenting "KBC_PULSE0" related case in cpu_reset() and machine successfuly rebooted by "triple fault and watchdog reset" bits (follow just after). Should we think about sysctl to give an option to switch it off?
By the way, I briefly tested NetBSD's x86 reboot quirks and found that they may be useful too (on i386 I mean). At least, the First case (reset via the Reset Control register) reboots my SoC machine successfuly. Second case (reset via the Fast A20 and Init register) don't reboot my Soc machine alone, but not hangs, and machine still rebooted (with the help of First). So it may be useful for someone. I think that these two cases must be enveloped into #ifdef __i386__ --- /usr/src/sys/arch/i386/i386/machdep.c Tue Feb 22 23:47:51 2011 +++ ./machdep.c Tue Mar 1 15:28:02 2011 @@ -3271,10 +3271,10 @@ * connected to the RESET pin on the CPU in many PCs. We tell the * keyboard controller to pulse this line a couple of times. */ - outb(IO_KBD + KBCMDP, KBC_PULSE0); - delay(100000); - outb(IO_KBD + KBCMDP, KBC_PULSE0); - delay(100000); +// outb(IO_KBD + KBCMDP, KBC_PULSE0); +// delay(100000); +// outb(IO_KBD + KBCMDP, KBC_PULSE0); +// delay(100000); /* * Try to cause a triple fault and watchdog reset by setting the @@ -3284,6 +3284,36 @@ setregion(®ion, idt, sizeof(idt_region) - 1); lidt(®ion); __asm __volatile("divl %0,%1" : : "q" (0), "a" (0)); + + /* FIRST CASE + * Attempt to force a reset via the Reset Control register at + * I/O port 0xcf9. Bit 2 forces a system reset when it + * transitions from 0 to 1. Bit 1 selects the type of reset + * to attempt: 0 selects a "soft" reset, and 1 selects a + * "hard" reset. We try a "hard" reset. The first write sets + * bit 1 to select a "hard" reset and clears bit 2. The + * second write forces a 0 -> 1 transition in bit 2 to trigger + * a reset. + */ + outb(0xcf9, 0x2); + outb(0xcf9, 0x6); + DELAY(500000); /* wait 0.5 sec to see if that did it */ + + /* SECOND CASE + * 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. + */ + uint8_t b; + 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 */ + } #if 1 -- antonvm