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-10-20 11:20:14 +0200 |
commit | 958d517215025851fd728abdc1f246c9ad808dab (patch) | |
tree | 3b9978ee3b655537be1bec85751c9ec81cbd2b49 /bsps/sparc | |
parent | bsps/leon3: leon3_counter_use_irqamp_timestamp() (diff) | |
download | rtems-958d517215025851fd728abdc1f246c9ad808dab.tar.bz2 |
bsps/leon3: Use DSU time tag for GR712RC
Close #4954.
Diffstat (limited to 'bsps/sparc')
-rw-r--r-- | bsps/sparc/leon3/start/cpucounter.c | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/bsps/sparc/leon3/start/cpucounter.c b/bsps/sparc/leon3/start/cpucounter.c index 502c30de62..8ca1962de9 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_asr_22_23_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( |