> Date: Thu, 11 Jun 2020 19:38:48 +0200 > From: Christian Weisgerber <na...@mips.inka.de> > > 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.
Hope you didn't spend too much time on that, because I already mentioned that I had arm64 working earlier in the thread. I've just fired up one of my sparc64 machines such that I can check how well the approach works for an architecture with two exported timecounters. As for decreasing the complexity of the diff, I think naddy's suggestion to have an MD header file actually helps. With that file we can easily avoid the function pointer and it becomes easier adding new timecounters in the kernel (which happens from time to time). Further opportunities to decrease the complexity: 1. Drop support for CLOCK_UPTIME and CLOCK_BOOTTIME. 2. Avoid using bintime. That would decouple the libc code more from the kernel timecounter implementation details. The downside of this is that we can't just copy and paste kernel code like we do now so this may not be a genuine benefit. I consider that mostly polishing though, although the polishing has to be done before this hits the tree. The real question that still need to be answered are: 1. Are we happy with an implementation that can only support clock/architectures that have a clock that can be accessed through a register or special instruction? 2. What are we going to do with the TSC on amd64 with regards to them not being synched up properly. For me the answers are: 1. Yes. 2. Not expose the TSC to userland if there is a significant skew. Cheers, Mark > --- ./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 > >