1 #include "Timing.h"
2
3 #ifdef CORTEXM
4
5 #define SYSTICK_INITIAL_VALUE 0x0FFFFFF
6 static uint32_t startCycles=0;
7 #endif
8
9 #if defined(CORTEXA) || defined(CORTEXR)
10 #if !defined(__GNUC_PYTHON__)
11 #include "cmsis_cp15.h"
12 #else
13 #if defined(__aarch64__)
14 #include "timing_aarch64.h"
15 #define AARCH64_TIMING
16 #endif
17 #endif
18
19 #if defined(CORTEXA) && defined(AARCH64_TIMING)
20 unsigned long long startCycles;
21 #else
22 unsigned int startCycles;
23 #endif
24
25 #define DO_RESET 1
26 #define ENABLE_DIVIDER 0
27 #endif
28
29 #if defined(EXTBENCH) || defined(CACHEANALYSIS)
30 unsigned long sectionCounter=0;
31 #endif
32
initCycleMeasurement()33 void initCycleMeasurement()
34 {
35 #if !defined(NOTIMING)
36 #ifdef CORTEXM
37 SysTick->LOAD = SYSTICK_INITIAL_VALUE;
38 SysTick->VAL = 0;
39 SysTick->CTRL = 0;
40 #endif
41
42 #if defined(CORTEXA) || defined(CORTEXR)
43 #if !defined(AARCH64_TIMING)
44
45 // in general enable all counters (including cycle counter)
46 int32_t value = 1;
47
48
49 // peform reset:
50 if (DO_RESET)
51 {
52 value |= 2; // reset all counters to zero.
53 value |= 4; // reset cycle counter to zero.
54 }
55
56 if (ENABLE_DIVIDER)
57 value |= 8; // enable "by 64" divider for CCNT.
58 //value |= 16;
59
60 // program the performance-counter control-register:
61 __set_CP(15, 0, value, 9, 12, 0);
62
63 // enable all counters:
64 __set_CP(15, 0, 0x8000000f, 9, 12, 1);
65
66 // clear overflows:
67 __set_CP(15, 0, 0x8000000f, 9, 12, 3);
68
69 #if defined(ARMCR52)
70 __get_CP(15, 0, value, 14, 15, 7);
71 value = value | (0x8000 << 12);
72 __set_CP(15, 0, value, 14, 15, 7);
73 #endif
74 #else
75 enable_timing();
76 #endif
77 #endif
78 #endif
79 }
80
cycleMeasurementStart()81 void cycleMeasurementStart()
82 {
83 #if !defined(NOTIMING)
84 #ifndef EXTBENCH
85 #ifdef CORTEXM
86
87 SysTick->CTRL = 0;
88 SysTick->LOAD = SYSTICK_INITIAL_VALUE;
89 SysTick->VAL = 0;
90
91 SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_CLKSOURCE_Msk;
92
93 startCycles = SysTick->VAL;
94
95
96
97 #endif
98
99 #if (defined(CORTEXA) || defined(CORTEXR))
100 #if !defined(AARCH64_TIMING)
101 unsigned int value;
102 // Read CCNT Register
103 __get_CP(15, 0, value, 9, 13, 0);
104 startCycles = value;
105 #else
106 startCycles = readCCNT();
107 #endif
108 #endif
109 #endif
110 #endif
111 }
112
cycleMeasurementStop()113 void cycleMeasurementStop()
114 {
115 #if !defined(NOTIMING)
116 #ifndef EXTBENCH
117 #ifdef CORTEXM
118 SysTick->CTRL = 0;
119 SysTick->LOAD = SYSTICK_INITIAL_VALUE;
120 #endif
121 #endif
122 #endif
123 }
124
getCycles()125 Testing::cycles_t getCycles()
126 {
127 #if defined(NOTIMING)
128 return(0);
129 #else
130 #ifdef CORTEXM
131 #if defined(NORMALFVP)
132 return(0);
133 #else
134 uint32_t v = SysTick->VAL;
135 int32_t result;
136
137 result = (int32_t)startCycles - (int32_t)v;
138
139 if (result < 0)
140 {
141 result += SYSTICK_INITIAL_VALUE;
142 }
143
144
145
146 /* SysTick tested and tuned on IPSS.
147 On other FVP, the value is forced to 0
148 because measurement is wrong.
149 */
150
151 return(result);
152 #endif
153 #endif
154
155 #if (defined(CORTEXA) || defined(CORTEXR))
156 #if !defined(AARCH64_TIMING)
157 unsigned int value;
158 // Read CCNT Register
159 __get_CP(15, 0, value, 9, 13, 0);
160 return(value - startCycles);
161 #else
162 unsigned long long value;
163 value = readCCNT();
164 return((Testing::cycles_t)(value - startCycles));
165 #endif
166 #endif
167 #endif
168
169 }
170