Index | Thread | Search

From:
Jonathan Gray <jsg@jsg.id.au>
Subject:
Re: Fix for OpenBSD reboot failure on Fujitsu Futro S940
To:
Gert-Jan Vons <uhssknjm@posteo.net>
Cc:
tech@openbsd.org
Date:
Tue, 13 Oct 2026 20:29:15 +1100

Download raw body.

Thread
On Tue, Oct 13, 2026 at 07:16:37AM +0000, Gert-Jan Vons wrote:
> Hi Jonathan,
> 
> On 13/10/2026 04:59, Jonathan Gray wrote:
> > On Wed, Oct 07, 2026 at 08:03:28AM +0000, Gert-Jan Vons wrote:
> > > On my Fujitsu Futro S940 (dmesg below), OpenBSD hangs on reboot. The console
> > > shows "rebooting..." but nothing happens and a power-cycle is needed to get
> > > things running again. Debugging showed that neither the cpuresetfn() nor the
> > > pulsing of the reset pin by the keyboard controller have any effect, and
> > > that the system hangs at the triple fault.
> > > 
> > > The patch below adds an attempt to reset using the Reset Control register,
> > > which solves the problem for me. I took this from FreeBSD/NetBSD and placed
> > > it at the same location in the code (after the reset pin pulsing).
> > This is normally encoded in the ACPI FADT.
> > 
> > What values does this system have for fadt->reset_reg.address and
> > fadt->reset_value in sys/dev/acpi/acpi.c acpi_reset() ?
> > 
> > Can also be seen by installing the acpica package and using
> > iasl -d on files in /var/db/acpi/
> 
> Output from iasl:
> 
>                 Reset Register Supported (V2) : 1
> 
>  [074h 0116 00Ch]              Reset Register : [Generic Address Structure]
> 
>  [074h 0116 001h]                    Space ID : 01 [SystemIO]
>  [075h 0117 001h]                   Bit Width : 08
>  [076h 0118 001h]                  Bit Offset : 00
>  [077h 0119 001h]        Encoded Access Width : 00 [Undefined/Legacy]
>  [078h 0120 008h]                     Address : 00000000000000B2
> 
>  [080h 0128 001h]        Value to cause reset : 15
> 
> Gert-Jan

Thanks, a strange choice on their part.

Your patch had utf-8 non-breaking space characters in it.  I've
recreated it without those, changed 'System reset' to 'System Reset' to
match Intel's PIIX4 documentation and made the same changes to i386.

Index: sys/arch/amd64/amd64/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/machdep.c,v
diff -u -p -r1.314 machdep.c
--- sys/arch/amd64/amd64/machdep.c	28 Sep 2026 14:14:03 -0000	1.314
+++ sys/arch/amd64/amd64/machdep.c	13 Oct 2026 09:07:39 -0000
@@ -150,6 +150,10 @@ extern int db_console;
 #include <dev/ic/pckbcvar.h>
 #endif
 
+#define RST_CNT	0xcf9		/* Reset Control Register */
+#define RST_CNT_SYS_RST	0x02	/* System Reset */
+#define RST_CNT_RST_CPU	0x04	/* Reset CPU */
+
 /* #define MACHDEP_DEBUG */
 
 #ifdef MACHDEP_DEBUG
@@ -1916,6 +1920,18 @@ cpu_reset(void)
 	delay(100000);
 	outb(IO_KBD + KBCMDP, KBC_PULSE0);
 	delay(100000);
+
+	/*
+	 * Try to force a reset via the Reset Control register.
+	 * Reset is triggered by the 0->1 transition of the RST_CPU bit,
+	 * and a hard reset will be done when the SYS_RST bit is set at
+	 * the moment of the transition.
+	 * First write selects the hard reset and clears RST_CPU, second
+	 * write forces the 0->1 transition on RST_CPU.
+	 */
+	outb(RST_CNT, RST_CNT_SYS_RST);
+	outb(RST_CNT, RST_CNT_SYS_RST | RST_CNT_RST_CPU);
+	delay(500000);
 
 	/*
 	 * Try to cause a triple fault and watchdog reset by making the IDT
Index: sys/arch/i386/i386/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v
diff -u -p -r1.681 machdep.c
--- sys/arch/i386/i386/machdep.c	1 Oct 2026 23:51:29 -0000	1.681
+++ sys/arch/i386/i386/machdep.c	13 Oct 2026 09:07:15 -0000
@@ -149,6 +149,10 @@ extern struct proc *npxproc;
 #include <dev/ic/pckbcvar.h>
 #endif
 
+#define RST_CNT	0xcf9		/* Reset Control Register */
+#define RST_CNT_SYS_RST	0x02	/* System Reset */
+#define RST_CNT_RST_CPU	0x04	/* Reset CPU */
+
 /* #define MACHDEP_DEBUG */
 
 #ifdef MACHDEP_DEBUG
@@ -3442,6 +3446,18 @@ cpu_reset(void)
 	delay(100000);
 	outb(IO_KBD + KBCMDP, KBC_PULSE0);
 	delay(100000);
+
+	/*
+	 * Try to force a reset via the Reset Control register.
+	 * Reset is triggered by the 0->1 transition of the RST_CPU bit,
+	 * and a hard reset will be done when the SYS_RST bit is set at
+	 * the moment of the transition.
+	 * First write selects the hard reset and clears RST_CPU, second
+	 * write forces the 0->1 transition on RST_CPU.
+	 */
+	outb(RST_CNT, RST_CNT_SYS_RST);
+	outb(RST_CNT, RST_CNT_SYS_RST | RST_CNT_RST_CPU);
+	delay(500000);
 
 	/*
 	 * Try to cause a triple fault and watchdog reset by setting the