199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2015 RehiveTech. All rights reserved. 399a2dd95SBruce Richardson */ 499a2dd95SBruce Richardson 599a2dd95SBruce Richardson #ifndef _RTE_CYCLES_ARM32_H_ 699a2dd95SBruce Richardson #define _RTE_CYCLES_ARM32_H_ 799a2dd95SBruce Richardson 8d5d13ef9SThomas Monjalon /* ARM v7 does not have suitable source of clock signals. 9d5d13ef9SThomas Monjalon * The only clock counter available in the core is 32 bit wide. 10d5d13ef9SThomas Monjalon * Therefore it is unsuitable as the counter overlaps every few seconds 11d5d13ef9SThomas Monjalon * and probably is not accessible by userspace programs. 12d5d13ef9SThomas Monjalon * Therefore we use clock_gettime(CLOCK_MONOTONIC_RAW) 13d5d13ef9SThomas Monjalon * to simulate counter running at 1GHz. 1499a2dd95SBruce Richardson */ 1599a2dd95SBruce Richardson 1699a2dd95SBruce Richardson #include <time.h> 1799a2dd95SBruce Richardson 18*719834a6SMattias Rönnblom #include "generic/rte_cycles.h" 19*719834a6SMattias Rönnblom 2099a2dd95SBruce Richardson #ifdef __cplusplus 2199a2dd95SBruce Richardson extern "C" { 2299a2dd95SBruce Richardson #endif 2399a2dd95SBruce Richardson 2499a2dd95SBruce Richardson /** 2599a2dd95SBruce Richardson * Read the time base register. 2699a2dd95SBruce Richardson * 2799a2dd95SBruce Richardson * @return 2899a2dd95SBruce Richardson * The time base for this lcore. 2999a2dd95SBruce Richardson */ 3099a2dd95SBruce Richardson #ifndef RTE_ARM_EAL_RDTSC_USE_PMU 3199a2dd95SBruce Richardson 3299a2dd95SBruce Richardson /** 3399a2dd95SBruce Richardson * This call is easily portable to any architecture, however, 347be78d02SJosh Soref * it may require a system call and imprecise for some tasks. 3599a2dd95SBruce Richardson */ 3699a2dd95SBruce Richardson static inline uint64_t 3799a2dd95SBruce Richardson __rte_rdtsc_syscall(void) 3899a2dd95SBruce Richardson { 3999a2dd95SBruce Richardson struct timespec val; 4099a2dd95SBruce Richardson uint64_t v; 4199a2dd95SBruce Richardson 4299a2dd95SBruce Richardson while (clock_gettime(CLOCK_MONOTONIC_RAW, &val) != 0) 4399a2dd95SBruce Richardson /* no body */; 4499a2dd95SBruce Richardson 4599a2dd95SBruce Richardson v = (uint64_t) val.tv_sec * 1000000000LL; 4699a2dd95SBruce Richardson v += (uint64_t) val.tv_nsec; 4799a2dd95SBruce Richardson return v; 4899a2dd95SBruce Richardson } 4999a2dd95SBruce Richardson #define rte_rdtsc __rte_rdtsc_syscall 5099a2dd95SBruce Richardson 5199a2dd95SBruce Richardson #else 5299a2dd95SBruce Richardson 5399a2dd95SBruce Richardson /** 5499a2dd95SBruce Richardson * This function requires to configure the PMCCNTR and enable 5599a2dd95SBruce Richardson * userspace access to it: 5699a2dd95SBruce Richardson * 5799a2dd95SBruce Richardson * asm volatile("mcr p15, 0, %0, c9, c14, 0" : : "r"(1)); 5899a2dd95SBruce Richardson * asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(29)); 5999a2dd95SBruce Richardson * asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r"(0x8000000f)); 6099a2dd95SBruce Richardson * 6199a2dd95SBruce Richardson * which is possible only from the privileged mode (kernel space). 6299a2dd95SBruce Richardson */ 6399a2dd95SBruce Richardson static inline uint64_t 6499a2dd95SBruce Richardson __rte_rdtsc_pmccntr(void) 6599a2dd95SBruce Richardson { 6699a2dd95SBruce Richardson unsigned tsc; 6799a2dd95SBruce Richardson uint64_t final_tsc; 6899a2dd95SBruce Richardson 6999a2dd95SBruce Richardson /* Read PMCCNTR */ 7099a2dd95SBruce Richardson asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(tsc)); 7199a2dd95SBruce Richardson /* 1 tick = 64 clocks */ 7299a2dd95SBruce Richardson final_tsc = ((uint64_t)tsc) << 6; 7399a2dd95SBruce Richardson 7499a2dd95SBruce Richardson return (uint64_t)final_tsc; 7599a2dd95SBruce Richardson } 7699a2dd95SBruce Richardson #define rte_rdtsc __rte_rdtsc_pmccntr 7799a2dd95SBruce Richardson 7899a2dd95SBruce Richardson #endif /* RTE_ARM_EAL_RDTSC_USE_PMU */ 7999a2dd95SBruce Richardson 8099a2dd95SBruce Richardson static inline uint64_t 8199a2dd95SBruce Richardson rte_rdtsc_precise(void) 8299a2dd95SBruce Richardson { 8399a2dd95SBruce Richardson rte_mb(); 8499a2dd95SBruce Richardson return rte_rdtsc(); 8599a2dd95SBruce Richardson } 8699a2dd95SBruce Richardson 8799a2dd95SBruce Richardson static inline uint64_t 8899a2dd95SBruce Richardson rte_get_tsc_cycles(void) { return rte_rdtsc(); } 8999a2dd95SBruce Richardson 9099a2dd95SBruce Richardson #ifdef __cplusplus 9199a2dd95SBruce Richardson } 9299a2dd95SBruce Richardson #endif 9399a2dd95SBruce Richardson 9499a2dd95SBruce Richardson #endif /* _RTE_CYCLES_ARM32_H_ */ 95