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 25void arm_init_ccnt(void); 26 27static 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 35static 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 46static 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