[PATCH v2 2/9] sparc: Move CPU counter implementation
Sebastian Huber
sebastian.huber at embedded-brains.de
Thu Sep 21 15:19:27 UTC 2023
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\", 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 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
More information about the devel
mailing list