diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index df82c7b3bc..fbd2a7878f 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -668,6 +668,7 @@ config LITEX_CORE_VEXRISCV_SMP select ARCH_NEED_ADDRENV_MAPPING select ARCH_HAVE_S_MODE select ARCH_HAVE_ELF_EXECUTABLE + select ARCH_HAVE_PERF_EVENTS endchoice # LITEX Core Selection diff --git a/arch/risc-v/src/common/riscv_perf_cycle.c b/arch/risc-v/src/common/riscv_perf_cycle.c new file mode 100644 index 0000000000..13e233ad9b --- /dev/null +++ b/arch/risc-v/src/common/riscv_perf_cycle.c @@ -0,0 +1,84 @@ +/**************************************************************************** + * arch/risc-v/src/common/riscv_perf_cycle.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this args 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 +#include + +#include "riscv_internal.h" + +#ifdef CONFIG_ARCH_PERF_EVENTS + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static unsigned long g_cycle_frequency = ULONG_MAX; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_perf_init + ****************************************************************************/ + +void up_perf_init(void *arg) +{ + g_cycle_frequency = (unsigned long)(uintptr_t)arg; +} + +/**************************************************************************** + * Name: up_perf_gettime + ****************************************************************************/ + +unsigned long up_perf_gettime(void) +{ + return READ_CSR(CSR_CYCLE); +} + +/**************************************************************************** + * Name: up_perf_getfreq + ****************************************************************************/ + +unsigned long up_perf_getfreq(void) +{ + return g_cycle_frequency; +} + +/**************************************************************************** + * Name: up_perf_convert + ****************************************************************************/ + +void up_perf_convert(unsigned long elapsed, struct timespec *ts) +{ + DEBUGASSERT(g_cycle_frequency && (g_cycle_frequency != ULONG_MAX)); + + ts->tv_sec = elapsed / g_cycle_frequency; + elapsed -= ts->tv_sec * g_cycle_frequency; + ts->tv_nsec = elapsed * (NSEC_PER_SEC / g_cycle_frequency); +} +#endif diff --git a/arch/risc-v/src/common/riscv_perf_time.c b/arch/risc-v/src/common/riscv_perf_time.c new file mode 100644 index 0000000000..da09723167 --- /dev/null +++ b/arch/risc-v/src/common/riscv_perf_time.c @@ -0,0 +1,84 @@ +/**************************************************************************** + * arch/risc-v/src/common/riscv_perf_time.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this args 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 +#include + +#include "riscv_internal.h" + +#ifdef CONFIG_ARCH_PERF_EVENTS + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static unsigned long g_clock_frequency = ULONG_MAX; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_perf_init + ****************************************************************************/ + +void up_perf_init(void *arg) +{ + g_clock_frequency = (unsigned long)(uintptr_t)arg; +} + +/**************************************************************************** + * Name: up_perf_gettime + ****************************************************************************/ + +unsigned long up_perf_gettime(void) +{ + return READ_CSR(CSR_TIME); +} + +/**************************************************************************** + * Name: up_perf_getfreq + ****************************************************************************/ + +unsigned long up_perf_getfreq(void) +{ + return g_clock_frequency; +} + +/**************************************************************************** + * Name: up_perf_convert + ****************************************************************************/ + +void up_perf_convert(unsigned long elapsed, struct timespec *ts) +{ + DEBUGASSERT(g_clock_frequency && (g_clock_frequency != ULONG_MAX)); + + ts->tv_sec = elapsed / g_clock_frequency; + elapsed -= ts->tv_sec * g_clock_frequency; + ts->tv_nsec = elapsed * (NSEC_PER_SEC / g_clock_frequency); +} +#endif diff --git a/arch/risc-v/src/litex/Make.defs b/arch/risc-v/src/litex/Make.defs index 653bba416f..104ce3db8b 100644 --- a/arch/risc-v/src/litex/Make.defs +++ b/arch/risc-v/src/litex/Make.defs @@ -40,6 +40,7 @@ CHIP_ASRCS += litex_cache.S ifeq ($(CONFIG_SCHED_TICKLESS),y) ifeq ($(CONFIG_SCHED_TICKLESS_ALARM),y) CHIP_CSRCS += litex_arch_alarm.c +CHIP_CSRCS += riscv_perf_time.c else CHIP_CSRCS += litex_tickless.c endif diff --git a/arch/risc-v/src/litex/litex_arch_alarm.c b/arch/risc-v/src/litex/litex_arch_alarm.c index e3621ae9b4..50f81d14ef 100644 --- a/arch/risc-v/src/litex/litex_arch_alarm.c +++ b/arch/risc-v/src/litex/litex_arch_alarm.c @@ -52,5 +52,9 @@ void up_timer_initialize(void) DEBUGASSERT(lower); +#ifdef CONFIG_ARCH_HAVE_PERF_EVENTS + up_perf_init((void *)CONFIG_LITEX_SYS_CORE_FREQ_HZ); +#endif + up_alarm_set_lowerhalf(lower); } diff --git a/boards/risc-v/litex/arty_a7/configs/knsh-tickless/defconfig b/boards/risc-v/litex/arty_a7/configs/knsh-tickless/defconfig index bcde8eceed..6240152145 100644 --- a/boards/risc-v/litex/arty_a7/configs/knsh-tickless/defconfig +++ b/boards/risc-v/litex/arty_a7/configs/knsh-tickless/defconfig @@ -64,12 +64,14 @@ CONFIG_NSH_FILE_APPS=y CONFIG_NSH_READLINE=y CONFIG_ONESHOT=y CONFIG_PATH_INITIAL="/system/bin" +CONFIG_PERF_OVERFLOW_CORRECTION=y CONFIG_RAM_SIZE=4194304 CONFIG_RAM_START=0x40400000 CONFIG_RAW_BINARY=y CONFIG_READLINE_CMD_HISTORY=y CONFIG_RR_INTERVAL=200 CONFIG_SCHED_HAVE_PARENT=y +CONFIG_SCHED_IRQMONITOR=y CONFIG_SCHED_LPWORK=y CONFIG_SCHED_TICKLESS=y CONFIG_SCHED_WAITPID=y @@ -81,6 +83,7 @@ CONFIG_SYSLOG_TIMESTAMP=y CONFIG_SYSTEM_CLE=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_NSH_PROGNAME="init" +CONFIG_SYSTEM_TIME64=y CONFIG_TESTING_GETPRIME=y CONFIG_UART0_RXBUFSIZE=128 CONFIG_UART0_SERIAL_CONSOLE=y