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