diff --git a/arch/arm/src/armv7-a/Make.defs b/arch/arm/src/armv7-a/Make.defs index e0809db2c11..54f85e19dec 100644 --- a/arch/arm/src/armv7-a/Make.defs +++ b/arch/arm/src/armv7-a/Make.defs @@ -49,6 +49,7 @@ CMN_CSRCS += arm_doirq.c arm_gicv2.c arm_gicv2_dump.c CMN_CSRCS += arm_initialstate.c arm_mmu.c arm_prefetchabort.c CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c CMN_CSRCS += arm_syscall.c arm_tcbinfo.c arm_undefinedinsn.c +CMN_CSRCS += arm_perf.c ifeq ($(CONFIG_ARMV7A_L2CC_PL310),y) CMN_CSRCS += arm_l2cc_pl310.c diff --git a/arch/arm/src/armv7-a/arm_perf.c b/arch/arm/src/armv7-a/arm_perf.c new file mode 100644 index 00000000000..83af327986a --- /dev/null +++ b/arch/arm/src/armv7-a/arm_perf.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_perf.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "arm_internal.h" +#include "sctlr.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint32_t g_cpu_freq; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_perf_* + * + * Description: + * The first interface simply provides the current time value in unknown + * units. NOTE: This function may be called early before the timer has + * been initialized. In that event, the function should just return a + * start time of zero. + * + * Nothing is assumed about the units of this time value. The following + * are assumed, however: (1) The time is an unsigned integer value, (2) + * the time is monotonically increasing, and (3) the elapsed time (also + * in unknown units) can be obtained by subtracting a start time from + * the current time. + * + * The second interface simple converts an elapsed time into well known + * units. + * + ****************************************************************************/ + +void up_perf_init(void *arg) +{ + g_cpu_freq = (uint32_t)(uintptr_t)arg; + + cp15_pmu_uer(PMUER_UME); + cp15_pmu_pmcr(PMCR_E); + cp15_pmu_cesr(PMCESR_CCES); +} + +uint32_t up_perf_getfreq(void) +{ + return g_cpu_freq; +} + +uint32_t up_perf_gettime(void) +{ + return cp15_pmu_rdccr(); +} + +void up_perf_convert(uint32_t elapsed, struct timespec *ts) +{ + uint32_t left; + + ts->tv_sec = elapsed / g_cpu_freq; + left = elapsed - ts->tv_sec * g_cpu_freq; + ts->tv_nsec = NSEC_PER_SEC * (uint64_t)left / g_cpu_freq; +} diff --git a/arch/arm/src/armv7-r/Make.defs b/arch/arm/src/armv7-r/Make.defs index 2989a9686ec..5c106ebea41 100644 --- a/arch/arm/src/armv7-r/Make.defs +++ b/arch/arm/src/armv7-r/Make.defs @@ -33,6 +33,7 @@ CMN_CSRCS += arm_cache.c arm_dataabort.c arm_doirq.c arm_gicv2.c CMN_CSRCS += arm_initialstate.c arm_prefetchabort.c CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c CMN_CSRCS += arm_syscall.c arm_tcbinfo.c arm_undefinedinsn.c +CMN_CSRCS += arm_perf.c # Common C source files diff --git a/arch/arm/src/armv7-r/arm_perf.c b/arch/arm/src/armv7-r/arm_perf.c new file mode 100644 index 00000000000..0f56dc369ed --- /dev/null +++ b/arch/arm/src/armv7-r/arm_perf.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/armv7-r/arm_perf.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "arm_internal.h" +#include "sctlr.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint32_t g_cpu_freq; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_perf_* + * + * Description: + * The first interface simply provides the current time value in unknown + * units. NOTE: This function may be called early before the timer has + * been initialized. In that event, the function should just return a + * start time of zero. + * + * Nothing is assumed about the units of this time value. The following + * are assumed, however: (1) The time is an unsigned integer value, (2) + * the time is monotonically increasing, and (3) the elapsed time (also + * in unknown units) can be obtained by subtracting a start time from + * the current time. + * + * The second interface simple converts an elapsed time into well known + * units. + * + ****************************************************************************/ + +void up_perf_init(void *arg) +{ + g_cpu_freq = (uint32_t)(uintptr_t)arg; + + cp15_pmu_uer(PMUER_UME); + cp15_pmu_pmcr(PMCR_E); + cp15_pmu_cesr(PMCESR_CCES); +} + +uint32_t up_perf_getfreq(void) +{ + return g_cpu_freq; +} + +uint32_t up_perf_gettime(void) +{ + return cp15_pmu_rdccr(); +} + +void up_perf_convert(uint32_t elapsed, struct timespec *ts) +{ + uint32_t left; + + ts->tv_sec = elapsed / g_cpu_freq; + left = elapsed - ts->tv_sec * g_cpu_freq; + ts->tv_nsec = NSEC_PER_SEC * (uint64_t)left / g_cpu_freq; +}