1 /*
2  * Copyright (c) 2019 Stephanos Ioannidis <root@stephanos.io>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_BENCHMARK_CMSIS_DSP_COMMON_BENCHMARK_COMMON_H_
8 #define ZEPHYR_BENCHMARK_CMSIS_DSP_COMMON_BENCHMARK_COMMON_H_
9 
10 #include <zephyr/ztest.h>
11 #include <zephyr/kernel.h>
12 
13 #if defined(CONFIG_CPU_CORTEX_M_HAS_DWT)
14 /* Use cycle counting on the Cortex-M devices that support DWT */
15 
16 #include <cmsis_core.h>
17 
benchmark_begin(uint32_t * irq_key,uint32_t * timestamp)18 static ALWAYS_INLINE void benchmark_begin(uint32_t *irq_key, uint32_t *timestamp)
19 {
20 	ARG_UNUSED(timestamp);
21 
22 	/* Lock interrupts to prevent preemption */
23 	*irq_key = irq_lock();
24 
25 	/* Start DWT cycle counter */
26 	DWT->CYCCNT = 0;
27 	DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
28 }
29 
benchmark_end(uint32_t irq_key,uint32_t timestamp)30 static ALWAYS_INLINE uint32_t benchmark_end(uint32_t irq_key, uint32_t timestamp)
31 {
32 	/* Stop DWT cycle counter */
33 	DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk;
34 
35 	/* Unlock interrupts */
36 	irq_unlock(irq_key);
37 
38 	/* Return DWT cycle counter value */
39 	return DWT->CYCCNT;
40 }
41 
42 #define BENCHMARK_TYPE		"Processor Cycles"
43 
44 #else
45 /* Use system timer clock on other systems */
46 
benchmark_begin(uint32_t * irq_key,uint32_t * timestamp)47 static ALWAYS_INLINE void benchmark_begin(uint32_t *irq_key, uint32_t *timestamp)
48 {
49 	volatile uint32_t now;
50 
51 	/* Lock interrupts to prevent preemption */
52 	*irq_key = irq_lock();
53 
54 	/* Read timestamp for the beginning of benchmark */
55 	now = k_cycle_get_32();
56 
57 	/* Store timestamp */
58 	*timestamp = now;
59 }
60 
benchmark_end(uint32_t irq_key,uint32_t timestamp)61 static ALWAYS_INLINE uint32_t benchmark_end(uint32_t irq_key, uint32_t timestamp)
62 {
63 	volatile uint32_t now;
64 
65 	/* Read timestamp for the end of benchmark */
66 	now = k_cycle_get_32();
67 
68 	/* Unlock interrupts */
69 	irq_unlock(irq_key);
70 
71 	/* Return timespan between the beginning and the end of benchmark */
72 	return now - timestamp;
73 }
74 
75 #define BENCHMARK_TYPE		"System Timer Cycles"
76 
77 #endif
78 
79 #endif /* ZEPHYR_BENCHMARK_CMSIS_DSP_COMMON_BENCHMARK_COMMON_H_ */
80