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

4.115
Last change on this file since 5564b5a was 5564b5a, checked in by Daniel Hellstrom <daniel@…>, on Apr 7, 2015 at 2:04:13 PM

leon3: timer config updated to use proper naming

To be merged with "leon3: make timer initialization configurable"

  • Property mode set to 100644
File size: 13.7 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 = (1 << (_source)); \
190  } while (0)
191
192#define LEON_Force_interrupt( _source ) \
193  do { \
194    LEON3_IrqCtrl_Regs->iforce = (1 << (_source)); \
195  } while (0)
196
197#define LEON_Is_interrupt_pending( _source ) \
198  (LEON3_IrqCtrl_Regs->ipend & (1 << (_source)))
199
200#define LEON_Cpu_Is_interrupt_masked( _source, _cpu ) \
201     (!(LEON3_IrqCtrl_Regs->mask[_cpu] & (1 << (_source))))
202
203#define LEON_Cpu_Mask_interrupt( _source, _cpu ) \
204  do { \
205    rtems_interrupt_lock_context _lock_context; \
206    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
207     LEON3_IrqCtrl_Regs->mask[_cpu]  &= ~(1 << (_source)); \
208    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
209  } while (0)
210
211#define LEON_Cpu_Unmask_interrupt( _source, _cpu ) \
212  do { \
213    rtems_interrupt_lock_context _lock_context; \
214    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
215    LEON3_IrqCtrl_Regs->mask[_cpu]  |= (1 << (_source)); \
216    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
217  } while (0)
218
219#define LEON_Cpu_Disable_interrupt( _source, _previous, _cpu ) \
220  do { \
221    rtems_interrupt_lock_context _lock_context; \
222    uint32_t _mask = 1 << (_source); \
223    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
224     (_previous) = LEON3_IrqCtrl_Regs->mask[_cpu]; \
225     LEON3_IrqCtrl_Regs->mask[_cpu] = _previous & ~_mask; \
226    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
227    (_previous) &= _mask; \
228  } while (0)
229
230#define LEON_Cpu_Restore_interrupt( _source, _previous, _cpu ) \
231  do { \
232    rtems_interrupt_lock_context _lock_context; \
233    uint32_t _mask = 1 << (_source); \
234    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
235      LEON3_IrqCtrl_Regs->mask[_cpu] = \
236        (LEON3_IrqCtrl_Regs->mask[_cpu] & ~_mask) | (_previous); \
237    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
238  } while (0)
239
240/* Map single-cpu operations to local CPU */
241#define LEON_Is_interrupt_masked( _source ) \
242  LEON_Cpu_Is_interrupt_masked(_source, _LEON3_Get_current_processor())
243
244#define LEON_Mask_interrupt(_source) \
245  LEON_Cpu_Mask_interrupt(_source, _LEON3_Get_current_processor())
246
247#define LEON_Unmask_interrupt(_source) \
248  LEON_Cpu_Unmask_interrupt(_source, _LEON3_Get_current_processor())
249
250#define LEON_Disable_interrupt(_source, _previous) \
251  LEON_Cpu_Disable_interrupt(_source, _previous, _LEON3_Get_current_processor())
252
253#define LEON_Restore_interrupt(_source, _previous) \
254  LEON_Cpu_Restore_interrupt(_source, _previous, _LEON3_Get_current_processor())
255
256/* Make all SPARC BSPs have common macros for interrupt handling */
257#define BSP_Clear_interrupt(_source) LEON_Clear_interrupt(_source)
258#define BSP_Force_interrupt(_source) LEON_Force_interrupt(_source)
259#define BSP_Is_interrupt_pending(_source) LEON_Is_interrupt_pending(_source)
260#define BSP_Is_interrupt_masked(_source) LEON_Is_interrupt_masked(_source)
261#define BSP_Unmask_interrupt(_source) LEON_Unmask_interrupt(_source)
262#define BSP_Mask_interrupt(_source) LEON_Mask_interrupt(_source)
263#define BSP_Disable_interrupt(_source, _previous) \
264        LEON_Disable_interrupt(_source, _prev)
265#define BSP_Restore_interrupt(_source, _previous) \
266        LEON_Restore_interrupt(_source, _previous)
267
268/* Make all SPARC BSPs have common macros for interrupt handling on any CPU */
269#define BSP_Cpu_Is_interrupt_masked(_source, _cpu) \
270        LEON_Cpu_Is_interrupt_masked(_source, _cpu)
271#define BSP_Cpu_Unmask_interrupt(_source, _cpu) \
272        LEON_Cpu_Unmask_interrupt(_source, _cpu)
273#define BSP_Cpu_Mask_interrupt(_source, _cpu) \
274        LEON_Cpu_Mask_interrupt(_source, _cpu)
275#define BSP_Cpu_Disable_interrupt(_source, _previous, _cpu) \
276        LEON_Cpu_Disable_interrupt(_source, _prev, _cpu)
277#define BSP_Cpu_Restore_interrupt(_source, _previous, _cpu) \
278        LEON_Cpu_Restore_interrupt(_source, _previous, _cpu)
279
280/*
281 *  Each timer control register is organized as follows:
282 *
283 *    D0 - Enable
284 *          1 = enable counting
285 *          0 = hold scaler and counter
286 *
287 *    D1 - Counter Reload
288 *          1 = reload counter at zero and restart
289 *          0 = stop counter at zero
290 *
291 *    D2 - Counter Load
292 *          1 = load counter with preset value
293 *          0 = no function
294 *
295 */
296
297#define LEON_REG_TIMER_COUNTER_RELOAD_AT_ZERO     0x00000002
298#define LEON_REG_TIMER_COUNTER_STOP_AT_ZERO       0x00000000
299
300#define LEON_REG_TIMER_COUNTER_LOAD_COUNTER       0x00000004
301
302#define LEON_REG_TIMER_COUNTER_ENABLE_COUNTING    0x00000001
303#define LEON_REG_TIMER_COUNTER_DISABLE_COUNTING   0x00000000
304
305#define LEON_REG_TIMER_COUNTER_RELOAD_MASK        0x00000002
306#define LEON_REG_TIMER_COUNTER_ENABLE_MASK        0x00000001
307
308#define LEON_REG_TIMER_COUNTER_DEFINED_MASK       0x00000003
309#define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK  0x00000003
310
311#if defined(RTEMS_MULTIPROCESSING)
312  #define LEON3_CLOCK_INDEX \
313   (rtems_configuration_get_user_multiprocessing_table() ? LEON3_Cpu_Index : 0)
314#else
315  #define LEON3_CLOCK_INDEX 0
316#endif
317
318/*
319 * We assume that a boot loader (usually GRMON) initialized the GPTIMER 0 to
320 * run with 1MHz.  This is used to determine all clock frequencies of the PnP
321 * devices.  See also ambapp_freq_init() and ambapp_freq_get().
322 */
323#define LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER 1000000
324
325/* Load 32-bit word by forcing a cache-miss */
326static inline unsigned int leon_r32_no_cache(uintptr_t addr)
327{
328  unsigned int tmp;
329  __asm__ volatile (" lda [%1] 1, %0\n" : "=r"(tmp) : "r"(addr));
330  return tmp;
331}
332
333/* Let user override which on-chip APBUART will be debug UART
334 * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
335 * 1 = APBUART[0]
336 * 2 = APBUART[1]
337 * 3 = APBUART[2]
338 * ...
339 */
340extern int syscon_uart_index;
341
342/* Let user override which on-chip APBUART will be debug UART
343 * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
344 * 1 = APBUART[0]
345 * 2 = APBUART[1]
346 * 3 = APBUART[2]
347 * ...
348 */
349extern int debug_uart_index;
350
351/* Let user override which on-chip TIMER core will be used for system clock
352 * timer. This controls which timer core will be accociated with
353 * LEON3_Timer_Regs registers base address. This value will by destroyed during
354 * initialization.
355 *  0 = Default configuration. GPTIMER[0]
356 *  1 = GPTIMER[1]
357 *  2 = GPTIMER[2]
358 *  ...
359 */
360extern int leon3_timer_core_index;
361
362/* Let user override system clock timer prescaler. This affects all timer
363 * instances on the system clock timer core determined by
364 * leon3_timer_core_index.
365 *  0 = Default configuration. Use bootloader configured value.
366 *  N = Prescaler is set to N. N must not be less that number of timers.
367 *  8 = Prescaler is set to 8 (the fastest prescaler possible on all HW)
368 *  ...
369 */
370extern unsigned int leon3_timer_prescaler;
371
372void leon3_cpu_counter_initialize(void);
373
374/* GRLIB extended IRQ controller register */
375void leon3_ext_irq_init(void);
376
377void bsp_debug_uart_init(void);
378
379void leon3_power_down_loop(void) RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
380
381static inline uint32_t leon3_get_cpu_count(
382  volatile struct irqmp_regs *irqmp
383)
384{
385  uint32_t mpstat = irqmp->mpstat;
386
387  return ((mpstat >> LEON3_IRQMPSTATUS_CPUNR) & 0xf)  + 1;
388}
389
390static inline void leon3_set_system_register(uint32_t addr, uint32_t val)
391{
392  __asm__ volatile(
393    "sta %1, [%0] 2"
394    :
395    : "r" (addr), "r" (val)
396  );
397}
398
399static inline uint32_t leon3_get_system_register(uint32_t addr)
400{
401  uint32_t val;
402
403  __asm__ volatile(
404    "lda [%1] 2, %0"
405    : "=r" (val)
406    : "r" (addr)
407  );
408
409  return val;
410}
411
412static inline void leon3_set_cache_control_register(uint32_t val)
413{
414  leon3_set_system_register(0x0, val);
415}
416
417static inline uint32_t leon3_get_cache_control_register(void)
418{
419  return leon3_get_system_register(0x0);
420}
421
422static inline bool leon3_data_cache_snooping_enabled(void)
423{
424  return leon3_get_cache_control_register() & LEON3_REG_CACHE_CTRL_DS;
425}
426
427static inline uint32_t leon3_get_inst_cache_config_register(void)
428{
429  return leon3_get_system_register(0x8);
430}
431
432static inline uint32_t leon3_get_data_cache_config_register(void)
433{
434  return leon3_get_system_register(0xc);
435}
436
437static inline bool leon3_irqmp_has_timestamp(
438  volatile struct irqmp_timestamp_regs *irqmp_ts
439)
440{
441  return (irqmp_ts->control >> 27) > 0;
442}
443
444#endif /* !ASM */
445
446#ifdef __cplusplus
447}
448#endif
449
450#endif /* !_INCLUDE_LEON_h */
451/* end of include file */
452
Note: See TracBrowser for help on using the repository browser.