This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 0ac580cb7a arch/risc-v/mpfs: Add optimized perf timer functions for 
mpfs
0ac580cb7a is described below

commit 0ac580cb7a06d142cb5304d7cd4e5e60cc355fe3
Author: Jukka Laitinen <jukka.laiti...@tii.ae>
AuthorDate: Wed Jun 4 15:06:11 2025 +0300

    arch/risc-v/mpfs: Add optimized perf timer functions for mpfs
    
    Add up_perf_ functions for MPFS, which don't rely on alarm/oneshot 
interface.
    
    Also add optimized up_udelay and up_ndelay functions, which use the MTIMER
    directly to measure time; making them accurate and more multithreading 
friendly.
    
    Signed-off-by: Jukka Laitinen <jukka.laiti...@tii.ae>
---
 arch/risc-v/Kconfig              |   2 +
 arch/risc-v/src/mpfs/Make.defs   |   1 +
 arch/risc-v/src/mpfs/mpfs_perf.c | 109 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 112 insertions(+)

diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig
index 0ee8c08354..ac7774fa7e 100644
--- a/arch/risc-v/Kconfig
+++ b/arch/risc-v/Kconfig
@@ -214,6 +214,8 @@ config ARCH_CHIP_MPFS
        select ARCH_HAVE_PWM_MULTICHAN
        select ARCH_HAVE_S_MODE
        select ARCH_RV_CPUID_MAP
+       select ARCH_HAVE_PERF_EVENTS
+       select ARCH_PERF_EVENTS
        select ONESHOT
        select ALARM_ARCH
        ---help---
diff --git a/arch/risc-v/src/mpfs/Make.defs b/arch/risc-v/src/mpfs/Make.defs
index 5e856643de..e2350451e9 100644
--- a/arch/risc-v/src/mpfs/Make.defs
+++ b/arch/risc-v/src/mpfs/Make.defs
@@ -35,6 +35,7 @@ CHIP_CSRCS += mpfs_lowputc.c mpfs_serial.c
 CHIP_CSRCS += mpfs_start.c mpfs_timerisr.c
 CHIP_CSRCS += mpfs_gpio.c mpfs_systemreset.c
 CHIP_CSRCS += mpfs_plic.c mpfs_dsn.c
+CHIP_CSRCS += mpfs_perf.c
 
 ifeq ($(CONFIG_MPFS_CLKINIT),y)
 CHIP_CSRCS += mpfs_clockconfig.c
diff --git a/arch/risc-v/src/mpfs/mpfs_perf.c b/arch/risc-v/src/mpfs/mpfs_perf.c
new file mode 100644
index 0000000000..2cdf7c29a6
--- /dev/null
+++ b/arch/risc-v/src/mpfs/mpfs_perf.c
@@ -0,0 +1,109 @@
+/****************************************************************************
+ * arch/risc-v/src/mpfs/mpfs_perf.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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 <nuttx/config.h>
+#include <nuttx/clock.h>
+#include <nuttx/arch.h>
+
+#include <stdint.h>
+#include <time.h>
+
+#include <arch/board/board.h>
+
+#include "riscv_internal.h"
+#include "hardware/mpfs_memorymap.h"
+#include "hardware/mpfs_clint.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_perf_init
+ ****************************************************************************/
+
+void up_perf_init(void *arg)
+{
+}
+
+/****************************************************************************
+ * Name: up_perf_gettime
+ ****************************************************************************/
+
+clock_t up_perf_gettime(void)
+{
+  return getreg64(MPFS_CLINT_MTIME);
+}
+
+/****************************************************************************
+ * Name: up_perf_getfreq
+ ****************************************************************************/
+
+unsigned long up_perf_getfreq(void)
+{
+  return MPFS_MSS_RTC_TOGGLE_CLK;
+}
+
+/****************************************************************************
+ * Name: up_perf_convert
+ ****************************************************************************/
+
+void up_perf_convert(clock_t elapsed, struct timespec *ts)
+{
+  ts->tv_sec  = elapsed / MPFS_MSS_RTC_TOGGLE_CLK;
+  elapsed    -= ts->tv_sec * MPFS_MSS_RTC_TOGGLE_CLK;
+  ts->tv_nsec = elapsed * NSEC_PER_SEC / MPFS_MSS_RTC_TOGGLE_CLK;
+}
+
+/****************************************************************************
+ * Name: up_udelay
+ *
+ * Description:
+ *   Delay for the requested number of microseconds.
+ *
+ ****************************************************************************/
+
+void up_udelay(useconds_t microseconds)
+{
+  clock_t start = up_perf_gettime();
+  clock_t end = microseconds * up_perf_getfreq() / USEC_PER_SEC + start + 1;
+  while (((sclock_t)(up_perf_gettime() - end)) < 0)
+    {
+    }
+}
+
+/****************************************************************************
+ * Name: up_ndelay
+ *
+ * Description:
+ *   Delay for the requested number of nanoseconds.
+ *
+ ****************************************************************************/
+
+void up_ndelay(unsigned long nanoseconds)
+{
+  up_udelay((nanoseconds + NSEC_PER_USEC - 1) / NSEC_PER_USEC);
+}

Reply via email to