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