1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2015 RehiveTech. All rights reserved. 3 */ 4 5 #ifndef _RTE_CYCLES_ARM32_H_ 6 #define _RTE_CYCLES_ARM32_H_ 7 8 /* ARM v7 does not have suitable source of clock signals. 9 * The only clock counter available in the core is 32 bit wide. 10 * Therefore it is unsuitable as the counter overlaps every few seconds 11 * and probably is not accessible by userspace programs. 12 * Therefore we use clock_gettime(CLOCK_MONOTONIC_RAW) 13 * to simulate counter running at 1GHz. 14 */ 15 16 #include <time.h> 17 18 #include "generic/rte_cycles.h" 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 /** 25 * Read the time base register. 26 * 27 * @return 28 * The time base for this lcore. 29 */ 30 #ifndef RTE_ARM_EAL_RDTSC_USE_PMU 31 32 /** 33 * This call is easily portable to any architecture, however, 34 * it may require a system call and imprecise for some tasks. 35 */ 36 static inline uint64_t 37 __rte_rdtsc_syscall(void) 38 { 39 struct timespec val; 40 uint64_t v; 41 42 while (clock_gettime(CLOCK_MONOTONIC_RAW, &val) != 0) 43 /* no body */; 44 45 v = (uint64_t) val.tv_sec * 1000000000LL; 46 v += (uint64_t) val.tv_nsec; 47 return v; 48 } 49 #define rte_rdtsc __rte_rdtsc_syscall 50 51 #else 52 53 /** 54 * This function requires to configure the PMCCNTR and enable 55 * userspace access to it: 56 * 57 * asm volatile("mcr p15, 0, %0, c9, c14, 0" : : "r"(1)); 58 * asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(29)); 59 * asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r"(0x8000000f)); 60 * 61 * which is possible only from the privileged mode (kernel space). 62 */ 63 static inline uint64_t 64 __rte_rdtsc_pmccntr(void) 65 { 66 unsigned tsc; 67 uint64_t final_tsc; 68 69 /* Read PMCCNTR */ 70 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(tsc)); 71 /* 1 tick = 64 clocks */ 72 final_tsc = ((uint64_t)tsc) << 6; 73 74 return (uint64_t)final_tsc; 75 } 76 #define rte_rdtsc __rte_rdtsc_pmccntr 77 78 #endif /* RTE_ARM_EAL_RDTSC_USE_PMU */ 79 80 static inline uint64_t 81 rte_rdtsc_precise(void) 82 { 83 rte_mb(); 84 return rte_rdtsc(); 85 } 86 87 static inline uint64_t 88 rte_get_tsc_cycles(void) { return rte_rdtsc(); } 89 90 #ifdef __cplusplus 91 } 92 #endif 93 94 #endif /* _RTE_CYCLES_ARM32_H_ */ 95