sparc: Move CPU counter implementation

Enable a BSP-specific CPU counter implementation.

Update #4954.
This commit is contained in:
Sebastian Huber
2023-09-14 16:08:53 +02:00
parent 8fe0fc4721
commit b6dc4b4707
13 changed files with 86 additions and 79 deletions

View File

@@ -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,

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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();

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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