From 7de1614a8456d310feda61b8079c4a7d93d948a2 Mon Sep 17 00:00:00 2001 From: cheloha Date: Thu, 25 Aug 2022 17:54:33 +0000 Subject: [PATCH] acpihpet(4): add acpihpet_delay(), another delay(9) implementation When lapic_delay() is removed from the tree in the near future, older machines without a constant/invariant TSC will need a delay(9) implementation better than i8254_delay(). This patch adds acpihpet_delay(), a delay(9) implementation based on the ACPI HPET timer. It is preferable to i8254_delay() (0) and acpitimer_delay() (1000), so set its quality to 2000. On newer machines, the HPET is slower to read than the PMT on newer machines for reasons unknown, so _technically_ this quality hierarchy is not always accurate. However, we expect these newer machines to have a constant/invariant TSC available, so the inaccuracy is harmless because tsc_delay() will be available, which is better than both the PMT and the HPET. In general, on real hardware that predates wide availability of the constant/invariant TSC, the HPET is preferable to the PMT. With input from jsg@. Link: https://marc.info/?l=openbsd-tech&m=166053729104923&w=2 ok mlarkin@ jsg@ --- sys/dev/acpi/acpihpet.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/sys/dev/acpi/acpihpet.c b/sys/dev/acpi/acpihpet.c index b917edbcd2b..87eaf02d37e 100644 --- a/sys/dev/acpi/acpihpet.c +++ b/sys/dev/acpi/acpihpet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpihpet.c,v 1.26 2022/04/06 18:59:27 naddy Exp $ */ +/* $OpenBSD: acpihpet.c,v 1.27 2022/08/25 17:54:33 cheloha Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert * @@ -18,9 +18,11 @@ #include #include #include +#include #include #include +#include #include #include @@ -31,7 +33,7 @@ int acpihpet_attached; int acpihpet_match(struct device *, void *, void *); void acpihpet_attach(struct device *, struct device *, void *); int acpihpet_activate(struct device *, int); - +void acpihpet_delay(int); u_int acpihpet_gettime(struct timecounter *tc); uint64_t acpihpet_r(bus_space_tag_t _iot, bus_space_handle_t _ioh, @@ -266,6 +268,9 @@ acpihpet_attach(struct device *parent, struct device *self, void *aux) hpet_timecounter.tc_priv = sc; hpet_timecounter.tc_name = sc->sc_dev.dv_xname; tc_init(&hpet_timecounter); + + delay_init(acpihpet_delay, 2000); + #if defined(__amd64__) extern void cpu_recalibrate_tsc(struct timecounter *); cpu_recalibrate_tsc(&hpet_timecounter); @@ -273,6 +278,18 @@ acpihpet_attach(struct device *parent, struct device *self, void *aux) acpihpet_attached++; } +void +acpihpet_delay(int usecs) +{ + uint64_t c, s; + struct acpihpet_softc *sc = hpet_timecounter.tc_priv; + + s = acpihpet_r(sc->sc_iot, sc->sc_ioh, HPET_MAIN_COUNTER); + c = usecs * hpet_timecounter.tc_frequency / 1000000; + while (acpihpet_r(sc->sc_iot, sc->sc_ioh, HPET_MAIN_COUNTER) - s < c) + CPU_BUSY_CYCLE(); +} + u_int acpihpet_gettime(struct timecounter *tc) { -- 2.20.1