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

4.11
Last change on this file since 291f30f was 291f30f, checked in by Jiri Gaisler <jiri@…>, on Nov 23, 2014 at 9:53:00 PM

sparc/leon3: LEON_Is_interrupt_masked for Leon3 in leon.h wrongly defined

Condition needs to be inverted, as a 1 in the mask register means
that the interrupt is enabled. Solves ticket #1958 in trac.

  • Property mode set to 100644
File size: 11.1 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 LEON Cache Control Register.
91 */
92#define LEON3_REG_CACHE_CTRL_FI      0x00200000 /* Flush instruction cache */
93#define LEON3_REG_CACHE_CTRL_DS      0x00800000 /* Data cache snooping */
94
95/* LEON3 Interrupt Controller */
96extern volatile struct irqmp_regs *LEON3_IrqCtrl_Regs;
97/* LEON3 GP Timer */
98extern volatile struct gptimer_regs *LEON3_Timer_Regs;
99
100/* LEON3 CPU Index of boot CPU */
101extern uint32_t LEON3_Cpu_Index;
102
103/* The external IRQ number, -1 if not external interrupts */
104extern int LEON3_IrqCtrl_EIrq;
105
106static __inline__ int bsp_irq_fixup(int irq)
107{
108  int eirq, cpu;
109
110  if (LEON3_IrqCtrl_EIrq != 0 && irq == LEON3_IrqCtrl_EIrq) {
111    /* Get interrupt number from IRQ controller */
112    cpu = _LEON3_Get_current_processor();
113    eirq = LEON3_IrqCtrl_Regs->intid[cpu] & 0x1f;
114    if (eirq & 0x10)
115      irq = eirq;
116  }
117
118  return irq;
119}
120
121/* Macros used for manipulating bits in LEON3 GP Timer Control Register */
122
123#define LEON3_IRQMPSTATUS_CPUNR     28
124#define LEON3_IRQMPSTATUS_BROADCAST 27
125
126
127#ifndef ASM
128
129/*
130 *  Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask,
131 *  and the Interrupt Pending Registers.
132 *
133 *  NOTE: For operations which are not atomic, this code disables interrupts
134 *        to guarantee there are no intervening accesses to the same register.
135 *        The operations which read the register, modify the value and then
136 *        store the result back are vulnerable.
137 */
138
139extern rtems_interrupt_lock LEON3_IrqCtrl_Lock;
140
141#define LEON3_IRQCTRL_ACQUIRE( _lock_context ) \
142  rtems_interrupt_lock_acquire( &LEON3_IrqCtrl_Lock, _lock_context )
143
144#define LEON3_IRQCTRL_RELEASE( _lock_context ) \
145  rtems_interrupt_lock_release( &LEON3_IrqCtrl_Lock, _lock_context )
146
147#define LEON_Clear_interrupt( _source ) \
148  do { \
149    LEON3_IrqCtrl_Regs->iclear = (1 << (_source)); \
150  } while (0)
151
152#define LEON_Force_interrupt( _source ) \
153  do { \
154    LEON3_IrqCtrl_Regs->iforce = (1 << (_source)); \
155  } while (0)
156
157#define LEON_Is_interrupt_pending( _source ) \
158  (LEON3_IrqCtrl_Regs->ipend & (1 << (_source)))
159
160#define LEON_Cpu_Is_interrupt_masked( _source, _cpu ) \
161     (!(LEON3_IrqCtrl_Regs->mask[_cpu] & (1 << (_source))))
162
163#define LEON_Cpu_Mask_interrupt( _source, _cpu ) \
164  do { \
165    rtems_interrupt_lock_context _lock_context; \
166    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
167     LEON3_IrqCtrl_Regs->mask[_cpu]  &= ~(1 << (_source)); \
168    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
169  } while (0)
170
171#define LEON_Cpu_Unmask_interrupt( _source, _cpu ) \
172  do { \
173    rtems_interrupt_lock_context _lock_context; \
174    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
175    LEON3_IrqCtrl_Regs->mask[_cpu]  |= (1 << (_source)); \
176    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
177  } while (0)
178
179#define LEON_Cpu_Disable_interrupt( _source, _previous, _cpu ) \
180  do { \
181    rtems_interrupt_lock_context _lock_context; \
182    uint32_t _mask = 1 << (_source); \
183    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
184     (_previous) = LEON3_IrqCtrl_Regs->mask[_cpu]; \
185     LEON3_IrqCtrl_Regs->mask[_cpu] = _previous & ~_mask; \
186    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
187    (_previous) &= _mask; \
188  } while (0)
189
190#define LEON_Cpu_Restore_interrupt( _source, _previous, _cpu ) \
191  do { \
192    rtems_interrupt_lock_context _lock_context; \
193    uint32_t _mask = 1 << (_source); \
194    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
195      LEON3_IrqCtrl_Regs->mask[_cpu] = \
196        (LEON3_IrqCtrl_Regs->mask[_cpu] & ~_mask) | (_previous); \
197    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
198  } while (0)
199
200/* Map single-cpu operations to local CPU */
201#define LEON_Is_interrupt_masked( _source ) \
202  LEON_Cpu_Is_interrupt_masked(_source, _LEON3_Get_current_processor())
203
204#define LEON_Mask_interrupt(_source) \
205  LEON_Cpu_Mask_interrupt(_source, _LEON3_Get_current_processor())
206
207#define LEON_Unmask_interrupt(_source) \
208  LEON_Cpu_Unmask_interrupt(_source, _LEON3_Get_current_processor())
209
210#define LEON_Disable_interrupt(_source, _previous) \
211  LEON_Cpu_Disable_interrupt(_source, _previous, _LEON3_Get_current_processor())
212
213#define LEON_Restore_interrupt(_source, _previous) \
214  LEON_Cpu_Restore_interrupt(_source, _previous, _LEON3_Get_current_processor())
215
216/* Make all SPARC BSPs have common macros for interrupt handling */
217#define BSP_Clear_interrupt(_source) LEON_Clear_interrupt(_source)
218#define BSP_Force_interrupt(_source) LEON_Force_interrupt(_source)
219#define BSP_Is_interrupt_pending(_source) LEON_Is_interrupt_pending(_source)
220#define BSP_Is_interrupt_masked(_source) LEON_Is_interrupt_masked(_source)
221#define BSP_Unmask_interrupt(_source) LEON_Unmask_interrupt(_source)
222#define BSP_Mask_interrupt(_source) LEON_Mask_interrupt(_source)
223#define BSP_Disable_interrupt(_source, _previous) \
224        LEON_Disable_interrupt(_source, _prev)
225#define BSP_Restore_interrupt(_source, _previous) \
226        LEON_Restore_interrupt(_source, _previous)
227
228/* Make all SPARC BSPs have common macros for interrupt handling on any CPU */
229#define BSP_Cpu_Is_interrupt_masked(_source, _cpu) \
230        LEON_Cpu_Is_interrupt_masked(_source, _cpu)
231#define BSP_Cpu_Unmask_interrupt(_source, _cpu) \
232        LEON_Cpu_Unmask_interrupt(_source, _cpu)
233#define BSP_Cpu_Mask_interrupt(_source, _cpu) \
234        LEON_Cpu_Mask_interrupt(_source, _cpu)
235#define BSP_Cpu_Disable_interrupt(_source, _previous, _cpu) \
236        LEON_Cpu_Disable_interrupt(_source, _prev, _cpu)
237#define BSP_Cpu_Restore_interrupt(_source, _previous, _cpu) \
238        LEON_Cpu_Restore_interrupt(_source, _previous, _cpu)
239
240/*
241 *  Each timer control register is organized as follows:
242 *
243 *    D0 - Enable
244 *          1 = enable counting
245 *          0 = hold scaler and counter
246 *
247 *    D1 - Counter Reload
248 *          1 = reload counter at zero and restart
249 *          0 = stop counter at zero
250 *
251 *    D2 - Counter Load
252 *          1 = load counter with preset value
253 *          0 = no function
254 *
255 */
256
257#define LEON_REG_TIMER_COUNTER_RELOAD_AT_ZERO     0x00000002
258#define LEON_REG_TIMER_COUNTER_STOP_AT_ZERO       0x00000000
259
260#define LEON_REG_TIMER_COUNTER_LOAD_COUNTER       0x00000004
261
262#define LEON_REG_TIMER_COUNTER_ENABLE_COUNTING    0x00000001
263#define LEON_REG_TIMER_COUNTER_DISABLE_COUNTING   0x00000000
264
265#define LEON_REG_TIMER_COUNTER_RELOAD_MASK        0x00000002
266#define LEON_REG_TIMER_COUNTER_ENABLE_MASK        0x00000001
267
268#define LEON_REG_TIMER_COUNTER_DEFINED_MASK       0x00000003
269#define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK  0x00000003
270
271#if defined(RTEMS_MULTIPROCESSING)
272  #define LEON3_CLOCK_INDEX \
273   (rtems_configuration_get_user_multiprocessing_table() ? LEON3_Cpu_Index : 0)
274#else
275  #define LEON3_CLOCK_INDEX 0
276#endif
277
278/*
279 * We assume that a boot loader (usually GRMON) initialized the GPTIMER 0 to
280 * run with 1MHz.  This is used to determine all clock frequencies of the PnP
281 * devices.  See also ambapp_freq_init() and ambapp_freq_get().
282 */
283#define LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER 1000000
284
285/* Load 32-bit word by forcing a cache-miss */
286static inline unsigned int leon_r32_no_cache(uintptr_t addr)
287{
288  unsigned int tmp;
289  __asm__ volatile (" lda [%1] 1, %0\n" : "=r"(tmp) : "r"(addr));
290  return tmp;
291}
292
293/* Let user override which on-chip APBUART will be debug UART
294 * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
295 * 1 = APBUART[0]
296 * 2 = APBUART[1]
297 * 3 = APBUART[2]
298 * ...
299 */
300extern int syscon_uart_index;
301
302/* Let user override which on-chip APBUART will be debug UART
303 * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
304 * 1 = APBUART[0]
305 * 2 = APBUART[1]
306 * 3 = APBUART[2]
307 * ...
308 */
309extern int debug_uart_index;
310
311void leon3_cpu_counter_initialize(void);
312
313/* GRLIB extended IRQ controller register */
314void leon3_ext_irq_init(void);
315
316void bsp_debug_uart_init(void);
317
318void leon3_power_down_loop(void) RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
319
320static inline uint32_t leon3_get_cpu_count(
321  volatile struct irqmp_regs *irqmp
322)
323{
324  uint32_t mpstat = irqmp->mpstat;
325
326  return ((mpstat >> LEON3_IRQMPSTATUS_CPUNR) & 0xf)  + 1;
327}
328
329static inline void leon3_set_system_register(uint32_t addr, uint32_t val)
330{
331  __asm__ volatile(
332    "sta %1, [%0] 2"
333    :
334    : "r" (addr), "r" (val)
335  );
336}
337
338static inline uint32_t leon3_get_system_register(uint32_t addr)
339{
340  uint32_t val;
341
342  __asm__ volatile(
343    "lda [%1] 2, %0"
344    : "=r" (val)
345    : "r" (addr)
346  );
347
348  return val;
349}
350
351static inline void leon3_set_cache_control_register(uint32_t val)
352{
353  leon3_set_system_register(0x0, val);
354}
355
356static inline uint32_t leon3_get_cache_control_register(void)
357{
358  return leon3_get_system_register(0x0);
359}
360
361static inline bool leon3_data_cache_snooping_enabled(void)
362{
363  return leon3_get_cache_control_register() & LEON3_REG_CACHE_CTRL_DS;
364}
365
366static inline uint32_t leon3_get_inst_cache_config_register(void)
367{
368  return leon3_get_system_register(0x8);
369}
370
371static inline uint32_t leon3_get_data_cache_config_register(void)
372{
373  return leon3_get_system_register(0xc);
374}
375
376static inline bool leon3_irqmp_has_timestamp(
377  volatile struct irqmp_timestamp_regs *irqmp_ts
378)
379{
380  return (irqmp_ts->control >> 27) > 0;
381}
382
383#endif /* !ASM */
384
385#ifdef __cplusplus
386}
387#endif
388
389#endif /* !_INCLUDE_LEON_h */
390/* end of include file */
391
Note: See TracBrowser for help on using the repository browser.