summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorScott Soule Cheloha <cheloha@cvs.openbsd.org>2022-09-12 10:58:06 +0000
committerScott Soule Cheloha <cheloha@cvs.openbsd.org>2022-09-12 10:58:06 +0000
commite9554cfa2874d6ab11f3fd3cc518cad9f7798383 (patch)
tree8cdaa90d01252bd3454d748f24a046116e63b563 /sys/dev
parentb2170cf8198db9bff0e63c94394c1e924bbf7254 (diff)
acpihpet(4): acpihpet_delay: only use lower 32 bits of counter
We can't use acpihpet_r() to implement acpihpet_delay(). Even if we made acpihpet_r() atomic on amd64, i386 would still be incapable of doing atomic 8-byte reads. As-is, the code does a split read on all platforms, which may or may not already be causing problems with TSC calibration: https://marc.info/?l=openbsd-tech&m=166220561709496&w=2 Switch from acpihpet_r() to bus_space_read_4() and only use the lower 32 bits of the counter. This makes acpihpet_delay() slightly larger, but unless we want two acpihpet_delay() implementations we have no choice. Link: https://marc.info/?l=openbsd-tech&m=166165347220077&w=2 ok jsg@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/acpi/acpihpet.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/dev/acpi/acpihpet.c b/sys/dev/acpi/acpihpet.c
index bb1e6c56947..7b7898ff185 100644
--- a/sys/dev/acpi/acpihpet.c
+++ b/sys/dev/acpi/acpihpet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpihpet.c,v 1.28 2022/08/25 18:01:54 cheloha Exp $ */
+/* $OpenBSD: acpihpet.c,v 1.29 2022/09/12 10:58:05 cheloha Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
@@ -281,13 +281,19 @@ acpihpet_attach(struct device *parent, struct device *self, void *aux)
void
acpihpet_delay(int usecs)
{
- uint64_t c, s;
+ uint64_t count = 0, cycles;
struct acpihpet_softc *sc = hpet_timecounter.tc_priv;
+ uint32_t val1, val2;
- 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)
+ val2 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, HPET_MAIN_COUNTER);
+ cycles = usecs * hpet_timecounter.tc_frequency / 1000000;
+ while (count < cycles) {
CPU_BUSY_CYCLE();
+ val1 = val2;
+ val2 = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ HPET_MAIN_COUNTER);
+ count += val2 - val1;
+ }
}
u_int