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