[PATCH 6/6] bsps/leon3: Use DSU time tag for GR712RC

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Sep 15 14:40:13 UTC 2023


Update #4954.
---
 bsps/sparc/leon3/include/bsp/leon3.h       |  2 +-
 bsps/sparc/leon3/start/cpucounter.c        | 63 +++++++++++++++++++---
 spec/build/bsps/sparc/leon3/grp.yml        |  2 +
 spec/build/bsps/sparc/leon3/optdsubase.yml | 18 +++++++
 4 files changed, 78 insertions(+), 7 deletions(-)
 create mode 100644 spec/build/bsps/sparc/leon3/optdsubase.yml

diff --git a/bsps/sparc/leon3/include/bsp/leon3.h b/bsps/sparc/leon3/include/bsp/leon3.h
index 4ee5531941..449e40c406 100644
--- a/bsps/sparc/leon3/include/bsp/leon3.h
+++ b/bsps/sparc/leon3/include/bsp/leon3.h
@@ -326,7 +326,7 @@ typedef struct {
    */
   uint32_t software_counter;
 
-#if !defined(LEON3_HAS_ASR_22_23_UP_COUNTER)
+#if !defined(LEON3_HAS_ASR_22_23_UP_COUNTER) && !defined(LEON3_DSU_BASE)
   /**
    * @brief This member may reference a hardware counter register.
    */
diff --git a/bsps/sparc/leon3/start/cpucounter.c b/bsps/sparc/leon3/start/cpucounter.c
index dbb1797a89..ed8ee5f616 100644
--- a/bsps/sparc/leon3/start/cpucounter.c
+++ b/bsps/sparc/leon3/start/cpucounter.c
@@ -61,7 +61,39 @@ CPU_Counter_ticks _CPU_Counter_read(void)
 RTEMS_ALIAS( _CPU_Counter_read )
 uint32_t _SPARC_Counter_read_ISR_disabled( void );
 
-#else /* !LEON3_HAS_ASR_22_23_UP_COUNTER */
+#elif defined(LEON3_DSU_BASE)
+
+static uint32_t leon3_read_dsu_time_tag(void)
+{
+  uint32_t value;
+  volatile uint32_t *reg;
+
+  /* Use a load with a forced cache miss */
+  reg = (uint32_t *) (LEON3_DSU_BASE + 8);
+  __asm__ volatile (
+    "\tlda\t[%1]1, %0"
+    : "=&r"(value)
+    : "r"(reg)
+  );
+  return value << 2;
+}
+
+static uint32_t leon3_timecounter_get_dsu_time_tag(
+  struct timecounter *tc
+)
+{
+  return leon3_read_dsu_time_tag();
+}
+
+CPU_Counter_ticks _CPU_Counter_read(void)
+{
+  return leon3_read_dsu_time_tag();
+}
+
+RTEMS_ALIAS(_CPU_Counter_read)
+uint32_t _SPARC_Counter_read_ISR_disabled(void);
+
+#else /* !LEON3_HAS_ASR_22_23_UP_COUNTER && !LEON3_DSU_BASE */
 
 /*
  * This is a workaround for:
@@ -103,7 +135,7 @@ static uint32_t leon3_timecounter_get_counter_up(struct timecounter *base)
 }
 #endif
 
-#endif /* LEON3_HAS_ASR_22_23_UP_COUNTER */
+#endif /* LEON3_HAS_ASR_22_23_UP_COUNTER || LEON3_DSU_BASE */
 
 static uint32_t leon3_timecounter_get_dummy(struct timecounter *base)
 {
@@ -139,7 +171,22 @@ static void leon3_counter_use_up_counter(leon3_timecounter *tc)
 }
 #endif
 
-#if defined(LEON3_IRQAMP_PROBE_TIMESTAMP)
+#if defined(LEON3_DSU_BASE)
+static void leon3_counter_use_dsu_time_tag(leon3_timecounter *tc)
+{
+  uint32_t frequency;
+
+  tc->base.tc_get_timecount = leon3_timecounter_get_dsu_time_tag;
+#if defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER)
+  frequency = leon3_processor_local_bus_frequency();
+#else
+  frequency = ambapp_freq_get(ambapp_plb(), LEON3_IrqCtrl_Adev);
+#endif
+  tc->base.tc_frequency = frequency << 2;
+}
+#endif
+
+#if defined(LEON3_IRQAMP_PROBE_TIMESTAMP) && !defined(LEON3_DSU_BASE)
 static void leon3_counter_use_irqamp_timestamp(
   leon3_timecounter *tc,
   irqamp_timestamp *irqmp_ts
@@ -158,7 +205,7 @@ static void leon3_counter_use_irqamp_timestamp(
 }
 #endif
 
-#if !defined(LEON3_HAS_ASR_22_23_UP_COUNTER)
+#if !defined(LEON3_HAS_ASR_22_23_UP_COUNTER) && !defined(LEON3_DSU_BASE)
 static void leon3_counter_use_gptimer(
   leon3_timecounter *tc,
   gptimer *gpt
@@ -190,7 +237,11 @@ static void leon3_counter_initialize(void)
   leon3_up_counter_enable();
   leon3_counter_use_up_counter(&leon3_timecounter_instance);
 
-#else /* !LEON3_HAS_ASR_22_23_UP_COUNTER */
+#elif defined(LEON3_DSU_BASE)
+
+  leon3_counter_use_dsu_time_tag(&leon3_timecounter_instance);
+
+#else /* !LEON3_HAS_ASR_22_23_UP_COUNTER && !LEON3_DSU_BASE */
 
 #if defined(LEON3_IRQAMP_PROBE_TIMESTAMP)
   irqamp_timestamp *irqmp_ts;
@@ -231,7 +282,7 @@ static void leon3_counter_initialize(void)
   }
 #endif
 
-#endif /* LEON3_HAS_ASR_22_23_UP_COUNTER */
+#endif /* LEON3_HAS_ASR_22_23_UP_COUNTER || LEON3_DSU_BASE */
 }
 
 RTEMS_SYSINIT_ITEM(
diff --git a/spec/build/bsps/sparc/leon3/grp.yml b/spec/build/bsps/sparc/leon3/grp.yml
index d708a65735..a995ccc60a 100644
--- a/spec/build/bsps/sparc/leon3/grp.yml
+++ b/spec/build/bsps/sparc/leon3/grp.yml
@@ -38,6 +38,8 @@ links:
   uid: optasrupcnt
 - role: build-dependency
   uid: optasrupcntprobe
+- role: build-dependency
+  uid: optdsubase
 - role: build-dependency
   uid: optgptimerbase
 - role: build-dependency
diff --git a/spec/build/bsps/sparc/leon3/optdsubase.yml b/spec/build/bsps/sparc/leon3/optdsubase.yml
new file mode 100644
index 0000000000..f528f0ca07
--- /dev/null
+++ b/spec/build/bsps/sparc/leon3/optdsubase.yml
@@ -0,0 +1,18 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2023 embedded brains GmbH & Co. KG
+actions:
+- get-integer: null
+- format-and-define: null
+build-type: option
+default:
+- enabled-by: sparc/gr712rc
+  value: 0x90000000
+enabled-by: true
+format: '{:#010x}'
+links: []
+name: LEON3_DSU_BASE
+description: |
+  This option defines the base address of the DSU register block used by
+  the clock driver and CPU counter.
+type: build
-- 
2.35.3



More information about the devel mailing list