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