Merge the timecounter and CPU counter support for the leon3 BSP family. Remove now unused functions from the CPU counter support of the erc32 and leon3 BSPs.
Update #4954. --- bsps/sparc/include/bsp/sparc-counter.h | 12 -- bsps/sparc/leon3/clock/ckinit.c | 2 +- bsps/sparc/leon3/include/bsp/leon3.h | 26 +++- bsps/sparc/leon3/start/cpucounter.c | 157 ++++++++++++++------ bsps/sparc/shared/start/sparc-counter-asm.S | 26 ---- spec/build/bsps/sparc/leon3/obj.yml | 2 - 6 files changed, 134 insertions(+), 91 deletions(-) diff --git a/bsps/sparc/include/bsp/sparc-counter.h b/bsps/sparc/include/bsp/sparc-counter.h index c71cddf304..bc4f2220e7 100644 --- a/bsps/sparc/include/bsp/sparc-counter.h +++ b/bsps/sparc/include/bsp/sparc-counter.h @@ -49,24 +49,12 @@ void _SPARC_Counter_at_tick_clock( void ); CPU_Counter_ticks _SPARC_Counter_read_default( void ); -CPU_Counter_ticks _SPARC_Counter_read_up( void ); - -CPU_Counter_ticks _SPARC_Counter_read_down( void ); - CPU_Counter_ticks _SPARC_Counter_read_clock_isr_disabled( void ); CPU_Counter_ticks _SPARC_Counter_read_clock( void ); -CPU_Counter_ticks _SPARC_Counter_read_asr23( void ); - -uint32_t _SPARC_Get_timecount_up( struct timecounter * ); - -uint32_t _SPARC_Get_timecount_down( struct timecounter * ); - uint32_t _SPARC_Get_timecount_clock( struct timecounter * ); -uint32_t _SPARC_Get_timecount_asr23( struct timecounter * ); - typedef CPU_Counter_ticks ( *SPARC_Counter_read )( void ); /* diff --git a/bsps/sparc/leon3/clock/ckinit.c b/bsps/sparc/leon3/clock/ckinit.c index c77fd23aff..d530f260a8 100644 --- a/bsps/sparc/leon3/clock/ckinit.c +++ b/bsps/sparc/leon3/clock/ckinit.c @@ -196,7 +196,7 @@ static void leon3_clock_initialize(void) } #endif - rtems_timecounter_install(&leon3_timecounter_instance); + rtems_timecounter_install(&leon3_timecounter_instance.base); } #define Clock_driver_support_initialize_hardware() \ diff --git a/bsps/sparc/leon3/include/bsp/leon3.h b/bsps/sparc/leon3/include/bsp/leon3.h index a5eecdded7..4ee5531941 100644 --- a/bsps/sparc/leon3/include/bsp/leon3.h +++ b/bsps/sparc/leon3/include/bsp/leon3.h @@ -9,7 +9,7 @@ */ /* - * Copyright (C) 2014, 2021 embedded brains GmbH & Co. KG + * Copyright (C) 2014, 2023 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -312,12 +312,34 @@ static inline uint32_t leon3_up_counter_frequency( void ) extern apbuart *leon3_debug_uart; #endif +/** + * @brief Represents the LEON3-specific timecounter. + */ +typedef struct { + /** + * @brief This member contains the base timecounter. + */ + struct timecounter base; + + /** + * @brief This member provides a software fall-back counter. + */ + uint32_t software_counter; + +#if !defined(LEON3_HAS_ASR_22_23_UP_COUNTER) + /** + * @brief This member may reference a hardware counter register. + */ + volatile uint32_t *counter_register; +#endif +} leon3_timecounter; + /** * @brief Provides the LEON3-specific timecounter. * * It is also used by the CPU counter implementation. */ -extern struct timecounter leon3_timecounter_instance; +extern leon3_timecounter leon3_timecounter_instance; /** @} */ diff --git a/bsps/sparc/leon3/start/cpucounter.c b/bsps/sparc/leon3/start/cpucounter.c index 61b767568d..71262ff210 100644 --- a/bsps/sparc/leon3/start/cpucounter.c +++ b/bsps/sparc/leon3/start/cpucounter.c @@ -9,7 +9,7 @@ */ /* - * Copyright (C) 2014, 2018 embedded brains GmbH & Co. KG + * Copyright (C) 2014, 2023 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,80 +39,143 @@ #include <rtems/counter.h> #include <rtems/sysinit.h> #include <rtems/timecounter.h> -#include <bsp/sparc-counter.h> -struct timecounter leon3_timecounter_instance = { - .tc_counter_mask = 0xffffffff, - .tc_frequency = 1000000000, - .tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER +#if defined(LEON3_HAS_ASR_22_23_UP_COUNTER) || \ + defined(LEON3_PROBE_ASR_22_23_UP_COUNTER) +static uint32_t leon3_timecounter_get_asr_22_23_up_counter( + struct timecounter *tc +) +{ + return leon3_up_counter_low(); +} +#endif + +#if defined(LEON3_HAS_ASR_22_23_UP_COUNTER) + +CPU_Counter_ticks _CPU_Counter_read(void) +{ + return leon3_up_counter_low(); +} + +RTEMS_ALIAS(_CPU_Counter_read) uint32_t _SPARC_Counter_read_ISR_disabled(void); + +#else /* !LEON3_HAS_ASR_22_23_UP_COUNTER */ + +/* + * This is a workaround for: + * https://gcc.gnu.org/bugzilla//show_bug.cgi?id=69027 + */ +__asm__ ( + "\t.section\t\".text\"\n" + "\t.align\t4\n" + "\t.globl\t_CPU_Counter_read\n" + "\t.globl\t_SPARC_Counter_read_ISR_disabled\n" + "\t.type\t_CPU_Counter_read, #function\n" + "\t.type\t_SPARC_Counter_read_ISR_disabled, #function\n" + "_CPU_Counter_read:\n" + "_SPARC_Counter_read_ISR_disabled:\n" + "\tsethi\t%hi(leon3_timecounter_instance), %o0\n" + "\tld [%o0 + %lo(leon3_timecounter_instance)], %o1\n" + "\tor\t%o0, %lo(leon3_timecounter_instance), %o0\n" + "\tor\t%o7, %g0, %g1\n" + "\tcall\t%o1, 0\n" + "\t or\t%g1, %g0, %o7\n" + "\t.previous\n" +); + +static uint32_t leon3_timecounter_get_counter_down(struct timecounter *base) +{ + leon3_timecounter *tc; + + tc = (leon3_timecounter *) base; + return -(*tc->counter_register); +} + +#if defined(LEON3_IRQAMP_PROBE_TIMESTAMP) +static uint32_t leon3_timecounter_get_counter_up(struct timecounter *base) +{ + leon3_timecounter *tc; + + tc = (leon3_timecounter *) base; + return *tc->counter_register; +} +#endif + +#endif /* LEON3_HAS_ASR_22_23_UP_COUNTER */ + +static uint32_t leon3_timecounter_get_dummy(struct timecounter *base) +{ + leon3_timecounter *tc; + uint32_t counter; + + tc = (leon3_timecounter *) base; + counter = tc->software_counter + 1; + tc->software_counter = counter; + return counter; +} + +leon3_timecounter leon3_timecounter_instance = { + .base = { + .tc_get_timecount = leon3_timecounter_get_dummy, + .tc_counter_mask = 0xffffffff, + .tc_frequency = 1000000000, + .tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + } }; uint32_t _CPU_Counter_frequency(void) { - return leon3_timecounter_instance.tc_frequency; + return leon3_timecounter_instance.base.tc_frequency; } #if defined(LEON3_HAS_ASR_22_23_UP_COUNTER) || \ defined(LEON3_PROBE_ASR_22_23_UP_COUNTER) -static void leon3_counter_use_up_counter( - struct timecounter *tc, - SPARC_Counter *counter -) +static void leon3_counter_use_asr_22_23_up_counter(leon3_timecounter *tc) { - counter->read_isr_disabled = _SPARC_Counter_read_asr23; - counter->read = _SPARC_Counter_read_asr23; - - tc->tc_get_timecount = _SPARC_Get_timecount_asr23; - tc->tc_frequency = leon3_up_counter_frequency(); + tc->base.tc_get_timecount = leon3_timecounter_get_asr_22_23_up_counter; + tc->base.tc_frequency = leon3_up_counter_frequency(); } #endif #if defined(LEON3_IRQAMP_PROBE_TIMESTAMP) static void leon3_counter_use_irqamp_timestamp( - struct timecounter *tc, - SPARC_Counter *counter, + leon3_timecounter *tc, irqamp_timestamp *irqmp_ts ) { - counter->read_isr_disabled = _SPARC_Counter_read_up; - counter->read = _SPARC_Counter_read_up; - counter->counter_register = &irqmp_ts->itcnt; - /* Enable interrupt timestamping for an arbitrary interrupt line */ grlib_store_32(&irqmp_ts->itstmpc, IRQAMP_ITSTMPC_TSISEL(1)); - tc->tc_get_timecount = _SPARC_Get_timecount_up; + tc->counter_register = &irqmp_ts->itcnt; + tc->base.tc_get_timecount = leon3_timecounter_get_counter_up; #if defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER) - tc->tc_frequency = leon3_processor_local_bus_frequency(); + tc->base.tc_frequency = leon3_processor_local_bus_frequency(); #else - tc->tc_frequency = ambapp_freq_get(ambapp_plb(), LEON3_IrqCtrl_Adev); + tc->base.tc_frequency = ambapp_freq_get(ambapp_plb(), LEON3_IrqCtrl_Adev); #endif } #endif #if !defined(LEON3_HAS_ASR_22_23_UP_COUNTER) static void leon3_counter_use_gptimer( - struct timecounter *tc, - SPARC_Counter *counter, + leon3_timecounter *tc, gptimer *gpt ) { gptimer_timer *timer; timer = &gpt->timer[LEON3_COUNTER_GPTIMER_INDEX]; - counter->read_isr_disabled = _SPARC_Counter_read_down; - counter->read = _SPARC_Counter_read_down; - counter->counter_register = &timer->tcntval; /* Make timer free-running */ grlib_store_32(&timer->trldval, 0xffffffff); grlib_store_32(&timer->tctrl, GPTIMER_TCTRL_EN | GPTIMER_TCTRL_RS); - tc->tc_get_timecount = _SPARC_Get_timecount_down; + tc->counter_register = &timer->tcntval; + tc->base.tc_get_timecount = leon3_timecounter_get_counter_down; #if defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER) - tc->tc_frequency = LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER; + tc->base.tc_frequency = LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER; #else - tc->tc_frequency = ambapp_freq_get(ambapp_plb(), LEON3_Timer_Adev) / + tc->base.tc_frequency = ambapp_freq_get(ambapp_plb(), LEON3_Timer_Adev) / (grlib_load_32(&gpt->sreload) + 1); #endif } @@ -120,28 +183,27 @@ static void leon3_counter_use_gptimer( static void leon3_counter_initialize(void) { +#if defined(LEON3_HAS_ASR_22_23_UP_COUNTER) + + leon3_up_counter_enable(); + leon3_counter_use_asr_22_23_up_counter(&leon3_timecounter_instance); + +#else /* !LEON3_HAS_ASR_22_23_UP_COUNTER */ + #if defined(LEON3_IRQAMP_PROBE_TIMESTAMP) irqamp_timestamp *irqmp_ts; #endif -#if !defined(LEON3_HAS_ASR_22_23_UP_COUNTER) gptimer *gpt; -#endif - struct timecounter *tc; - SPARC_Counter *counter; + leon3_timecounter *tc; tc = &leon3_timecounter_instance; - counter = &_SPARC_Counter; -#if defined(LEON3_HAS_ASR_22_23_UP_COUNTER) - leon3_up_counter_enable(); - leon3_counter_use_up_counter(tc, counter); -#else /* LEON3_HAS_ASR_22_23_UP_COUNTER */ #if defined(LEON3_PROBE_ASR_22_23_UP_COUNTER) leon3_up_counter_enable(); if (leon3_up_counter_is_available()) { /* Use the LEON4 up-counter if available */ - leon3_counter_use_up_counter(tc, counter); + leon3_counter_use_asr_22_23_up_counter(tc); return; } #endif @@ -151,7 +213,7 @@ static void leon3_counter_initialize(void) if (irqmp_ts != NULL) { /* Use the interrupt controller timestamp counter if available */ - leon3_counter_use_irqamp_timestamp(tc, counter, irqmp_ts); + leon3_counter_use_irqamp_timestamp(tc, irqmp_ts); return; } #endif @@ -159,13 +221,14 @@ static void leon3_counter_initialize(void) gpt = LEON3_Timer_Regs; #if defined(LEON3_GPTIMER_BASE) - leon3_counter_use_gptimer(tc, counter, gpt); + leon3_counter_use_gptimer(tc, gpt); #else if (gpt != NULL) { /* Fall back to the first GPTIMER if available */ - leon3_counter_use_gptimer(tc, counter, gpt); + leon3_counter_use_gptimer(tc, gpt); } #endif + #endif /* LEON3_HAS_ASR_22_23_UP_COUNTER */ } @@ -174,5 +237,3 @@ RTEMS_SYSINIT_ITEM( RTEMS_SYSINIT_CPU_COUNTER, RTEMS_SYSINIT_ORDER_FIRST ); - -SPARC_COUNTER_DEFINITION; diff --git a/bsps/sparc/shared/start/sparc-counter-asm.S b/bsps/sparc/shared/start/sparc-counter-asm.S index 8b988bf3ed..590d77050d 100644 --- a/bsps/sparc/shared/start/sparc-counter-asm.S +++ b/bsps/sparc/shared/start/sparc-counter-asm.S @@ -74,25 +74,6 @@ SYM(_SPARC_Counter_read_default): jmp %o7 + 8 nop - PUBLIC(_SPARC_Counter_read_up) - PUBLIC(_SPARC_Get_timecount_up) -SYM(_SPARC_Counter_read_up): -SYM(_SPARC_Get_timecount_up): - sethi %hi(_SPARC_Counter + 8), %o0 - ld [%o0 + %lo(_SPARC_Counter + 8)], %o0 - jmp %o7 + 8 - ld [%o0], %o0 - - PUBLIC(_SPARC_Counter_read_down) - PUBLIC(_SPARC_Get_timecount_down) -SYM(_SPARC_Counter_read_down): -SYM(_SPARC_Get_timecount_down): - sethi %hi(_SPARC_Counter + 8), %o0 - ld [%o0 + %lo(_SPARC_Counter + 8)], %o0 - ld [%o0], %o0 - jmp %o7 + 8 - xnor %g0, %o0, %o0 - /* * For the corresponding C code is something like this: * @@ -168,10 +149,3 @@ SYM(_SPARC_Get_timecount_clock): add %o4, %o5, %o4 jmp %o7 + 8 sub %o4, %o0, %o0 - - PUBLIC(_SPARC_Counter_read_asr23) - PUBLIC(_SPARC_Get_timecount_asr23) -SYM(_SPARC_Counter_read_asr23): -SYM(_SPARC_Get_timecount_asr23): - jmp %o7 + 8 - mov %asr23, %o0 diff --git a/spec/build/bsps/sparc/leon3/obj.yml b/spec/build/bsps/sparc/leon3/obj.yml index 6585b30310..7a4ccaa0cb 100644 --- a/spec/build/bsps/sparc/leon3/obj.yml +++ b/spec/build/bsps/sparc/leon3/obj.yml @@ -15,7 +15,6 @@ install: - bsps/sparc/leon3/include/leon.h - destination: ${BSP_INCLUDEDIR}/bsp source: - - bsps/sparc/include/bsp/sparc-counter.h - bsps/sparc/leon3/include/bsp/irq.h - bsps/sparc/leon3/include/bsp/irqimpl.h - bsps/sparc/leon3/include/bsp/watchdog.h @@ -58,5 +57,4 @@ source: - bsps/sparc/shared/pci/pci_memreg_sparc_be.c - bsps/sparc/shared/pci/pci_memreg_sparc_le.c - bsps/sparc/shared/start/bsp_fatal_exit.c -- bsps/sparc/shared/start/sparc-counter-asm.S type: build -- 2.35.3 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel