The HPET appears to be broken on silby's Acer Pentium M system, never

advancing.  Read from the timer before attaching to be sure it advances
in 1 us.  Since the slowest rate allowed by the spec is 10 MHz, the
timer is guaranteed to change in this interval if it is working.

Tested by:	Rui Paulo
Approved by:	re
MFC after:	3 days
This commit is contained in:
Nate Lawson 2007-07-22 20:45:27 +00:00
parent 944f82cd4f
commit 9bbad5af65

View file

@ -140,7 +140,7 @@ acpi_hpet_attach(device_t dev)
{
struct acpi_hpet_softc *sc;
int rid;
uint32_t val;
uint32_t val, val2;
uintmax_t freq;
ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
@ -163,6 +163,9 @@ acpi_hpet_attach(device_t dev)
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;
@ -175,12 +178,23 @@ acpi_hpet_attach(device_t dev)
((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);