1 /*
2  * Copyright 2014, General Dynamics C4 Systems
3  *
4  * SPDX-License-Identifier: GPL-2.0-only
5  */
6 
7 #pragma once
8 
9 #include <config.h>
10 #ifdef CONFIG_ENABLE_BENCHMARKS
11 
12 #include <armv/benchmark.h>
13 #include <mode/machine.h>
14 #include <model/statedata.h>
15 
16 /* these values are consistent across all arm PMUs */
17 #define PMCR_ENABLE 0
18 #define PMCR_ECNT_RESET 1
19 #define PMCR_CCNT_RESET 2
20 
21 #if defined(CONFIG_BENCHMARK_TRACK_UTILISATION) && defined(KERNEL_PMU_IRQ)
22 #define CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT 1
23 #endif
24 
25 void arm_init_ccnt(void);
26 
timestamp(void)27 static inline timestamp_t timestamp(void)
28 {
29     timestamp_t ccnt;
30     SYSTEM_READ_WORD(CCNT, ccnt);
31     return ccnt;
32 }
33 
34 #ifdef CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT
handleOverflowIRQ(void)35 static inline void handleOverflowIRQ(void)
36 {
37     if (likely(NODE_STATE(benchmark_log_utilisation_enabled))) {
38         NODE_STATE(ksCurThread)->benchmark.utilisation += UINT32_MAX - NODE_STATE(ksCurThread)->benchmark.schedule_start_time;
39         NODE_STATE(ksCurThread)->benchmark.schedule_start_time = 0;
40         NODE_STATE(ccnt_num_overflows)++;
41     }
42     armv_handleOverflowIRQ();
43 }
44 #endif /* CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT */
45 
benchmark_arch_utilisation_reset(void)46 static inline void benchmark_arch_utilisation_reset(void)
47 {
48 #ifdef CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT
49     NODE_STATE(ccnt_num_overflows) = 0;
50 #endif /* CONFIG_ARM_ENABLE_PMU_OVERFLOW_INTERRUPT */
51 }
52 #endif /* CONFIG_ENABLE_BENCHMARKS */
53 
54