How to read the system timer?

How can I read the system timer in AArch64 assembly?
I want to read a global timer, not a timer local to each processor.

What are you trying to achieve exactly ? With ARMv8 there are per-core generic timers, system (linux) relies on these timers to track time (cf kernel/time/timekeeping.c). At user-space level you can typically retrieve ‘time’ with the gettimeofday function (cf arch/arm64/kernel/vdso/gettimeofday.S). You can also directly read the value of the timer (CNTVCT_EL0 register).

I’m writing a bare-metal program.
I want to get elapsed time between a core executes an instruction, and other core executes another.
This can be achieved if I can read the global timer.
Per-core timers are not suitable for this usage because I guess they have some gap.

I guessed I could read the system-wide timer via some memory-mapped registers.
So I wanted to know to which address the system timer is mapped.

If I’m not wrong timer counter is a system-wide64-bit count, which counts up from zero, giving a consistent view of time across cores. Each core can then manage its own comparators, typically to generate per-core timer interrupt.

The CNTFRQ_EL0 register reports the frequency of the system timer.
The CNTPCT_EL0 register reports the current count value.
CNTKCTL_EL1 controls whether EL0 can access the system timer.

I suggest you to have a look at the programmer’s Guide for ARMv8-A.

1 Like

I have already read the Architecture Reference Manual for ARMv8-A, but I misunderstood that the value of CNTFRQ_EL0 and CNTPCT_EL0 is per-core.
Now I understand that they have system-wide values.

Thank you for your quick response!
And sorry for that my question is not relevant to HiKey960.

@ordovicia Any idea on how to scale the cntfrq value with the actual CPU frequency?

What do you mean, you’re not supposed to change system timer frequency.