diff --git a/arch/arm/src/armv7-a/arm_perf.c b/arch/arm/src/armv7-a/arm_perf.c index 9768bf7d898..2f50fb87c38 100644 --- a/arch/arm/src/armv7-a/arm_perf.c +++ b/arch/arm/src/armv7-a/arm_perf.c @@ -26,6 +26,7 @@ #include #include "arm_internal.h" +#include "arm_timer.h" #include "sctlr.h" #ifdef CONFIG_ARCH_PERF_EVENTS @@ -64,6 +65,13 @@ void up_perf_init(void *arg) { g_cpu_freq = (unsigned long)(uintptr_t)arg; +#ifdef CONFIG_ARMV7A_HAVE_PTM + if (g_cpu_freq == ULONG_MAX || g_cpu_freq == 0) + { + g_cpu_freq = arm_timer_get_freq(); + } +#endif + cp15_pmu_uer(PMUER_UME); cp15_pmu_pmcr(PMCR_E); cp15_pmu_cesr(PMCESR_CCES); diff --git a/arch/arm/src/armv7-a/arm_timer.c b/arch/arm/src/armv7-a/arm_timer.c index 5dce5717444..2efc1054917 100644 --- a/arch/arm/src/armv7-a/arm_timer.c +++ b/arch/arm/src/armv7-a/arm_timer.c @@ -87,12 +87,6 @@ static const struct oneshot_operations_s g_arm_timer_ops = * Private Functions ****************************************************************************/ -static inline uint32_t arm_timer_get_freq(void) -{ - ARM_ISB(); - return CP15_GET(CNTFRQ); -} - static inline void arm_timer_set_freq(uint32_t freq) { CP15_SET(CNTFRQ, freq); @@ -263,6 +257,12 @@ static int arm_timer_interrupt(int irq, void *context, void *arg) * Public Functions ****************************************************************************/ +uint32_t arm_timer_get_freq(void) +{ + ARM_ISB(); + return CP15_GET(CNTFRQ); +} + struct oneshot_lowerhalf_s *arm_timer_initialize(unsigned int freq) { struct arm_timer_lowerhalf_s *lower; diff --git a/arch/arm/src/armv7-a/arm_timer.h b/arch/arm/src/armv7-a/arm_timer.h index c1b8336bd01..52ee69fac64 100644 --- a/arch/arm/src/armv7-a/arm_timer.h +++ b/arch/arm/src/armv7-a/arm_timer.h @@ -59,8 +59,10 @@ extern "C" #ifdef CONFIG_ARMV7A_HAVE_PTM struct oneshot_lowerhalf_s *arm_timer_initialize(unsigned int freq); +uint32_t arm_timer_get_freq(void); #else # define arm_timer_initialize(freq) NULL +# define arm_timer_get_freq() 0 #endif #undef EXTERN diff --git a/arch/arm/src/armv7-r/arm_perf.c b/arch/arm/src/armv7-r/arm_perf.c index c3d1310862f..de25750f64e 100644 --- a/arch/arm/src/armv7-r/arm_perf.c +++ b/arch/arm/src/armv7-r/arm_perf.c @@ -26,6 +26,7 @@ #include #include "arm_internal.h" +#include "arm_timer.h" #include "sctlr.h" #ifdef CONFIG_ARCH_PERF_EVENTS @@ -64,6 +65,13 @@ void up_perf_init(void *arg) { g_cpu_freq = (unsigned long)(uintptr_t)arg; +#ifdef CONFIG_ARMV7R_HAVE_PTM + if (g_cpu_freq == ULONG_MAX || g_cpu_freq == 0) + { + g_cpu_freq = arm_timer_get_freq(); + } +#endif + cp15_pmu_uer(PMUER_UME); cp15_pmu_pmcr(PMCR_E); cp15_pmu_cesr(PMCESR_CCES); diff --git a/arch/arm/src/armv7-r/arm_timer.c b/arch/arm/src/armv7-r/arm_timer.c index 08f9d24a6c4..af7a5a7496c 100644 --- a/arch/arm/src/armv7-r/arm_timer.c +++ b/arch/arm/src/armv7-r/arm_timer.c @@ -87,12 +87,6 @@ static const struct oneshot_operations_s g_arm_timer_ops = * Private Functions ****************************************************************************/ -static inline uint32_t arm_timer_get_freq(void) -{ - ARM_ISB(); - return CP15_GET(CNTFRQ); -} - static inline void arm_timer_set_freq(uint32_t freq) { CP15_SET(CNTFRQ, freq); @@ -265,6 +259,12 @@ static int arm_timer_interrupt(int irq, void *context, void *arg) * Public Functions ****************************************************************************/ +uint32_t arm_timer_get_freq(void) +{ + ARM_ISB(); + return CP15_GET(CNTFRQ); +} + struct oneshot_lowerhalf_s *arm_timer_initialize(unsigned int freq) { struct arm_timer_lowerhalf_s *lower; diff --git a/arch/arm/src/armv7-r/arm_timer.h b/arch/arm/src/armv7-r/arm_timer.h index cd9549ecf79..681e5060daa 100644 --- a/arch/arm/src/armv7-r/arm_timer.h +++ b/arch/arm/src/armv7-r/arm_timer.h @@ -59,8 +59,10 @@ extern "C" #ifdef CONFIG_ARMV7R_HAVE_PTM struct oneshot_lowerhalf_s *arm_timer_initialize(unsigned int freq); +uint32_t arm_timer_get_freq(void); #else # define arm_timer_initialize(freq) NULL +# define arm_timer_get_freq() 0 #endif #undef EXTERN diff --git a/arch/arm/src/goldfish/goldfish_boot.c b/arch/arm/src/goldfish/goldfish_boot.c index c0b6bac29c8..b9bf51f473b 100644 --- a/arch/arm/src/goldfish/goldfish_boot.c +++ b/arch/arm/src/goldfish/goldfish_boot.c @@ -47,6 +47,10 @@ void arm_boot(void) { + /* Perf init */ + + up_perf_init(0); + /* Set the page table for section */ goldfish_setupmappings(); diff --git a/arch/arm/src/qemu/qemu_boot.c b/arch/arm/src/qemu/qemu_boot.c index 479bbc5883d..29eafa84e4f 100644 --- a/arch/arm/src/qemu/qemu_boot.c +++ b/arch/arm/src/qemu/qemu_boot.c @@ -47,6 +47,10 @@ void arm_boot(void) { + /* Perf init */ + + up_perf_init(0); + /* Set the page table for section */ qemu_setupmappings();