summaryrefslogtreecommitdiff
path: root/sys/arch/arm64
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2017-02-07 21:51:04 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2017-02-07 21:51:04 +0000
commit32186ec30002874db64d52ca745048834a153ae7 (patch)
tree37365505d0717e259aba9d6f0dd8bd53d2803173 /sys/arch/arm64
parent5bd2506a1256271eefbc5a5fb94919ea766092cb (diff)
The default frequency we chose for the generic timer does not always ring
true. Instead, unless overwritten by the device tree, we should ask the generic timer for its frequency. This fixes time on my AMD Seattle and should improve time management on QEMU as well.
Diffstat (limited to 'sys/arch/arm64')
-rw-r--r--sys/arch/arm64/dev/agtimer.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/sys/arch/arm64/dev/agtimer.c b/sys/arch/arm64/dev/agtimer.c
index 451f439715f..bbcb37ee038 100644
--- a/sys/arch/arm64/dev/agtimer.c
+++ b/sys/arch/arm64/dev/agtimer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agtimer.c,v 1.3 2017/01/23 10:15:53 kettenis Exp $ */
+/* $OpenBSD: agtimer.c,v 1.4 2017/02/07 21:51:03 patrick Exp $ */
/*
* Copyright (c) 2011 Dale Rahn <drahn@openbsd.org>
* Copyright (c) 2013 Patrick Wildt <patrick@blueri.se>
@@ -100,6 +100,16 @@ agtimer_readcnt64(void)
return (val);
}
+static inline uint64_t
+agtimer_get_freq(void)
+{
+ uint64_t val;
+
+ __asm volatile("MRS %x0, CNTFRQ_EL0" : "=r" (val));
+
+ return (val);
+}
+
static inline int
agtimer_get_ctrl(void)
{
@@ -149,6 +159,8 @@ agtimer_attach(struct device *parent, struct device *self, void *aux)
sc->sc_node = faa->fa_node;
+ if (agtimer_get_freq() != 0)
+ agtimer_frequency = agtimer_get_freq();
agtimer_frequency =
OF_getpropint(sc->sc_node, "clock-frequency", agtimer_frequency);
sc->sc_ticks_per_second = agtimer_frequency;