PATCH: get_cyclecount() on ARMv6 and better
Aleksandr Rybalko
ray at freebsd.org
Sat Aug 3 11:51:48 UTC 2013
On Sat, 3 Aug 2013 10:24:40 +0100
Mark R V Murray <mark at grondar.org> wrote:
> Hi folks
>
> The CSPRNG used to drive /dev/random is Yarrow, and it needs good
> timing jitter to produce decent numbers.
>
> The i86_32 and i86_64 platforms both have the TSC register, wrapped
> in the get_cyclecount() inline function, but the ARM platform doesn't
> use its equivalent, the CCNT register. The alternative, using system
> time, loses LOTS of low-bit jitter, and is certainly worth improving
> upon.
>
> I'm at the early stages of testing the patch below (I only have RPi),
> and would like to get some comments and reviews, please. I am very
> doubtful indeed that I got the #ifdefs right - they are a bit of a
> minefield! ;-)
>
> The patch returns the 32-bit CCNT register as the 64-bit quantity
> that get_cyclecount() provides on all platforms; this is a very minor
> problem, but I suppose I could figure out some kind of crude carry
> mechanism and force the number to increment beyond 32 bits; I doubt
> its worth it though, as its the low bits that provide the jitter.
>
> Thanks in advance!
>
> M
> --
> Mark R V Murray
>
> Index: cpu.h
> ===================================================================
> --- cpu.h (revision 253832)
> +++ cpu.h (working copy)
> @@ -5,6 +5,9 @@
> #define MACHINE_CPU_H
>
> #include <machine/armreg.h>
> +#ifndef _KERNEL
> +#include <machine/sysarch.h>
> +#endif
>
> void cpu_halt(void);
> void swi_vm(void *);
> @@ -13,11 +16,26 @@
> static __inline uint64_t
> get_cyclecount(void)
> {
> +#if defined (__ARM_ARCH_7__) || \
> + defined (__ARM_ARCH_7A__) || \
> + defined (__ARM_ARCH_6__) || \
> + defined (__ARM_ARCH_6J__) || \
> + defined (__ARM_ARCH_6K__) || \
> + defined (__ARM_ARCH_6T2__) || \
> + defined (__ARM_ARCH_6Z__) || \
> + defined (__ARM_ARCH_6ZK__)
> +
> + uint32_t ccnt;
> +
> + /* Read CCNT. Darn; its only 32 bits. */
> + __asm __volatile("mrc p15, 0, %0, c9, c13, 0": "=r" (ccnt));
> + return ((uint64_t)ccnt);
> +#else
> struct bintime bt;
>
> binuptime(&bt);
> return ((uint64_t)bt.sec << 56 | bt.frac >> 8);
> -
> +#endif
> }
> #endif
>
>
Hi Mark!
Do we setup Performance Monitor Control Register before use that
counter?
WBW
--
Aleksandr Rybalko <ray at freebsd.org>
More information about the freebsd-arm
mailing list