Current-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Weird clock behaviour with current (amd64) kernel
mlelstv%serpens.de@localhost (Michael van Elst) writes:
>In your case, you say it takes ~6 minutes between attachment and
>calibration and your hpet runs at 19.2MHz.
>This is enough for HPET_MCOUNT_LO to overflow.
This patch adds a separate delay of ~0.1 seconds to calibrate
the timers. This should avoid any overflow.
Index: sys/dev/ic/hpet.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/hpet.c,v
retrieving revision 1.17
diff -p -u -r1.17 hpet.c
--- sys/dev/ic/hpet.c 16 May 2020 23:06:40 -0000 1.17
+++ sys/dev/ic/hpet.c 13 Aug 2022 21:24:58 -0000
@@ -54,8 +54,6 @@ static u_int hpet_get_timecount(struct t
static bool hpet_resume(device_t, const pmf_qual_t *);
static struct hpet_softc *hpet0 __read_mostly;
-static uint32_t hpet_attach_val;
-static uint64_t hpet_attach_tsc;
int
hpet_detach(device_t dv, int flags)
@@ -147,14 +145,6 @@ hpet_attach_subr(device_t dv)
eval = bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT_LO);
val = eval - sval;
sc->sc_adj = (int64_t)val * sc->sc_period / 1000;
-
- /* Store attach-time values for computing TSC frequency later. */
- if (cpu_hascounter() && sc == hpet0) {
- (void)cpu_counter();
- val = bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT_LO);
- hpet_attach_tsc = cpu_counter();
- hpet_attach_val = val;
- }
}
static u_int
@@ -214,33 +204,37 @@ uint64_t
hpet_tsc_freq(void)
{
struct hpet_softc *sc;
- uint64_t td, val, freq;
- uint32_t hd;
+ uint64_t td0, td, val, freq;
+ uint32_t hd0, hd;
int s;
if (hpet0 == NULL || !cpu_hascounter())
return 0;
- /* Slow down if we got here from attach in under 0.1s. */
sc = hpet0;
- hd = bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT_LO);
- hd -= hpet_attach_val;
- if (hd < (uint64_t)100000 * 1000000000 / sc->sc_period)
- hpet_delay(100000);
+
+ s = splhigh();
+ (void)cpu_counter();
+ (void)bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT_LO);
+ hd0 = bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT_LO);
+ td0 = cpu_counter();
+ splx(s);
+
+ hpet_delay(100000);
/*
* Determine TSC freq by comparing how far the TSC and HPET have
- * advanced since attach time. Take the cost of reading HPET
- * register into account and round result to the nearest 1000.
+ * advanced and round result to the nearest 1000.
*/
s = splhigh();
(void)cpu_counter();
+ (void)bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT_LO);
hd = bus_space_read_4(sc->sc_memt, sc->sc_memh, HPET_MCOUNT_LO);
td = cpu_counter();
splx(s);
- hd -= hpet_attach_val;
- val = ((uint64_t)hd * sc->sc_period - sc->sc_adj) / 100000000;
- freq = (td - hpet_attach_tsc) * 10000000 / val;
+
+ val = (uint64_t)(hd - hd0) * sc->sc_period / 100000000;
+ freq = (td - td0) * 10000000 / val;
return rounddown(freq + 500, 1000);
}
Home |
Main Index |
Thread Index |
Old Index