diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2023-09-15 16:20:47 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2023-09-18 10:53:24 +0200 |
commit | 89ec4f4b921f7b102c8d0a5d9a46039106f8811b (patch) | |
tree | 917ae96652b140d4d76cfc8981bd211d32c85a2a | |
parent | 70a277ff49a79ea4f47f293f4a1f87a389c38741 (diff) |
bsps/leon3: Use DSU time tag for GR712RC
Update #4954.
-rw-r--r-- | bsps/sparc/leon3/include/bsp/leon3.h | 2 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/cpucounter.c | 61 | ||||
-rw-r--r-- | spec/build/bsps/sparc/leon3/grp.yml | 2 | ||||
-rw-r--r-- | spec/build/bsps/sparc/leon3/optdsubase.yml | 24 |
4 files changed, 84 insertions, 5 deletions
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 01f5811c1b..d4b229a3bc 100644 --- a/bsps/sparc/leon3/start/cpucounter.c +++ b/bsps/sparc/leon3/start/cpucounter.c @@ -65,7 +65,56 @@ 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) + +/* + * 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_get_timecount = leon3_timecounter_get_dsu_time_tag; + tc->base.tc_frequency = + leon3_processor_local_bus_frequency() << LEON3_DSU_TIME_TAG_ZERO_BITS; +} + +#else /* !LEON3_HAS_ASR_22_23_UP_COUNTER && !LEON3_DSU_BASE */ /* * This is a workaround for: @@ -144,7 +193,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 */ static uint32_t leon3_timecounter_get_dummy(struct timecounter *base) { @@ -178,7 +227,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 */ /* Try to find the best CPU counter available */ @@ -221,7 +274,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 @@ -39,6 +39,8 @@ links: - role: build-dependency uid: optasrupcntprobe - role: build-dependency + uid: optdsubase +- role: build-dependency uid: optgptimerbase - role: build-dependency uid: optirqampbase 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 |