diff options
author | ian <ian@FreeBSD.org> | 2015-02-13 16:21:36 +0000 |
---|---|---|
committer | ian <ian@FreeBSD.org> | 2015-02-13 16:21:36 +0000 |
commit | 68023855e86ca07fa26e05298b542ed56ce32878 (patch) | |
tree | 2ab14dc94b71ce94730612912567cf42bfcdd2f4 /sys/arm/include | |
parent | 180276472cc13f04474f4c6d2a748edf4819057a (diff) | |
download | FreeBSD-src-68023855e86ca07fa26e05298b542ed56ce32878.zip FreeBSD-src-68023855e86ca07fa26e05298b542ed56ce32878.tar.gz |
MFC r266083, r267597:
Give suitably-endowed ARMs a register similar to the x86 TSC register.
Diffstat (limited to 'sys/arm/include')
-rw-r--r-- | sys/arm/include/cpu.h | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/sys/arm/include/cpu.h b/sys/arm/include/cpu.h index c6f7088..dd7b6ac 100644 --- a/sys/arm/include/cpu.h +++ b/sys/arm/include/cpu.h @@ -14,11 +14,35 @@ void swi_vm(void *); static __inline uint64_t get_cyclecount(void) { +/* This '#if' asks the question 'Does CP15/SCC include performance counters?' */ +#if defined(CPU_ARM1136) || defined(CPU_ARM1176) \ + || defined(CPU_MV_PJ4B) \ + || defined(CPU_CORTEXA) || defined(CPU_KRAIT) + uint32_t ccnt; + uint64_t ccnt64; + + /* + * Read PMCCNTR. Curses! Its only 32 bits. + * TODO: Fix this by catching overflow with interrupt? + */ +/* The ARMv6 vs ARMv7 divide is going to need a better way of + * distinguishing between them. + */ +#if defined(CPU_ARM1136) || defined(CPU_ARM1176) + /* ARMv6 - Earlier model SCCs */ + __asm __volatile("mrc p15, 0, %0, c15, c12, 1": "=r" (ccnt)); +#else + /* ARMv7 - Later model SCCs */ + __asm __volatile("mrc p15, 0, %0, c9, c13, 0": "=r" (ccnt)); +#endif + ccnt64 = (uint64_t)ccnt; + return (ccnt64); +#else /* No performance counters, so use binuptime(9). This is slooooow */ struct bintime bt; binuptime(&bt); return ((uint64_t)bt.sec << 56 | bt.frac >> 8); - +#endif } #endif |