void acpitimerattach(struct device *parent, struct device *self, void *aux) { struct acpitimer_softc *sc = (struct acpitimer_softc *) self; struct acpi_softc *psc = (struct acpi_softc *) parent; int rc; if (psc->sc_fadt->hdr_revision >= 3 && psc->sc_fadt->x_pm_tmr_blk.address != 0) rc = acpi_map_address(psc, &psc->sc_fadt->x_pm_tmr_blk, 0, psc->sc_fadt->pm_tmr_len, &sc->sc_ioh, &sc->sc_iot); else rc = acpi_map_address(psc, NULL, psc->sc_fadt->pm_tmr_blk, psc->sc_fadt->pm_tmr_len, &sc->sc_ioh, &sc->sc_iot); if (rc) { printf(": can't map i/o space\n"); return; } printf(": %d Hz, %d bits\n", ACPI_FREQUENCY, psc->sc_fadt->flags & FADT_TMR_VAL_EXT ? 32 : 24); if (psc->sc_fadt->flags & FADT_TMR_VAL_EXT) acpi_timecounter.tc_counter_mask = 0xffffffffU; acpi_timecounter.tc_priv = sc; acpi_timecounter.tc_name = sc->sc_dev.dv_xname; tc_init(&acpi_timecounter); }
void acpihpet_attach(struct device *parent, struct device *self, void *aux) { struct acpihpet_softc *sc = (struct acpihpet_softc *) self; struct acpi_softc *psc = (struct acpi_softc *)parent; struct acpi_attach_args *aaa = aux; struct acpi_hpet *hpet = (struct acpi_hpet *)aaa->aaa_table; u_int64_t period, freq; /* timer period in femtoseconds (10^-15) */ u_int32_t v1, v2; int timeout; if (acpi_map_address(psc, &hpet->base_address, 0, HPET_REG_SIZE, &sc->sc_ioh, &sc->sc_iot)) { printf(": can't map i/o space\n"); return; } /* * Revisions 0x30 through 0x3a of the AMD SB700, with spread * spectrum enabled, have an SMM based HPET emulation that's * subtly broken. The hardware is initialized upon first * access of the configuration register. Initialization takes * some time during which the configuration register returns * 0xffffffff. */ timeout = 1000; do { if (bus_space_read_4(sc->sc_iot, sc->sc_ioh, HPET_CONFIGURATION) != 0xffffffff) break; } while(--timeout > 0); if (timeout == 0) { printf(": disabled\n"); return; } /* enable hpet */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, HPET_CONFIGURATION, 1); /* make sure hpet is working */ v1 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, HPET_MAIN_COUNTER); delay(1); v2 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, HPET_MAIN_COUNTER); if (v1 == v2) { printf(": counter not incrementing\n"); bus_space_write_4(sc->sc_iot, sc->sc_ioh, HPET_CONFIGURATION, 0); return; } period = bus_space_read_4(sc->sc_iot, sc->sc_ioh, HPET_CAPABILITIES + sizeof(u_int32_t)); if (period == 0) { printf(": invalid period\n"); bus_space_write_4(sc->sc_iot, sc->sc_ioh, HPET_CONFIGURATION, 0); return; } freq = 1000000000000000ull / period; printf(": %lld Hz\n", freq); hpet_timecounter.tc_frequency = (u_int32_t)freq; hpet_timecounter.tc_priv = sc; hpet_timecounter.tc_name = sc->sc_dev.dv_xname; tc_init(&hpet_timecounter); acpihpet_attached++; }