svn commit: r216735 - stable/8/sys/dev/ichwd

Attilio Rao attilio at FreeBSD.org
Mon Dec 27 12:52:36 UTC 2010


Author: attilio
Date: Mon Dec 27 12:52:35 2010
New Revision: 216735
URL: http://svn.freebsd.org/changeset/base/216735

Log:
  MFC r215868, 215918, 216266, 216298:
  - Advertise when the reboot came from a watchdog-induced reset
  - Fix a bug where TCO_BOOT_STS was supposed to be cleared after
    TCO_SECOND_TO_STS
  - Use macros for max and min value capping when re-arming the
    watchdog timeout
  
  Sponsored by:	Sandvine Incorporated

Modified:
  stable/8/sys/dev/ichwd/ichwd.c
  stable/8/sys/dev/ichwd/ichwd.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/ichwd/ichwd.c
==============================================================================
--- stable/8/sys/dev/ichwd/ichwd.c	Mon Dec 27 12:39:24 2010	(r216734)
+++ stable/8/sys/dev/ichwd/ichwd.c	Mon Dec 27 12:52:35 2010	(r216735)
@@ -179,12 +179,12 @@ ichwd_sts_reset(struct ichwd_softc *sc)
 	 * by writing a 1, not a 0.
 	 */
 	ichwd_write_tco_2(sc, TCO1_STS, TCO_TIMEOUT);
-	/*
-	 * XXX The datasheet says that TCO_SECOND_TO_STS must be cleared
-	 * before TCO_BOOT_STS, not the other way around.
+	/* 
+	 * According to Intel's docs, clearing SECOND_TO_STS and BOOT_STS must 
+	 * be done in two separate operations.
 	 */
-	ichwd_write_tco_2(sc, TCO2_STS, TCO_BOOT_STS);
 	ichwd_write_tco_2(sc, TCO2_STS, TCO_SECOND_TO_STS);
+	ichwd_write_tco_2(sc, TCO2_STS, TCO_BOOT_STS);
 }
 
 /*
@@ -242,30 +242,23 @@ static __inline void
 ichwd_tmr_set(struct ichwd_softc *sc, unsigned int timeout)
 {
 
-	/*
-	 * If the datasheets are to be believed, the minimum value
-	 * actually varies from chipset to chipset - 4 for ICH5 and 2 for
-	 * all other chipsets.  I suspect this is a bug in the ICH5
-	 * datasheet and that the minimum is uniformly 2, but I'd rather
-	 * err on the side of caution.
-	 */
-	if (timeout < 4)
-		timeout = 4;
+	if (timeout < TCO_RLD_TMR_MIN)
+		timeout = TCO_RLD_TMR_MIN;
 
 	if (sc->ich_version <= 5) {
 		uint8_t tmr_val8 = ichwd_read_tco_1(sc, TCO_TMR1);
 
-		tmr_val8 &= 0xc0;
-		if (timeout > 0x3f)
-			timeout = 0x3f;
+		tmr_val8 &= (~TCO_RLD1_TMR_MAX & 0xff);
+		if (timeout > TCO_RLD1_TMR_MAX)
+			timeout = TCO_RLD1_TMR_MAX;
 		tmr_val8 |= timeout;
 		ichwd_write_tco_1(sc, TCO_TMR1, tmr_val8);
 	} else {
 		uint16_t tmr_val16 = ichwd_read_tco_2(sc, TCO_TMR2);
 
-		tmr_val16 &= 0xfc00;
-		if (timeout > 0x03ff)
-			timeout = 0x03ff;
+		tmr_val16 &= (~TCO_RLD2_TMR_MAX & 0xffff);
+		if (timeout > TCO_RLD2_TMR_MAX)
+			timeout = TCO_RLD2_TMR_MAX;
 		tmr_val16 |= timeout;
 		ichwd_write_tco_2(sc, TCO_TMR2, tmr_val16);
 	}
@@ -474,11 +467,13 @@ ichwd_attach(device_t dev)
 	    device_get_desc(dev), sc->ich_version);
 
 	/*
-	 * XXX we should check the status registers (specifically, the
-	 * TCO_SECOND_TO_STS bit in the TCO2_STS register) to see if we
-	 * just came back from a watchdog-induced reset, and let the user
-	 * know.
+	 * Determine if we are coming up after a watchdog-induced reset.  Some
+	 * BIOSes may clear this bit at bootup, preventing us from reporting
+	 * this case on such systems.  We clear this bit in ichwd_sts_reset().
 	 */
+	if ((ichwd_read_tco_2(sc, TCO2_STS) & TCO_SECOND_TO_STS) != 0)
+		device_printf(dev,
+		    "resuming after hardware watchdog timeout\n");
 
 	/* reset the watchdog status registers */
 	ichwd_sts_reset(sc);

Modified: stable/8/sys/dev/ichwd/ichwd.h
==============================================================================
--- stable/8/sys/dev/ichwd/ichwd.h	Mon Dec 27 12:39:24 2010	(r216734)
+++ stable/8/sys/dev/ichwd/ichwd.h	Mon Dec 27 12:52:35 2010	(r216735)
@@ -153,6 +153,17 @@ struct ichwd_softc {
 #define TCO_TMR_HALT		0x0800 /* clear to enable WDT */
 #define TCO_CNT_PRESERVE	0x0200 /* preserve these bits */
 
+/*
+ * Masks for the TCO timer value field in TCO_RLD.
+ * If the datasheets are to be believed, the minimum value actually varies
+ * from chipset to chipset - 4 for ICH5 and 2 for all other chipsets.
+ * I suspect this is a bug in the ICH5 datasheet and that the minimum is
+ * uniformly 2, but I'd rather err on the side of caution.
+ */
+#define TCO_RLD_TMR_MIN		0x0004
+#define TCO_RLD1_TMR_MAX	0x003f
+#define TCO_RLD2_TMR_MAX	0x03ff
+
 /* approximate length in nanoseconds of one WDT tick (about 0.6 sec) */
 #define ICHWD_TICK		600000000
 


More information about the svn-src-all mailing list