source: rtems/bsps/sparc/leon3/include/leon.h @ d7a48e1

Last change on this file since d7a48e1 was d7a48e1, checked in by Sebastian Huber <sebastian.huber@…>, on 10/06/20 at 05:39:44

rtems: Improve RTEMS_NO_RETURN attribute

Provide RTEMS_NO_RETURN also in case RTEMS_DEBUG is defined to prevent errors
like this:

error: no return statement in function returning non-void [-Werror=return-type]

Use C11 and C++11 standard means to declare a no-return function.

Close #4122.

  • Property mode set to 100644
File size: 15.0 KB
Line 
1/**
2 * @file
3 * @ingroup sparc_leon3
4 * @brief LEON3 BSP data types and macros
5 */
6
7/*  leon.h
8 *
9 *  LEON3 BSP data types and macros.
10 *
11 *  COPYRIGHT (c) 1989-1998.
12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  Modified for LEON3 BSP.
15 *  COPYRIGHT (c) 2004.
16 *  Gaisler Research.
17 *
18 *  The license and distribution terms for this file may be
19 *  found in the file LICENSE in this distribution or at
20 *  http://www.rtems.org/license/LICENSE.
21 */
22
23#ifndef _INCLUDE_LEON_h
24#define _INCLUDE_LEON_h
25
26#include <rtems.h>
27#include <amba.h>
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33#define LEON_INTERRUPT_EXTERNAL_1 5
34
35#ifndef ASM
36/*
37 *  Trap Types for on-chip peripherals
38 *
39 *  Source: Table 8 - Interrupt Trap Type and Default Priority Assignments
40 *
41 *  NOTE: The priority level for each source corresponds to the least
42 *        significant nibble of the trap type.
43 */
44
45#define LEON_TRAP_TYPE( _source ) SPARC_ASYNCHRONOUS_TRAP((_source) + 0x10)
46
47#define LEON_TRAP_SOURCE( _trap ) ((_trap) - 0x10)
48
49#define LEON_INT_TRAP( _trap ) \
50  ( (_trap) >= 0x11 && \
51    (_trap) <= 0x1F )
52
53/* /\* */
54/*  *  This is used to manipulate the on-chip registers. */
55/*  * */
56/*  *  The following symbol must be defined in the linkcmds file and point */
57/*  *  to the correct location. */
58/*  *\/ */
59/* Leon uses dynamic register mapping using amba configuration records */
60/* LEON_Register_Map is obsolete */
61/* extern LEON_Register_Map LEON_REG; */
62
63#endif
64
65/*
66 *  The following defines the bits in Memory Configuration Register 1.
67 */
68
69#define LEON_MEMORY_CONFIGURATION_PROM_SIZE_MASK  0x0003C000
70
71/*
72 *  The following defines the bits in Memory Configuration Register 1.
73 */
74
75#define LEON_MEMORY_CONFIGURATION_RAM_SIZE_MASK  0x00001E00
76
77
78/*
79 *  The following defines the bits in the Timer Control Register.
80 */
81
82#define LEON_REG_TIMER_CONTROL_EN    0x00000001  /* 1 = enable counting */
83                                              /* 0 = hold scalar and counter */
84#define LEON_REG_TIMER_CONTROL_RL    0x00000002  /* 1 = reload at 0 */
85                                              /* 0 = stop at 0 */
86#define LEON_REG_TIMER_CONTROL_LD    0x00000004  /* 1 = load counter */
87                                              /* 0 = no function */
88
89/*
90 *  The following defines the bits in the UART Control Registers.
91 */
92
93#define LEON_REG_UART_CONTROL_RTD  0x000000FF /* RX/TX data */
94
95/*
96 *  The following defines the bits in the LEON UART Status Register.
97 */
98
99#define LEON_REG_UART_STATUS_DR   0x00000001 /* Data Ready */
100#define LEON_REG_UART_STATUS_TSE  0x00000002 /* TX Send Register Empty */
101#define LEON_REG_UART_STATUS_THE  0x00000004 /* TX Hold Register Empty */
102#define LEON_REG_UART_STATUS_BR   0x00000008 /* Break Error */
103#define LEON_REG_UART_STATUS_OE   0x00000010 /* RX Overrun Error */
104#define LEON_REG_UART_STATUS_PE   0x00000020 /* RX Parity Error */
105#define LEON_REG_UART_STATUS_FE   0x00000040 /* RX Framing Error */
106#define LEON_REG_UART_STATUS_TF   0x00000200 /* FIFO Full */
107#define LEON_REG_UART_STATUS_ERR  0x00000078 /* Error Mask */
108
109/*
110 *  The following defines the bits in the LEON UART Control Register.
111 */
112
113#define LEON_REG_UART_CTRL_RE     0x00000001 /* Receiver enable */
114#define LEON_REG_UART_CTRL_TE     0x00000002 /* Transmitter enable */
115#define LEON_REG_UART_CTRL_RI     0x00000004 /* Receiver interrupt enable */
116#define LEON_REG_UART_CTRL_TI     0x00000008 /* Transmitter interrupt enable */
117#define LEON_REG_UART_CTRL_PS     0x00000010 /* Parity select */
118#define LEON_REG_UART_CTRL_PE     0x00000020 /* Parity enable */
119#define LEON_REG_UART_CTRL_FL     0x00000040 /* Flow control enable */
120#define LEON_REG_UART_CTRL_LB     0x00000080 /* Loop Back enable */
121#define LEON_REG_UART_CTRL_DB     0x00000800 /* Debug FIFO enable */
122#define LEON_REG_UART_CTRL_SI     0x00004000 /* TX shift register empty IRQ enable */
123#define LEON_REG_UART_CTRL_FA     0x80000000 /* FIFO Available */
124#define LEON_REG_UART_CTRL_FA_BIT 31
125
126/*
127 *  The following defines the bits in the LEON Cache Control Register.
128 */
129#define LEON3_REG_CACHE_CTRL_FI      0x00200000 /* Flush instruction cache */
130#define LEON3_REG_CACHE_CTRL_DS      0x00800000 /* Data cache snooping */
131
132/* LEON3 Interrupt Controller */
133extern volatile struct irqmp_regs *LEON3_IrqCtrl_Regs;
134extern struct ambapp_dev *LEON3_IrqCtrl_Adev;
135
136/* LEON3 GP Timer */
137extern volatile struct gptimer_regs *LEON3_Timer_Regs;
138extern struct ambapp_dev *LEON3_Timer_Adev;
139
140/* LEON3 CPU Index of boot CPU */
141extern uint32_t LEON3_Cpu_Index;
142
143/* The external IRQ number, -1 if not external interrupts */
144extern int LEON3_IrqCtrl_EIrq;
145
146static __inline__ int bsp_irq_fixup(int irq)
147{
148  int eirq, cpu;
149
150  if (LEON3_IrqCtrl_EIrq != 0 && irq == LEON3_IrqCtrl_EIrq) {
151    /* Get interrupt number from IRQ controller */
152    cpu = _LEON3_Get_current_processor();
153    eirq = LEON3_IrqCtrl_Regs->intid[cpu] & 0x1f;
154    if (eirq & 0x10)
155      irq = eirq;
156  }
157
158  return irq;
159}
160
161/* Macros used for manipulating bits in LEON3 GP Timer Control Register */
162
163#define LEON3_IRQMPSTATUS_CPUNR     28
164#define LEON3_IRQMPSTATUS_BROADCAST 27
165
166
167#ifndef ASM
168
169/*
170 *  Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask,
171 *  and the Interrupt Pending Registers.
172 *
173 *  NOTE: For operations which are not atomic, this code disables interrupts
174 *        to guarantee there are no intervening accesses to the same register.
175 *        The operations which read the register, modify the value and then
176 *        store the result back are vulnerable.
177 */
178
179extern rtems_interrupt_lock LEON3_IrqCtrl_Lock;
180
181#define LEON3_IRQCTRL_ACQUIRE( _lock_context ) \
182  rtems_interrupt_lock_acquire( &LEON3_IrqCtrl_Lock, _lock_context )
183
184#define LEON3_IRQCTRL_RELEASE( _lock_context ) \
185  rtems_interrupt_lock_release( &LEON3_IrqCtrl_Lock, _lock_context )
186
187#define LEON_Clear_interrupt( _source ) \
188  do { \
189    LEON3_IrqCtrl_Regs->iclear = (1U << (_source)); \
190  } while (0)
191
192#define LEON_Force_interrupt( _source ) \
193  do { \
194    LEON3_IrqCtrl_Regs->iforce = (1U << (_source)); \
195  } while (0)
196
197#define LEON_Enable_interrupt_broadcast( _source ) \
198  do { \
199    rtems_interrupt_lock_context _lock_context; \
200    uint32_t _mask = 1U << ( _source ); \
201    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
202    LEON3_IrqCtrl_Regs->bcast |= _mask; \
203    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
204  } while (0)
205
206#define LEON_Disable_interrupt_broadcast( _source ) \
207  do { \
208    rtems_interrupt_lock_context _lock_context; \
209    uint32_t _mask = 1U << ( _source ); \
210    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
211    LEON3_IrqCtrl_Regs->bcast &= ~_mask; \
212    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
213  } while (0)
214
215#define LEON_Is_interrupt_pending( _source ) \
216  (LEON3_IrqCtrl_Regs->ipend & (1U << (_source)))
217
218#define LEON_Cpu_Is_interrupt_masked( _source, _cpu ) \
219     (!(LEON3_IrqCtrl_Regs->mask[_cpu] & (1U << (_source))))
220
221#define LEON_Cpu_Mask_interrupt( _source, _cpu ) \
222  do { \
223    rtems_interrupt_lock_context _lock_context; \
224    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
225     LEON3_IrqCtrl_Regs->mask[_cpu]  &= ~(1U << (_source)); \
226    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
227  } while (0)
228
229#define LEON_Cpu_Unmask_interrupt( _source, _cpu ) \
230  do { \
231    rtems_interrupt_lock_context _lock_context; \
232    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
233    LEON3_IrqCtrl_Regs->mask[_cpu]  |= (1U << (_source)); \
234    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
235  } while (0)
236
237#define LEON_Cpu_Disable_interrupt( _source, _previous, _cpu ) \
238  do { \
239    rtems_interrupt_lock_context _lock_context; \
240    uint32_t _mask = 1U << (_source); \
241    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
242     (_previous) = LEON3_IrqCtrl_Regs->mask[_cpu]; \
243     LEON3_IrqCtrl_Regs->mask[_cpu] = _previous & ~_mask; \
244    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
245    (_previous) &= _mask; \
246  } while (0)
247
248#define LEON_Cpu_Restore_interrupt( _source, _previous, _cpu ) \
249  do { \
250    rtems_interrupt_lock_context _lock_context; \
251    uint32_t _mask = 1U << (_source); \
252    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
253      LEON3_IrqCtrl_Regs->mask[_cpu] = \
254        (LEON3_IrqCtrl_Regs->mask[_cpu] & ~_mask) | (_previous); \
255    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
256  } while (0)
257
258/* Map single-cpu operations to local CPU */
259#define LEON_Is_interrupt_masked( _source ) \
260  LEON_Cpu_Is_interrupt_masked(_source, _LEON3_Get_current_processor())
261
262#define LEON_Mask_interrupt(_source) \
263  LEON_Cpu_Mask_interrupt(_source, _LEON3_Get_current_processor())
264
265#define LEON_Unmask_interrupt(_source) \
266  LEON_Cpu_Unmask_interrupt(_source, _LEON3_Get_current_processor())
267
268#define LEON_Disable_interrupt(_source, _previous) \
269  LEON_Cpu_Disable_interrupt(_source, _previous, _LEON3_Get_current_processor())
270
271#define LEON_Restore_interrupt(_source, _previous) \
272  LEON_Cpu_Restore_interrupt(_source, _previous, _LEON3_Get_current_processor())
273
274/* Make all SPARC BSPs have common macros for interrupt handling */
275#define BSP_Clear_interrupt(_source) LEON_Clear_interrupt(_source)
276#define BSP_Force_interrupt(_source) LEON_Force_interrupt(_source)
277#define BSP_Is_interrupt_pending(_source) LEON_Is_interrupt_pending(_source)
278#define BSP_Is_interrupt_masked(_source) LEON_Is_interrupt_masked(_source)
279#define BSP_Unmask_interrupt(_source) LEON_Unmask_interrupt(_source)
280#define BSP_Mask_interrupt(_source) LEON_Mask_interrupt(_source)
281#define BSP_Disable_interrupt(_source, _previous) \
282        LEON_Disable_interrupt(_source, _prev)
283#define BSP_Restore_interrupt(_source, _previous) \
284        LEON_Restore_interrupt(_source, _previous)
285
286/* Make all SPARC BSPs have common macros for interrupt handling on any CPU */
287#define BSP_Cpu_Is_interrupt_masked(_source, _cpu) \
288        LEON_Cpu_Is_interrupt_masked(_source, _cpu)
289#define BSP_Cpu_Unmask_interrupt(_source, _cpu) \
290        LEON_Cpu_Unmask_interrupt(_source, _cpu)
291#define BSP_Cpu_Mask_interrupt(_source, _cpu) \
292        LEON_Cpu_Mask_interrupt(_source, _cpu)
293#define BSP_Cpu_Disable_interrupt(_source, _previous, _cpu) \
294        LEON_Cpu_Disable_interrupt(_source, _prev, _cpu)
295#define BSP_Cpu_Restore_interrupt(_source, _previous, _cpu) \
296        LEON_Cpu_Restore_interrupt(_source, _previous, _cpu)
297
298/*
299 *  Each timer control register is organized as follows:
300 *
301 *    D0 - Enable
302 *          1 = enable counting
303 *          0 = hold scaler and counter
304 *
305 *    D1 - Counter Reload
306 *          1 = reload counter at zero and restart
307 *          0 = stop counter at zero
308 *
309 *    D2 - Counter Load
310 *          1 = load counter with preset value
311 *          0 = no function
312 *
313 */
314
315#define LEON_REG_TIMER_COUNTER_RELOAD_AT_ZERO     0x00000002
316#define LEON_REG_TIMER_COUNTER_STOP_AT_ZERO       0x00000000
317
318#define LEON_REG_TIMER_COUNTER_LOAD_COUNTER       0x00000004
319
320#define LEON_REG_TIMER_COUNTER_ENABLE_COUNTING    0x00000001
321#define LEON_REG_TIMER_COUNTER_DISABLE_COUNTING   0x00000000
322
323#define LEON_REG_TIMER_COUNTER_RELOAD_MASK        0x00000002
324#define LEON_REG_TIMER_COUNTER_ENABLE_MASK        0x00000001
325
326#define LEON_REG_TIMER_COUNTER_DEFINED_MASK       0x00000003
327#define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK  0x00000003
328
329#if defined(RTEMS_MULTIPROCESSING)
330  #define LEON3_CLOCK_INDEX \
331   (rtems_configuration_get_user_multiprocessing_table() ? LEON3_Cpu_Index : 0)
332#else
333  #define LEON3_CLOCK_INDEX 0
334#endif
335
336#if defined(RTEMS_SMP)
337#define LEON3_COUNTER_GPTIMER_INDEX (LEON3_CLOCK_INDEX + 1)
338#else
339#define LEON3_COUNTER_GPTIMER_INDEX LEON3_CLOCK_INDEX
340#endif
341
342/*
343 * We assume that a boot loader (usually GRMON) initialized the GPTIMER 0 to
344 * run with 1MHz.  This is used to determine all clock frequencies of the PnP
345 * devices.  See also ambapp_freq_init() and ambapp_freq_get().
346 */
347#define LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER 1000000
348
349/* Load 32-bit word by forcing a cache-miss */
350static inline unsigned int leon_r32_no_cache(uintptr_t addr)
351{
352  unsigned int tmp;
353  __asm__ volatile (" lda [%1] 1, %0\n" : "=r"(tmp) : "r"(addr));
354  return tmp;
355}
356
357/* Let user override which on-chip APBUART will be debug UART
358 * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
359 * 1 = APBUART[0]
360 * 2 = APBUART[1]
361 * 3 = APBUART[2]
362 * ...
363 */
364extern int syscon_uart_index;
365
366/* Let user override which on-chip APBUART will be debug UART
367 * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
368 * 1 = APBUART[0]
369 * 2 = APBUART[1]
370 * 3 = APBUART[2]
371 * ...
372 */
373extern int leon3_debug_uart_index;
374
375/* Let user override which on-chip TIMER core will be used for system clock
376 * timer. This controls which timer core will be accociated with
377 * LEON3_Timer_Regs registers base address. This value will by destroyed during
378 * initialization.
379 *  0 = Default configuration. GPTIMER[0]
380 *  1 = GPTIMER[1]
381 *  2 = GPTIMER[2]
382 *  ...
383 */
384extern int leon3_timer_core_index;
385
386/* Let user override system clock timer prescaler. This affects all timer
387 * instances on the system clock timer core determined by
388 * leon3_timer_core_index.
389 *  0 = Default configuration. Use bootloader configured value.
390 *  N = Prescaler is set to N. N must not be less that number of timers.
391 *  8 = Prescaler is set to 8 (the fastest prescaler possible on all HW)
392 *  ...
393 */
394extern unsigned int leon3_timer_prescaler;
395
396/* GRLIB extended IRQ controller register */
397void leon3_ext_irq_init(void);
398
399RTEMS_NO_RETURN void leon3_power_down_loop(void);
400
401static inline uint32_t leon3_get_cpu_count(
402  volatile struct irqmp_regs *irqmp
403)
404{
405  uint32_t mpstat = irqmp->mpstat;
406
407  return ((mpstat >> LEON3_IRQMPSTATUS_CPUNR) & 0xf)  + 1;
408}
409
410static inline void leon3_set_system_register(uint32_t addr, uint32_t val)
411{
412  __asm__ volatile(
413    "sta %1, [%0] 2"
414    :
415    : "r" (addr), "r" (val)
416  );
417}
418
419static inline uint32_t leon3_get_system_register(uint32_t addr)
420{
421  uint32_t val;
422
423  __asm__ volatile(
424    "lda [%1] 2, %0"
425    : "=r" (val)
426    : "r" (addr)
427  );
428
429  return val;
430}
431
432static inline void leon3_set_cache_control_register(uint32_t val)
433{
434  leon3_set_system_register(0x0, val);
435}
436
437static inline uint32_t leon3_get_cache_control_register(void)
438{
439  return leon3_get_system_register(0x0);
440}
441
442static inline bool leon3_data_cache_snooping_enabled(void)
443{
444  return leon3_get_cache_control_register() & LEON3_REG_CACHE_CTRL_DS;
445}
446
447static inline uint32_t leon3_get_inst_cache_config_register(void)
448{
449  return leon3_get_system_register(0x8);
450}
451
452static inline uint32_t leon3_get_data_cache_config_register(void)
453{
454  return leon3_get_system_register(0xc);
455}
456
457static inline uint32_t leon3_up_counter_low(void)
458{
459  uint32_t asr23;
460
461  __asm__ volatile (
462    "mov %%asr23, %0"
463    : "=&r" (asr23)
464  );
465
466  return asr23;
467}
468
469static inline uint32_t leon3_up_counter_high(void)
470{
471  uint32_t asr22;
472
473  __asm__ volatile (
474    "mov %%asr22, %0"
475    : "=&r" (asr22)
476  );
477
478  return asr22;
479}
480
481static inline void leon3_up_counter_enable(void)
482{
483  __asm__ volatile (
484    "mov %g0, %asr22"
485  );
486}
487
488static inline bool leon3_up_counter_is_available(void)
489{
490  return leon3_up_counter_low() != leon3_up_counter_low();
491}
492
493static inline uint32_t leon3_up_counter_frequency(void)
494{
495  /*
496   * For simplicity, assume that the interrupt controller uses the processor
497   * clock.  This is at least true on the GR740.
498   */
499  return ambapp_freq_get(&ambapp_plb, LEON3_IrqCtrl_Adev);
500}
501
502#endif /* !ASM */
503
504#ifdef __cplusplus
505}
506#endif
507
508#endif /* !_INCLUDE_LEON_h */
509/* end of include file */
510
Note: See TracBrowser for help on using the repository browser.