RTEMS 6.1-rc1
leon3.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-2-Clause */
2
11/*
12 * Copyright (C) 2014, 2023 embedded brains GmbH & Co. KG
13 *
14 * Copyright (C) 2015 Cobham Gaisler AB
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifndef LIBBSP_SPARC_LEON3_BSP_LEON3_H
39#define LIBBSP_SPARC_LEON3_BSP_LEON3_H
40
41#include <grlib/apbuart-regs.h>
42#include <grlib/gptimer-regs.h>
43
44#include <bspopts.h>
45#include <bsp/irqimpl.h>
46
47#if !defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER)
48#include <grlib/ambapp.h>
49#endif
50
51#include <sys/timetc.h>
52
53#ifdef __cplusplus
54extern "C" {
55#endif
56
68
73#define LEON3_REG_CACHE_CTRL_FI 0x00200000U
74
79#define LEON3_REG_CACHE_CTRL_DS 0x00800000U
80
88static inline void leon3_set_system_register( uint32_t addr, uint32_t val )
89{
90 __asm__ volatile(
91 "sta %1, [%0] 2"
92 :
93 : "r" ( addr ), "r" ( val )
94 );
95}
96
104static inline uint32_t leon3_get_system_register( uint32_t addr )
105{
106 uint32_t val;
107
108 __asm__ volatile(
109 "lda [%1] 2, %0"
110 : "=r" ( val )
111 : "r" ( addr )
112 );
113
114 return val;
115}
116
122static inline void leon3_set_cache_control_register( uint32_t val )
123{
124 leon3_set_system_register( 0x0, val );
125}
126
132static inline uint32_t leon3_get_cache_control_register( void )
133{
134 return leon3_get_system_register( 0x0 );
135}
136
143static inline bool leon3_data_cache_snooping_enabled( void )
144{
145 return ( leon3_get_cache_control_register() & LEON3_REG_CACHE_CTRL_DS ) != 0;
146}
147
153static inline uint32_t leon3_get_inst_cache_config_register( void )
154{
155 return leon3_get_system_register( 0x8 );
156}
157
163static inline uint32_t leon3_get_data_cache_config_register( void )
164{
165 return leon3_get_system_register( 0xc );
166}
167
175static inline uint32_t leon3_get_cpu_count( const irqamp *regs )
176{
177 return IRQAMP_MPSTAT_NCPU_GET( grlib_load_32( &regs->mpstat ) ) + 1;
178}
179
180#if !defined(LEON3_GPTIMER_BASE)
196extern int leon3_timer_core_index;
197
212extern unsigned int leon3_timer_prescaler;
213#endif
214
219#if defined(RTEMS_MULTIPROCESSING)
220#define LEON3_CLOCK_INDEX \
221 ( leon3_timer_core_index != 0 ? 0 : 2 * LEON3_Cpu_Index )
222#else
223#define LEON3_CLOCK_INDEX 0
224#endif
225
230#define LEON3_COUNTER_GPTIMER_INDEX ( LEON3_CLOCK_INDEX + 1 )
231
240#define LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER 1000000
241
245#if defined(LEON3_GPTIMER_BASE)
246#define LEON3_Timer_Regs ((gptimer *) LEON3_GPTIMER_BASE)
247#else
249
253extern struct ambapp_dev *LEON3_Timer_Adev;
254#endif
255
261static inline uint32_t leon3_processor_local_bus_frequency( void )
262{
263#if defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER)
264 return ( grlib_load_32( &LEON3_Timer_Regs->sreload ) + 1 ) *
266#else
267 /*
268 * For simplicity, assume that the interrupt controller uses the processor
269 * clock. This is at least true on the GR740.
270 */
271 return ambapp_freq_get( ambapp_plb(), LEON3_IrqCtrl_Adev );
272#endif
273}
274
280static inline uint32_t leon3_up_counter_low( void )
281{
282 uint32_t asr23;
283
284 __asm__ volatile (
285 "mov %%asr23, %0"
286 : "=&r" (asr23)
287 );
288
289 return asr23;
290}
291
297static inline uint32_t leon3_up_counter_high(void)
298{
299 uint32_t asr22;
300
301 __asm__ volatile (
302 "mov %%asr22, %0"
303 : "=&r" (asr22)
304 );
305
306 return asr22;
307}
308
312static inline void leon3_up_counter_enable( void )
313{
314 __asm__ volatile (
315 "mov %g0, %asr22"
316 );
317}
318
319#if !defined(LEON3_HAS_ASR_22_23_UP_COUNTER)
327static inline bool leon3_up_counter_is_available( void )
328{
329 return leon3_up_counter_low() != leon3_up_counter_low();
330}
331#endif
332
338static inline uint32_t leon3_up_counter_frequency( void )
339{
340 return leon3_processor_local_bus_frequency();
341}
342
346#if defined(LEON3_APBUART_BASE)
347#define leon3_debug_uart ((struct apbuart *) LEON3_APBUART_BASE)
348#else
350#endif
351
355typedef struct {
359 struct timecounter base;
360
361#if !defined(LEON3_HAS_ASR_22_23_UP_COUNTER)
366
370 volatile uint32_t *counter_register;
371#endif
373
380
383#ifdef __cplusplus
384}
385#endif
386
387#endif /* LIBBSP_SPARC_LEON3_BSP_LEON3_H */
This header file defines the APBUART register block interface.
This header file defines the GPTIMER register block interface.
#define RTEMS_NO_RETURN
Tells the compiler in a function declaration that this function does not return.
Definition: basedefs.h:386
struct ambapp_dev * LEON3_Timer_Adev
This pointer provides the GPTIMER device information block.
Definition: amba.c:127
gptimer * LEON3_Timer_Regs
This pointer provides the GPTIMER register block address.
Definition: amba.c:126
apbuart * leon3_debug_uart
This pointer provides the debug APBUART register block address.
Definition: printk_support.c:54
int leon3_timer_core_index
This object lets the user override which on-chip GPTIMER core will be used for system clock timer.
unsigned int leon3_timer_prescaler
This object lets the user override system clock timer prescaler.
#define LEON3_REG_CACHE_CTRL_DS
This constant represents the data cache snooping enable flag of the LEON cache control register.
Definition: leon3.h:79
#define LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER
This constant defines the frequency set by the boot loader of the first GPTIMER instance.
Definition: leon3.h:240
struct ambapp_dev * LEON3_IrqCtrl_Adev
This pointer provides the IRQ(A)MP device information block.
Definition: amba.c:122
RTEMS_NO_RETURN void leon3_power_down_loop(void)
Sets asr19 to zero to enter the power-down mode of the processor in an infinite loop.
leon3_timecounter leon3_timecounter_instance
Provides the LEON3-specific timecounter.
Definition: cpucounter.c:224
register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__("g6")
The pointer to the current per-CPU control is available via register g6.
struct ambapp_bus * ambapp_plb(void)
Gets the fully scanned AMBA Plug & Play Processor Local Bus (PLB).
Definition: bspstart.c:58
Definition: ambapp.h:94
This structure defines the APBUART register block memory map.
Definition: apbuart-regs.h:248
This structure defines the GPTIMER register block memory map.
Definition: gptimer-regs.h:346
uint32_t sreload
See Scaler reload value register (SRELOAD).
Definition: gptimer-regs.h:355
This structure defines the IRQ(A)MP register block memory map.
Definition: irqamp-regs.h:780
uint32_t mpstat
See Multiprocessor status register (MPSTAT).
Definition: irqamp-regs.h:804
Represents the LEON3-specific timecounter.
Definition: leon3.h:355
volatile uint32_t * counter_register
This member may reference a hardware counter register.
Definition: leon3.h:370
uint32_t software_counter
This member provides a software fall-back counter.
Definition: leon3.h:365
Definition: timetc.h:60
This header file provides interfaces of the timecounter implementation.