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

ligd 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 8d2fc5c9ee arch/x86_64:Add nanosecond delay interface to TSC
8d2fc5c9ee is described below

commit 8d2fc5c9ee1888306358528bbed2b9c61f3a2512
Author: liwenxiang1 <[email protected]>
AuthorDate: Thu Oct 10 09:59:50 2024 +0800

    arch/x86_64:Add nanosecond delay interface to TSC
    
    Signed-off-by: liwenxiang1 <[email protected]>
---
 arch/x86_64/src/common/x86_64_mdelay.c             |  4 ++
 arch/x86_64/src/common/x86_64_udelay.c             |  4 ++
 arch/x86_64/src/intel64/CMakeLists.txt             |  1 +
 arch/x86_64/src/intel64/Make.defs                  |  1 +
 .../intel64_tsc_ndelay.c}                          | 67 ++++++++++++----------
 5 files changed, 48 insertions(+), 29 deletions(-)

diff --git a/arch/x86_64/src/common/x86_64_mdelay.c 
b/arch/x86_64/src/common/x86_64_mdelay.c
index 29d60cf96c..5643b31199 100644
--- a/arch/x86_64/src/common/x86_64_mdelay.c
+++ b/arch/x86_64/src/common/x86_64_mdelay.c
@@ -63,6 +63,9 @@
 
 void up_mdelay(unsigned int milliseconds)
 {
+#ifdef CONFIG_ARCH_INTEL64_HAVE_TSC
+  up_ndelay(milliseconds * NSEC_PER_MSEC);
+#else
   volatile int i;
   volatile int j;
 
@@ -72,4 +75,5 @@ void up_mdelay(unsigned int milliseconds)
         {
         }
     }
+#endif
 }
diff --git a/arch/x86_64/src/common/x86_64_udelay.c 
b/arch/x86_64/src/common/x86_64_udelay.c
index f4e0c62ec2..c3a03fc30e 100644
--- a/arch/x86_64/src/common/x86_64_udelay.c
+++ b/arch/x86_64/src/common/x86_64_udelay.c
@@ -56,6 +56,9 @@
 
 void up_udelay(useconds_t microseconds)
 {
+#ifdef CONFIG_ARCH_INTEL64_HAVE_TSC
+  up_ndelay(microseconds * NSEC_PER_USEC);
+#else
   volatile int i;
 
   /* We'll do this a little at a time because we expect that the
@@ -99,4 +102,5 @@ void up_udelay(useconds_t microseconds)
 
       microseconds--;
     }
+#endif
 }
diff --git a/arch/x86_64/src/intel64/CMakeLists.txt 
b/arch/x86_64/src/intel64/CMakeLists.txt
index c575aa92d8..2e6dadad60 100644
--- a/arch/x86_64/src/intel64/CMakeLists.txt
+++ b/arch/x86_64/src/intel64/CMakeLists.txt
@@ -82,6 +82,7 @@ if(CONFIG_ARCH_INTEL64_HAVE_TSC)
   else()
     list(APPEND SRCS intel64_tsc_timerisr.c)
   endif()
+  list(APPEND SRCS intel64_tsc_ndelay.c)
 endif()
 
 if(CONFIG_INTEL64_HPET)
diff --git a/arch/x86_64/src/intel64/Make.defs 
b/arch/x86_64/src/intel64/Make.defs
index 52cf364ea3..c17c07a001 100644
--- a/arch/x86_64/src/intel64/Make.defs
+++ b/arch/x86_64/src/intel64/Make.defs
@@ -72,6 +72,7 @@ CHIP_CSRCS += intel64_tsc_tickless.c
 else
 CHIP_CSRCS += intel64_tsc_timerisr.c
 endif
+CHIP_CSRCS += intel64_tsc_ndelay.c
 endif
 
 ifeq ($(CONFIG_INTEL64_HPET),y)
diff --git a/arch/x86_64/src/common/x86_64_mdelay.c 
b/arch/x86_64/src/intel64/intel64_tsc_ndelay.c
similarity index 56%
copy from arch/x86_64/src/common/x86_64_mdelay.c
copy to arch/x86_64/src/intel64/intel64_tsc_ndelay.c
index 29d60cf96c..00a8c6dac4 100644
--- a/arch/x86_64/src/common/x86_64_mdelay.c
+++ b/arch/x86_64/src/intel64/intel64_tsc_ndelay.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/x86_64/src/common/x86_64_mdelay.c
+ * arch/x86_64/src/intel64/intel64_tsc_ndelay.c
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -25,51 +25,60 @@
 #include <nuttx/config.h>
 #include <nuttx/arch.h>
 
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
+extern unsigned long g_x86_64_timer_freq;
 
-/****************************************************************************
- * Private Types
- ****************************************************************************/
+/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
 
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
+static inline void rep_nop(void)
+{
+  __asm__ __volatile__("rep;nop": : :"memory");
+}
 
-/****************************************************************************
- * Private Data
- ****************************************************************************/
+/* TSC based delay: */
 
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
+static inline void delay_tsc(uint64_t cycles)
+{
+  uint64_t bclock;
+  irqstate_t irq;
+  uint64_t now;
+
+  irq = up_irq_save();
+  bclock = rdtscp();
+
+  for (; ; )
+    {
+      now = rdtscp();
+      if (now - bclock >= cycles)
+        {
+          break;
+        }
+
+      rep_nop();
+    }
+
+  up_irq_restore(irq);
+}
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_mdelay
+ * Name: up_nsdelay
  *
  * Description:
- *   Delay inline for the requested number of milliseconds.
+ *   Delay inline for the requested number of nanoseconds.
  *   *** NOT multi-tasking friendly ***
  *
- * ASSUMPTIONS:
- *   The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated
  *
  ****************************************************************************/
 
-void up_mdelay(unsigned int milliseconds)
+void up_ndelay(unsigned long nanoseconds)
 {
-  volatile int i;
-  volatile int j;
+  uint64_t cycles;
 
-  for (i = 0; i < milliseconds; i++)
-    {
-      for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++)
-        {
-        }
-    }
+  cycles = (nanoseconds * g_x86_64_timer_freq + NSEC_PER_SEC - 1)
+           / NSEC_PER_SEC;
+
+  delay_tsc(cycles);
 }

Reply via email to