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);
}