diff --git a/sys/man/2/cputime b/sys/man/2/cputime index 4d6440116..282e93ade 100644 --- a/sys/man/2/cputime +++ b/sys/man/2/cputime @@ -39,6 +39,7 @@ if any, and stores it via Currently supported architectures are .BR 386 , .BR amd64 , +.B arm64 and .BR power ; on all others, diff --git a/sys/src/9/bcm64/clock.c b/sys/src/9/bcm64/clock.c index f7b3e55f7..f5fcc4784 100644 --- a/sys/src/9/bcm64/clock.c +++ b/sys/src/9/bcm64/clock.c @@ -2,14 +2,14 @@ * bcm283[56] timers * System timers run at 1MHz (timers 1 and 2 are used by GPU) * ARM timer usually runs at 250MHz (may be slower in low power modes) - * Cycle counter runs at 700MHz (unless overclocked) * All are free-running up-counters * * Use system timer 3 (64 bits) for hzclock interrupts and fastticks * For smp on bcm2836, use local generic timer for interrupts on cpu1-3 * Use ARM timer (32 bits) for perfticks * Use ARM timer to force immediate interrupt - * Use cycle counter for cycles() + * Use performance cycle counter for lcycles() + * Use generic timer virtual counter for cycles() */ #include "u.h" @@ -118,6 +118,7 @@ clockinit(void) syswr(PMCR_EL0, 1<<6 | 7); syswr(PMCNTENSET, 1<<31); syswr(PMUSERENR_EL0, 1<<2); + syswr(CNTKCTL_EL1, 1<<1); syswr(CNTP_TVAL_EL0, ~0UL); if(m->machno == 0){ @@ -147,7 +148,19 @@ clockinit(void) t1 -= t0; m->cpuhz = 100 * t1; m->cpumhz = (m->cpuhz + Mhz/2 - 1) / Mhz; - m->cyclefreq = m->cpuhz; + + /* + * Cyclefreq used to be the same as cpuhz as + * we where using the PMCCNTR_EL0 which counts + * per core cpu cycles. But is is kind of useless + * in userspace because each core has a differnet + * counter and it stops when the core is idle (WFI). + * So we change it to use the generic timer + * virtual counter register CNTVCT_EL0 instead + * running at the same frequency as system timer. + * (CNTFRQ_EL0 is WRONG on raspberry pi). + */ + m->cyclefreq = SystimerFreq; if(m->machno == 0){ tn->cs = 1<<3; diff --git a/sys/src/9/bcm64/sysreg.h b/sys/src/9/bcm64/sysreg.h index c057bbba8..0d9b1b172 100644 --- a/sys/src/9/bcm64/sysreg.h +++ b/sys/src/9/bcm64/sysreg.h @@ -32,6 +32,8 @@ #define PMUSERENR_EL0 SYSREG(3,3,9,14,0) #define CNTPCT_EL0 SYSREG(3,3,14,0,1) +#define CNTVCT_EL0 SYSREG(3,3,14,0,2) +#define CNTKCTL_EL1 SYSREG(3,0,14,1,0) #define CNTP_TVAL_EL0 SYSREG(3,3,14,2,0) #define CNTP_CTL_EL0 SYSREG(3,3,14,2,1) #define CNTP_CVAL_EL0 SYSREG(3,3,14,2,2) diff --git a/sys/src/libc/arm64/cycles.s b/sys/src/libc/arm64/cycles.s index 389ea201f..03955b9ad 100644 --- a/sys/src/libc/arm64/cycles.s +++ b/sys/src/libc/arm64/cycles.s @@ -1,7 +1,7 @@ #define SYSREG(op0,op1,Cn,Cm,op2) SPR(((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5)) -#define PMCCNTR_EL0 SYSREG(3,3,9,13,0) +#define CNTVCT_EL0 SYSREG(3,3,14,0,2) TEXT cycles(SB), 1, $-4 - MRS PMCCNTR_EL0, R1 + MRS CNTVCT_EL0, R1 MOV R1, (R0) RETURN