Enable a BSP-specific CPU counter implementation. Update #4954. --- bsps/sparc/erc32/clock/ckinit.c | 8 +-- .../sparc/include/bsp/sparc-counter.h | 64 +++++++++---------- bsps/sparc/leon2/clock/ckinit.c | 8 +-- bsps/sparc/leon3/clock/ckinit.c | 6 +- bsps/sparc/leon3/start/cpucounter.c | 4 +- .../sparc/shared/start}/sparc-counter-asm.S | 28 +++++++- cpukit/score/cpu/sparc/cpu_asm.S | 6 +- .../score/cpu/sparc/include/rtems/score/cpu.h | 26 +------- .../cpu/sparc/include/rtems/score/cpuimpl.h | 7 ++ spec/build/bsps/sparc/erc32/bsperc32.yml | 2 + spec/build/bsps/sparc/leon2/obj.yml | 2 + spec/build/bsps/sparc/leon3/obj.yml | 2 + spec/build/cpukit/cpusparc.yml | 2 - 13 files changed, 86 insertions(+), 79 deletions(-) rename cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h => bsps/sparc/include/bsp/sparc-counter.h (63%) rename {cpukit/score/cpu/sparc => bsps/sparc/shared/start}/sparc-counter-asm.S (86%)
diff --git a/bsps/sparc/erc32/clock/ckinit.c b/bsps/sparc/erc32/clock/ckinit.c index 83cafb73c3..e8cf7188eb 100644 --- a/bsps/sparc/erc32/clock/ckinit.c +++ b/bsps/sparc/erc32/clock/ckinit.c @@ -26,7 +26,7 @@ #include <rtems/irq-extension.h> #include <rtems/sysinit.h> #include <rtems/timecounter.h> -#include <rtems/score/sparcimpl.h> +#include <bsp/sparc-counter.h> extern int CLOCK_SPEED; @@ -46,7 +46,7 @@ static void erc32_clock_init( void ) rtems_timecounter_install(tc); } -uint32_t _CPU_Counter_frequency(void) +uint32_t _CPU_Counter_frequency( void ) { return ERC32_REAL_TIME_CLOCK_FREQUENCY; } @@ -56,7 +56,7 @@ static void erc32_clock_at_tick( void ) SPARC_Counter *counter; rtems_interrupt_level level; - counter = &_SPARC_Counter_mutable; + counter = &_SPARC_Counter; rtems_interrupt_local_disable(level); ERC32_Clear_interrupt( ERC32_INTERRUPT_REAL_TIME_CLOCK ); @@ -83,7 +83,7 @@ static void erc32_clock_initialize_early( void ) ERC32_MEC_TIMER_COUNTER_RELOAD_AT_ZERO ); - counter = &_SPARC_Counter_mutable; + counter = &_SPARC_Counter; counter->read_isr_disabled = _SPARC_Counter_read_clock_isr_disabled; counter->read = _SPARC_Counter_read_clock; counter->counter_register = &ERC32_MEC.Real_Time_Clock_Counter, diff --git a/cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h b/bsps/sparc/include/bsp/sparc-counter.h similarity index 63% rename from cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h rename to bsps/sparc/include/bsp/sparc-counter.h index d9be984179..c71cddf304 100644 --- a/cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h +++ b/bsps/sparc/include/bsp/sparc-counter.h @@ -3,13 +3,14 @@ /** * @file * - * @ingroup RTEMSScoreCPUSPARC + * @ingroup RTEMSBSPsSPARCShared * - * @brief This header file provides interfaces used by the SPARC port of RTEMS. + * @brief This header file provides interfaces of a CPU counter implementation + * for SPARC BSPs. */ /* - * Copyright (C) 2016, 2018 embedded brains GmbH & Co. KG + * Copyright (C) 2016, 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 @@ -33,8 +34,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _RTEMS_SCORE_SPARCIMPL_H -#define _RTEMS_SCORE_SPARCIMPL_H +#ifndef _BSP_SPARC_COUNTER_H +#define _BSP_SPARC_COUNTER_H #include <rtems/score/cpu.h> @@ -44,13 +45,6 @@ extern "C" { struct timecounter; -/* - * Provides a mutable alias to _SPARC_Counter for use in - * _SPARC_Counter_initialize(). The _SPARC_Counter and _SPARC_Counter_mutable - * are defined via the SPARC_COUNTER_DEFINITION define. - */ -extern SPARC_Counter _SPARC_Counter_mutable; - void _SPARC_Counter_at_tick_clock( void ); CPU_Counter_ticks _SPARC_Counter_read_default( void ); @@ -73,33 +67,35 @@ uint32_t _SPARC_Get_timecount_clock( struct timecounter * ); uint32_t _SPARC_Get_timecount_asr23( struct timecounter * ); +typedef CPU_Counter_ticks ( *SPARC_Counter_read )( void ); + /* - * Defines the _SPARC_Counter and _SPARC_Counter_mutable global variables. - * Place this define in the global file scope of the CPU counter support file - * of the BSP. + * The SPARC processors supported by RTEMS have no built-in CPU counter + * support. We have to use some hardware counter module for this purpose, for + * example the GPTIMER instance used by the clock driver. The BSP must provide + * an implementation of the CPU counter read function. This allows the use of + * dynamic hardware enumeration. */ +typedef struct { + SPARC_Counter_read read_isr_disabled; + SPARC_Counter_read read; + volatile const CPU_Counter_ticks *counter_register; + volatile const uint32_t *pending_register; + uint32_t pending_mask; + CPU_Counter_ticks accumulated; + CPU_Counter_ticks interval; +} SPARC_Counter; + +extern SPARC_Counter _SPARC_Counter; + #define SPARC_COUNTER_DEFINITION \ - __asm__ ( \ - "\t.global\t_SPARC_Counter\n" \ - "\t.global\t_SPARC_Counter_mutable\n" \ - "\t.section\t.data._SPARC_Counter,\"aw\",@progbits\n" \ - "\t.align\t4\n" \ - "\t.type\t_SPARC_Counter, #object\n" \ - "\t.size\t_SPARC_Counter, 28\n" \ - "_SPARC_Counter:\n" \ - "_SPARC_Counter_mutable:\n" \ - "\t.long\t_SPARC_Counter_read_default\n" \ - "\t.long\t_SPARC_Counter_read_default\n" \ - "\t.long\t0\n" \ - "\t.long\t0\n" \ - "\t.long\t0\n" \ - "\t.long\t0\n" \ - "\t.long\t0\n" \ - "\t.previous\n" \ - ) + SPARC_Counter _SPARC_Counter = { \ + .read_isr_disabled = _SPARC_Counter_read_default, \ + .read = _SPARC_Counter_read_default \ + } #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* _RTEMS_SCORE_SPARCIMPL_H */ +#endif /* _BSP_SPARC_COUNTER_H */ diff --git a/bsps/sparc/leon2/clock/ckinit.c b/bsps/sparc/leon2/clock/ckinit.c index 604d995573..31f8bca7ba 100644 --- a/bsps/sparc/leon2/clock/ckinit.c +++ b/bsps/sparc/leon2/clock/ckinit.c @@ -45,7 +45,7 @@ #include <bspopts.h> #include <rtems/sysinit.h> #include <rtems/timecounter.h> -#include <rtems/score/sparcimpl.h> +#include <bsp/sparc-counter.h> extern int CLOCK_SPEED; @@ -70,7 +70,7 @@ static void leon2_clock_at_tick( void ) SPARC_Counter *counter; rtems_interrupt_level level; - counter = &_SPARC_Counter_mutable; + counter = &_SPARC_Counter; rtems_interrupt_local_disable(level); LEON_Clear_interrupt( LEON_INTERRUPT_TIMER1 ); @@ -91,7 +91,7 @@ static void leon2_clock_initialize_early( void ) LEON_REG_TIMER_COUNTER_LOAD_COUNTER ); - counter = &_SPARC_Counter_mutable; + counter = &_SPARC_Counter; counter->read_isr_disabled = _SPARC_Counter_read_clock_isr_disabled; counter->read = _SPARC_Counter_read_clock; counter->counter_register = &LEON_REG.Timer_Counter_1; @@ -107,7 +107,7 @@ RTEMS_SYSINIT_ITEM( RTEMS_SYSINIT_ORDER_FIRST ); -uint32_t _CPU_Counter_frequency(void) +uint32_t _CPU_Counter_frequency( void ) { return LEON2_TIMER_1_FREQUENCY; } diff --git a/bsps/sparc/leon3/clock/ckinit.c b/bsps/sparc/leon3/clock/ckinit.c index cff2991e60..eea4649fa3 100644 --- a/bsps/sparc/leon3/clock/ckinit.c +++ b/bsps/sparc/leon3/clock/ckinit.c @@ -47,7 +47,7 @@ #include <rtems/rtems/intr.h> #include <grlib/irqamp.h> #include <rtems/score/profiling.h> -#include <rtems/score/sparcimpl.h> +#include <bsp/sparc-counter.h> #include <rtems/timecounter.h> #if !defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER) @@ -73,7 +73,7 @@ static void leon3_tc_tick_default(void) SPARC_Counter *counter; rtems_interrupt_level level; - counter = &_SPARC_Counter_mutable; + counter = &_SPARC_Counter; rtems_interrupt_local_disable(level); grlib_store_32(&LEON3_IrqCtrl_Regs->iclear, counter->pending_mask); @@ -249,7 +249,7 @@ static void leon3_clock_use_gptimer( #else SPARC_Counter *counter; - counter = &_SPARC_Counter_mutable; + counter = &_SPARC_Counter; counter->read_isr_disabled = _SPARC_Counter_read_clock_isr_disabled; counter->read = _SPARC_Counter_read_clock; counter->counter_register = &timer->tcntval; diff --git a/bsps/sparc/leon3/start/cpucounter.c b/bsps/sparc/leon3/start/cpucounter.c index c36e7ea23b..a6db7677a3 100644 --- a/bsps/sparc/leon3/start/cpucounter.c +++ b/bsps/sparc/leon3/start/cpucounter.c @@ -38,7 +38,7 @@ #include <rtems/counter.h> #include <rtems/sysinit.h> -#include <rtems/score/sparcimpl.h> +#include <bsp/sparc-counter.h> static uint32_t leon3_counter_frequency = 1000000000; @@ -112,7 +112,7 @@ static void leon3_counter_initialize(void) #endif SPARC_Counter *counter; - counter = &_SPARC_Counter_mutable; + counter = &_SPARC_Counter; #if defined(LEON3_HAS_ASR_22_23_UP_COUNTER) leon3_up_counter_enable(); diff --git a/cpukit/score/cpu/sparc/sparc-counter-asm.S b/bsps/sparc/shared/start/sparc-counter-asm.S similarity index 86% rename from cpukit/score/cpu/sparc/sparc-counter-asm.S rename to bsps/sparc/shared/start/sparc-counter-asm.S index 890876eff1..8b988bf3ed 100644 --- a/cpukit/score/cpu/sparc/sparc-counter-asm.S +++ b/bsps/sparc/shared/start/sparc-counter-asm.S @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (C) 2016, 2018 embedded brains GmbH & Co. KG + * Copyright (C) 2016, 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,6 +39,32 @@ .section ".text" .align 4 + /* + * This is a workaround for: + * https://gcc.gnu.org/bugzilla//show_bug.cgi?id=69027 + */ + PUBLIC(_CPU_Counter_read) +SYM(_CPU_Counter_read): + sethi %hi(_SPARC_Counter + 4), %o1 + ld [%o1 + %lo(_SPARC_Counter + 4)], %o1 + or %o7, %g0, %g1 + call %o1, 0 + or %g1, %g0, %o7 + +#if defined(RTEMS_PROFILING) + /* + * This is a workaround for: + * https://gcc.gnu.org/bugzilla//show_bug.cgi?id=69027 + */ + PUBLIC(_SPARC_Counter_read_ISR_disabled) +SYM(_SPARC_Counter_read_ISR_disabled): + sethi %hi(_SPARC_Counter), %o1 + ld [%o1 + %lo(_SPARC_Counter)], %o1 + or %o7, %g0, %g1 + call %o1, 0 + or %g1, %g0, %o7 +#endif + PUBLIC(_SPARC_Counter_read_default) SYM(_SPARC_Counter_read_default): sethi %hi(_SPARC_Counter + 12), %o1 diff --git a/cpukit/score/cpu/sparc/cpu_asm.S b/cpukit/score/cpu/sparc/cpu_asm.S index e742acae5a..fd7186b499 100644 --- a/cpukit/score/cpu/sparc/cpu_asm.S +++ b/cpukit/score/cpu/sparc/cpu_asm.S @@ -523,9 +523,7 @@ dont_do_the_window: bnz dont_switch_stacks ! No, then do not switch stacks #if defined(RTEMS_PROFILING) - sethi %hi(_SPARC_Counter), %o5 - ld [%o5 + %lo(_SPARC_Counter)], %l4 - call %l4 + call SYM(_SPARC_Counter_read_ISR_disabled) nop mov %o0, %o5 #else @@ -604,7 +602,7 @@ dont_switch_stacks: cmp %l7, 0 bne profiling_not_outer_most_exit nop - call %l4 ! Call _SPARC_Counter.counter_read + call SYM(_SPARC_Counter_read_ISR_disabled) mov %g1, %l4 ! Save previous interrupt status mov %o0, %o2 ! o2 = 3rd arg = interrupt exit instant mov %l3, %o1 ! o1 = 2nd arg = interrupt entry instant diff --git a/cpukit/score/cpu/sparc/include/rtems/score/cpu.h b/cpukit/score/cpu/sparc/include/rtems/score/cpu.h index 7a3588f812..a21cef371f 100644 --- a/cpukit/score/cpu/sparc/include/rtems/score/cpu.h +++ b/cpukit/score/cpu/sparc/include/rtems/score/cpu.h @@ -1151,31 +1151,7 @@ typedef uint32_t CPU_Counter_ticks; uint32_t _CPU_Counter_frequency( void ); -typedef CPU_Counter_ticks ( *SPARC_Counter_read )( void ); - -/* - * The SPARC processors supported by RTEMS have no built-in CPU counter - * support. We have to use some hardware counter module for this purpose, for - * example the GPTIMER instance used by the clock driver. The BSP must provide - * an implementation of the CPU counter read function. This allows the use of - * dynamic hardware enumeration. - */ -typedef struct { - SPARC_Counter_read read_isr_disabled; - SPARC_Counter_read read; - volatile const CPU_Counter_ticks *counter_register; - volatile const uint32_t *pending_register; - uint32_t pending_mask; - CPU_Counter_ticks accumulated; - CPU_Counter_ticks interval; -} SPARC_Counter; - -extern const SPARC_Counter _SPARC_Counter; - -static inline CPU_Counter_ticks _CPU_Counter_read( void ) -{ - return ( *_SPARC_Counter.read )(); -} +CPU_Counter_ticks _CPU_Counter_read( void ); /** Type that can store a 32-bit integer or a pointer. */ typedef uintptr_t CPU_Uint32ptr; diff --git a/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h index 459b981ae5..9697209a97 100644 --- a/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h @@ -258,6 +258,13 @@ static inline void *_CPU_Get_TLS_thread_pointer( return (void *) context->g7; } +#if defined(RTEMS_PROFILING) +/** + * @brief Reads the CPU counter while interrupts are disabled. + */ +CPU_Counter_ticks _SPARC_Counter_read_ISR_disabled( void ); +#endif + #ifdef __cplusplus } #endif diff --git a/spec/build/bsps/sparc/erc32/bsperc32.yml b/spec/build/bsps/sparc/erc32/bsperc32.yml index f373d67b6d..4d57e5902d 100644 --- a/spec/build/bsps/sparc/erc32/bsperc32.yml +++ b/spec/build/bsps/sparc/erc32/bsperc32.yml @@ -18,6 +18,7 @@ install: source: - bsps/sparc/erc32/include/bsp/irq.h - bsps/sparc/erc32/include/bsp/irqimpl.h + - bsps/sparc/include/bsp/sparc-counter.h - destination: ${BSP_LIBDIR} source: - bsps/sparc/erc32/start/linkcmds @@ -69,4 +70,5 @@ source: - bsps/sparc/shared/irq/bsp_isr_handler.c - bsps/sparc/shared/irq/irq-shared.c - bsps/sparc/shared/start/bsp_fatal_exit.c +- bsps/sparc/shared/start/sparc-counter-asm.S type: build diff --git a/spec/build/bsps/sparc/leon2/obj.yml b/spec/build/bsps/sparc/leon2/obj.yml index edcdfe7489..5a68f896ed 100644 --- a/spec/build/bsps/sparc/leon2/obj.yml +++ b/spec/build/bsps/sparc/leon2/obj.yml @@ -14,6 +14,7 @@ install: - bsps/sparc/leon2/include/leon.h - destination: ${BSP_INCLUDEDIR}/bsp source: + - bsps/sparc/include/bsp/sparc-counter.h - bsps/sparc/leon2/include/bsp/at697_pci.h - bsps/sparc/leon2/include/bsp/irq.h - bsps/sparc/leon2/include/bsp/irqimpl.h @@ -47,4 +48,5 @@ source: - bsps/sparc/shared/irq/bsp_isr_handler.c - bsps/sparc/shared/irq/irq-shared.c - bsps/sparc/shared/start/bsp_fatal_exit.c +- bsps/sparc/shared/start/sparc-counter-asm.S type: build diff --git a/spec/build/bsps/sparc/leon3/obj.yml b/spec/build/bsps/sparc/leon3/obj.yml index 7a4ccaa0cb..6585b30310 100644 --- a/spec/build/bsps/sparc/leon3/obj.yml +++ b/spec/build/bsps/sparc/leon3/obj.yml @@ -15,6 +15,7 @@ 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 @@ -57,4 +58,5 @@ 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 diff --git a/spec/build/cpukit/cpusparc.yml b/spec/build/cpukit/cpusparc.yml index aeaecc7bae..42406bcd95 100644 --- a/spec/build/cpukit/cpusparc.yml +++ b/spec/build/cpukit/cpusparc.yml @@ -25,7 +25,6 @@ install: - cpukit/score/cpu/sparc/include/rtems/score/cpu.h - cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h - cpukit/score/cpu/sparc/include/rtems/score/sparc.h - - cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h links: [] source: - cpukit/score/cpu/no_cpu/cpuidle.c @@ -36,7 +35,6 @@ source: - cpukit/score/cpu/sparc/sparc-bad-trap.S - cpukit/score/cpu/sparc/sparc-context-validate.S - cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S -- cpukit/score/cpu/sparc/sparc-counter-asm.S - cpukit/score/cpu/sparc/sparc-exception-frame-print.c - cpukit/score/cpu/sparc/sparc-isr-handler.S - cpukit/score/cpu/sparc/sparc-isr-install.c -- 2.35.3 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel