source: rtems/c/src/lib/libbsp/sparc/leon3/include/leon.h @ 9361412

5
Last change on this file since 9361412 was 9361412, checked in by Sebastian Huber <sebastian.huber@…>, on 10/18/16 at 22:21:21

bsp/leon3: Avoid implicit integer conversions

  • 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/*
337 * We assume that a boot loader (usually GRMON) initialized the GPTIMER 0 to
338 * run with 1MHz.  This is used to determine all clock frequencies of the PnP
339 * devices.  See also ambapp_freq_init() and ambapp_freq_get().
340 */
341#define LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER 1000000
342
343/* Load 32-bit word by forcing a cache-miss */
344static inline unsigned int leon_r32_no_cache(uintptr_t addr)
345{
346  unsigned int tmp;
347  __asm__ volatile (" lda [%1] 1, %0\n" : "=r"(tmp) : "r"(addr));
348  return tmp;
349}
350
351/* Let user override which on-chip APBUART will be debug UART
352 * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
353 * 1 = APBUART[0]
354 * 2 = APBUART[1]
355 * 3 = APBUART[2]
356 * ...
357 */
358extern int syscon_uart_index;
359
360/* Let user override which on-chip APBUART will be debug UART
361 * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
362 * 1 = APBUART[0]
363 * 2 = APBUART[1]
364 * 3 = APBUART[2]
365 * ...
366 */
367extern int debug_uart_index;
368
369/* Let user override which on-chip TIMER core will be used for system clock
370 * timer. This controls which timer core will be accociated with
371 * LEON3_Timer_Regs registers base address. This value will by destroyed during
372 * initialization.
373 *  0 = Default configuration. GPTIMER[0]
374 *  1 = GPTIMER[1]
375 *  2 = GPTIMER[2]
376 *  ...
377 */
378extern int leon3_timer_core_index;
379
380/* Let user override system clock timer prescaler. This affects all timer
381 * instances on the system clock timer core determined by
382 * leon3_timer_core_index.
383 *  0 = Default configuration. Use bootloader configured value.
384 *  N = Prescaler is set to N. N must not be less that number of timers.
385 *  8 = Prescaler is set to 8 (the fastest prescaler possible on all HW)
386 *  ...
387 */
388extern unsigned int leon3_timer_prescaler;
389
390/* GRLIB extended IRQ controller register */
391void leon3_ext_irq_init(void);
392
393void leon3_power_down_loop(void) RTEMS_NO_RETURN;
394
395static inline uint32_t leon3_get_cpu_count(
396  volatile struct irqmp_regs *irqmp
397)
398{
399  uint32_t mpstat = irqmp->mpstat;
400
401  return ((mpstat >> LEON3_IRQMPSTATUS_CPUNR) & 0xf)  + 1;
402}
403
404static inline void leon3_set_system_register(uint32_t addr, uint32_t val)
405{
406  __asm__ volatile(
407    "sta %1, [%0] 2"
408    :
409    : "r" (addr), "r" (val)
410  );
411}
412
413static inline uint32_t leon3_get_system_register(uint32_t addr)
414{
415  uint32_t val;
416
417  __asm__ volatile(
418    "lda [%1] 2, %0"
419    : "=r" (val)
420    : "r" (addr)
421  );
422
423  return val;
424}
425
426static inline void leon3_set_cache_control_register(uint32_t val)
427{
428  leon3_set_system_register(0x0, val);
429}
430
431static inline uint32_t leon3_get_cache_control_register(void)
432{
433  return leon3_get_system_register(0x0);
434}
435
436static inline bool leon3_data_cache_snooping_enabled(void)
437{
438  return leon3_get_cache_control_register() & LEON3_REG_CACHE_CTRL_DS;
439}
440
441static inline uint32_t leon3_get_inst_cache_config_register(void)
442{
443  return leon3_get_system_register(0x8);
444}
445
446static inline uint32_t leon3_get_data_cache_config_register(void)
447{
448  return leon3_get_system_register(0xc);
449}
450
451static inline bool leon3_irqmp_has_timestamp(
452  volatile struct irqmp_timestamp_regs *irqmp_ts
453)
454{
455  return (irqmp_ts->control >> 27) > 0;
456}
457
458static inline uint32_t leon3_up_counter_low(void)
459{
460  uint32_t asr23;
461
462  __asm__ volatile (
463    "mov %%asr23, %0"
464    : "=&r" (asr23)
465  );
466
467  return asr23;
468}
469
470static inline uint32_t leon3_up_counter_high(void)
471{
472  uint32_t asr22;
473
474  __asm__ volatile (
475    "mov %%asr22, %0"
476    : "=&r" (asr22)
477  );
478
479  return asr22;
480}
481
482static inline void leon3_up_counter_enable(void)
483{
484  __asm__ volatile (
485    "mov %g0, %asr23"
486  );
487}
488
489static inline bool leon3_up_counter_is_available(void)
490{
491  return leon3_up_counter_low() != leon3_up_counter_low();
492}
493
494static inline uint32_t leon3_up_counter_frequency(void)
495{
496  /*
497   * For simplicity, assume that the interrupt controller uses the processor
498   * clock.  This is at least true on the GR740.
499   */
500  return ambapp_freq_get(&ambapp_plb, LEON3_IrqCtrl_Adev);
501}
502
503#endif /* !ASM */
504
505#ifdef __cplusplus
506}
507#endif
508
509#endif /* !_INCLUDE_LEON_h */
510/* end of include file */
511
Note: See TracBrowser for help on using the repository browser.