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);