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 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel