[PATCH v2 9/9] bsps/leon3: Use DSU time tag for GR712RC
Sebastian Huber
sebastian.huber at embedded-brains.de
Thu Sep 21 15:19:34 UTC 2023
Update #4954.
---
bsps/sparc/leon3/start/cpucounter.c | 62 ++++++++++++++++++++--
spec/build/bsps/sparc/leon3/grp.yml | 2 +
spec/build/bsps/sparc/leon3/optdsubase.yml | 24 +++++++++
3 files changed, 84 insertions(+), 4 deletions(-)
create mode 100644 spec/build/bsps/sparc/leon3/optdsubase.yml
diff --git a/bsps/sparc/leon3/start/cpucounter.c b/bsps/sparc/leon3/start/cpucounter.c
index db4f566021..35db839cd4 100644
--- a/bsps/sparc/leon3/start/cpucounter.c
+++ b/bsps/sparc/leon3/start/cpucounter.c
@@ -77,7 +77,57 @@ RTEMS_ALIAS(_CPU_Counter_read) uint32_t _SPARC_Counter_read_ISR_disabled(void);
#define LEON3_GET_TIMECOUNT_INIT leon3_timecounter_get_processor_up_counter
-#else /* !LEON3_HAS_ASR_22_23_UP_COUNTER */
+#elif defined(LEON3_DSU_BASE)
+
+/*
+ * In general, using the Debug Support Unit (DSU) is not recommended. Before
+ * you use it, check that it is available in flight models and that the time
+ * tag register is implemented in radiation hardened flip-flops. For the
+ * GR712RC, this is the case.
+ */
+
+/* This value is specific to the GR712RC */
+#define LEON3_DSU_TIME_TAG_ZERO_BITS 2
+
+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 << LEON3_DSU_TIME_TAG_ZERO_BITS;
+}
+
+static uint32_t leon3_timecounter_get_dsu_time_tag(
+ struct timecounter *tc
+)
+{
+ (void) 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);
+
+static void leon3_counter_use_dsu_time_tag(leon3_timecounter *tc)
+{
+ tc->base.tc_frequency =
+ leon3_processor_local_bus_frequency() << LEON3_DSU_TIME_TAG_ZERO_BITS;
+}
+
+#define LEON3_GET_TIMECOUNT_INIT leon3_timecounter_get_dsu_time_tag
+
+#else /* !LEON3_HAS_ASR_22_23_UP_COUNTER && !LEON3_DSU_BASE */
/*
* This is a workaround for:
@@ -169,7 +219,7 @@ static void leon3_counter_use_irqamp_timestamp(
}
#endif /* LEON3_IRQAMP_PROBE_TIMESTAMP */
-#endif /* LEON3_HAS_ASR_22_23_UP_COUNTER */
+#endif /* LEON3_HAS_ASR_22_23_UP_COUNTER || LEON3_DSU_BASE */
leon3_timecounter leon3_timecounter_instance = {
.base = {
@@ -192,7 +242,11 @@ static void leon3_counter_initialize(void)
leon3_up_counter_enable();
leon3_counter_use_asr_22_23_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 */
/* Try to find the best CPU counter available */
@@ -235,7 +289,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..5fd0b9bfb7
--- /dev/null
+++ b/spec/build/bsps/sparc/leon3/optdsubase.yml
@@ -0,0 +1,24 @@
+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 implementation.
+
+ In general, using the Debug Support Unit (DSU) is not recommended for the
+ clock driver and CPU counter implementation. Before you use it, check that
+ it is available in flight models and that the time tag register is
+ implemented in radiation hardened flip-flops. For the GR712RC, this is the
+ case.
+type: build
--
2.35.3
More information about the devel
mailing list