Theo de Raadt:

> The diff is growing complexity to support a future which wouldn't
> exist if attempts at *supporting all* architectures received priority.

Adding support for more archs is very simple, since you just need
to copy the corresponding get_timecounter function from the kernel.

Here's arm64.  I'm running a kernel and libc with this.

I can also provide alpha, powerpc, and sparc64, but I don't have
such machines.

--- ./lib/libc/arch/aarch64/gen/usertc.c.orig   Thu Jun 11 19:07:39 2020
+++ ./lib/libc/arch/aarch64/gen/usertc.c        Thu Jun 11 19:08:01 2020
@@ -18,4 +18,32 @@
 #include <sys/types.h>
 #include <sys/timetc.h>
 
-int (*const _tc_get_timecount)(struct timekeep *, uint64_t *) = NULL;
+static uint64_t
+readcnt64(void)
+{
+       uint64_t val0, val1;
+
+       /*
+        * Work around Cortex-A73 errata 858921, where there is a
+        * one-cycle window where the read might return the old value
+        * for the low 32 bits and the new value for the high 32 bits
+        * upon roll-over of the low 32 bits.
+        */
+       __asm volatile("isb" : : : "memory");
+       __asm volatile("mrs %x0, CNTVCT_EL0" : "=r" (val0));
+       __asm volatile("mrs %x0, CNTVCT_EL0" : "=r" (val1));
+       return ((val0 ^ val1) & 0x100000000ULL) ? val0 : val1;
+}
+
+int
+tc_get_timecount(struct timekeep *tk, uint64_t *tc)
+{
+       if (tc == NULL || tk->tk_user != 1)
+               return -1;
+
+       *tc = readcnt64();
+       return 0;
+}
+
+int (*const _tc_get_timecount)(struct timekeep *, uint64_t *)
+       = tc_get_timecount;
--- ./sys/arch/arm64/arm64/machdep.c.orig       Thu Jun 11 17:46:54 2020
+++ ./sys/arch/arm64/arm64/machdep.c    Thu Jun 11 17:46:59 2020
@@ -91,7 +91,7 @@
 char    machine[] = MACHINE;            /* from <machine/param.h> */
 
 /* timekeep number of user accesible clocks */
-int tk_nclocks = 0;
+int tk_nclocks = 1;
 
 int safepri = 0;
 
--- ./sys/arch/arm64/dev/agtimer.c.orig Thu Jun 11 17:47:23 2020
+++ ./sys/arch/arm64/dev/agtimer.c      Thu Jun 11 17:47:27 2020
@@ -43,7 +43,7 @@
 u_int agtimer_get_timecount(struct timecounter *);
 
 static struct timecounter agtimer_timecounter = {
-       agtimer_get_timecount, NULL, 0x7fffffff, 0, "agtimer", 0, NULL, 0
+       agtimer_get_timecount, NULL, 0x7fffffff, 0, "agtimer", 0, NULL, 1
 };
 
 struct agtimer_pcpu_softc {
-- 
Christian "naddy" Weisgerber                          na...@mips.inka.de

Reply via email to