Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Jul 2007 18:55:15 -0700
From:      Nate Lawson <nate@root.org>
To:        current@FreeBSD.org
Subject:   patch to catch non-working hpet
Message-ID:  <4696DB83.4000803@root.org>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------040802030100070704070802
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

I need someone to test this code.  You have to have an HPET timer.  It
should detect the case where it's non-working on at least one Acer
system but not break others.  Your system should boot and work normally
with no change in dmesg.  Let me know if it breaks something, thx.


--------------040802030100070704070802
Content-Type: text/x-patch;
 name="hpet1.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="hpet1.diff"

Index: sys/dev/acpica/acpi_hpet.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/acpica/acpi_hpet.c,v
retrieving revision 1.5.2.4
diff -u -r1.5.2.4 acpi_hpet.c
--- sys/dev/acpica/acpi_hpet.c	18 Jun 2007 00:29:55 -0000	1.5.2.4
+++ sys/dev/acpica/acpi_hpet.c	12 Jul 2007 21:20:27 -0000
@@ -144,7 +144,7 @@
 {
 	struct acpi_hpet_softc *sc;
 	int rid;
-	uint32_t val;
+	uint32_t val, val2;
 	uintmax_t freq;
 
 	ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
@@ -167,6 +167,9 @@
 		return (ENXIO);
 	}
 
+	/* Be sure timer is enabled. */
+	bus_write_4(sc->mem_res, HPET_OFFSET_ENABLE, 1);
+
 	/* Read basic statistics about the timer. */
 	val = bus_read_4(sc->mem_res, HPET_OFFSET_PERIOD);
 	freq = (1000000000000000LL + val / 2) / val;
@@ -179,12 +182,23 @@
 		    ((val >> 13) & 1) ? " count_size" : "");
 	}
 
-	/* Be sure it is enabled. */
-	bus_write_4(sc->mem_res, HPET_OFFSET_ENABLE, 1);
-
 	if (testenv("debug.acpi.hpet_test"))
 		acpi_hpet_test(sc);
 
+	/*
+	 * Don't attach if the timer never increments.  Since the spec
+	 * requires it to be at least 10 MHz, it has to change in 1 us.
+	 */
+	val = bus_read_4(sc->mem_res, HPET_OFFSET_VALUE);
+	DELAY(1);
+	val2 = bus_read_4(sc->mem_res, HPET_OFFSET_VALUE);
+	if (val == val2) {
+		device_printf(dev, "HPET never increments, disabling\n");
+		bus_write_4(sc->mem_res, HPET_OFFSET_ENABLE, 0);
+		bus_free_resource(dev, SYS_RES_MEMORY, sc->mem_res);
+		return (ENXIO);
+	}
+
 	hpet_timecounter.tc_frequency = freq;
 	hpet_timecounter.tc_priv = sc;
 	tc_init(&hpet_timecounter);

--------------040802030100070704070802--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4696DB83.4000803>