Author: ian Date: Fri Feb 13 16:21:36 2015 New Revision: 278680 URL: https://svnweb.freebsd.org/changeset/base/278680
Log: MFC r266083, r267597: Give suitably-endowed ARMs a register similar to the x86 TSC register. Modified: stable/10/sys/arm/arm/cpufunc.c stable/10/sys/arm/include/cpu.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/arm/arm/cpufunc.c ============================================================================== --- stable/10/sys/arm/arm/cpufunc.c Fri Feb 13 16:08:45 2015 (r278679) +++ stable/10/sys/arm/arm/cpufunc.c Fri Feb 13 16:21:36 2015 (r278680) @@ -1397,6 +1397,53 @@ arm10_setup(args) } #endif /* CPU_ARM9E || CPU_ARM10 */ +#if defined(CPU_ARM1136) || defined(CPU_ARM1176) \ + || defined(CPU_MV_PJ4B) \ + || defined(CPU_CORTEXA) || defined(CPU_KRAIT) +static __inline void +cpu_scc_setup_ccnt(void) +{ +/* This is how you give userland access to the CCNT and PMCn + * registers. + * BEWARE! This gives write access also, which may not be what + * you want! + */ +#ifdef _PMC_USER_READ_WRITE_ +#if defined(CPU_ARM1136) || defined(CPU_ARM1176) + /* Use the Secure User and Non-secure Access Validation Control Register + * to allow userland access + */ + __asm volatile ("mcr p15, 0, %0, c15, c9, 0\n\t" + : + : "r"(0x00000001)); +#else + /* Set PMUSERENR[0] to allow userland access */ + __asm volatile ("mcr p15, 0, %0, c9, c14, 0\n\t" + : + : "r"(0x00000001)); +#endif +#endif +#if defined(CPU_ARM1136) || defined(CPU_ARM1176) + /* Set PMCR[2,0] to enable counters and reset CCNT */ + __asm volatile ("mcr p15, 0, %0, c15, c12, 0\n\t" + : + : "r"(0x00000005)); +#else + /* Set up the PMCCNTR register as a cyclecounter: + * Set PMINTENCLR to 0xFFFFFFFF to block interrupts + * Set PMCR[2,0] to enable counters and reset CCNT + * Set PMCNTENSET to 0x80000000 to enable CCNT */ + __asm volatile ("mcr p15, 0, %0, c9, c14, 2\n\t" + "mcr p15, 0, %1, c9, c12, 0\n\t" + "mcr p15, 0, %2, c9, c12, 1\n\t" + : + : "r"(0xFFFFFFFF), + "r"(0x00000005), + "r"(0x80000000)); +#endif +} +#endif + #if defined(CPU_ARM1136) || defined(CPU_ARM1176) struct cpu_option arm11_options[] = { { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, @@ -1500,6 +1547,8 @@ arm11x6_setup(char *args) /* And again. */ cpu_idcache_wbinv_all(); + + cpu_scc_setup_ccnt(); } #endif /* CPU_ARM1136 || CPU_ARM1176 */ @@ -1534,6 +1583,8 @@ pj4bv7_setup(args) /* And again. */ cpu_idcache_wbinv_all(); + + cpu_scc_setup_ccnt(); } #endif /* CPU_MV_PJ4B */ @@ -1581,6 +1632,8 @@ cortexa_setup(char *args) #ifdef SMP armv7_auxctrl((1 << 6) | (1 << 0), (1 << 6) | (1 << 0)); /* Enable SMP + TLB broadcasting */ #endif + + cpu_scc_setup_ccnt(); } #endif /* CPU_CORTEXA */ Modified: stable/10/sys/arm/include/cpu.h ============================================================================== --- stable/10/sys/arm/include/cpu.h Fri Feb 13 16:08:45 2015 (r278679) +++ stable/10/sys/arm/include/cpu.h Fri Feb 13 16:21:36 2015 (r278680) @@ -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 _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"