[PATCH 2/6] sparc: Move CPU counter implementation

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Sep 15 14:40:09 UTC 2023


Enable a BSP-specific CPU counter implementation.

Update #4954.
---
 bsps/sparc/erc32/clock/ckinit.c               |  9 +--
 .../sparc/include/bsp/sparc-counter.h         | 57 +++++++++----------
 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, 83 insertions(+), 76 deletions(-)
 rename cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h => bsps/sparc/include/bsp/sparc-counter.h (69%)
 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..a3009efce8 100644
--- a/bsps/sparc/erc32/clock/ckinit.c
+++ b/bsps/sparc/erc32/clock/ckinit.c
@@ -23,10 +23,11 @@
  */
 
 #include <bsp.h>
+#include <rtems/score/cpuimpl.h>
 #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 +47,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 +57,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 +84,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 69%
rename from cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h
rename to bsps/sparc/include/bsp/sparc-counter.h
index d9be984179..a659aa98c5 100644
--- a/cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h
+++ b/bsps/sparc/include/bsp/sparc-counter.h
@@ -33,8 +33,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 +44,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 +66,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\", at 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 8947064ff8..287c2c4cd9 100644
--- a/cpukit/score/cpu/sparc/cpu_asm.S
+++ b/cpukit/score/cpu/sparc/cpu_asm.S
@@ -496,9 +496,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
@@ -577,7 +575,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 43b9b75bec..2021b108db 100644
--- a/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
@@ -1132,31 +1132,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 e15be48e9e..f763712175 100644
--- a/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h
@@ -251,6 +251,13 @@ static inline void _CPU_Use_thread_local_storage(
    __asm__ volatile ( "" : : "r" ( 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



More information about the devel mailing list