xref: /dpdk/lib/eal/arm/include/rte_cycles_32.h (revision 719834a6849e1daf4a70ff7742bbcc3ae7e25607)
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