[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