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 [email protected]