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

4.115
Last change on this file since 95518e59 was 95518e59, checked in by Daniel Hellstrom <daniel@…>, on 04/06/12 at 10:05:07

SPARC BSPs: implemented shared-irq using libbsp/shared layer

The implementation use IRQ number instead of vector number since
some IRQs does not have a unique vector, for example the extended
interrupts all enter the same trap vector entry.

Added support for the LEON3 extended interrupt controller when using
the shared IRQ layer.

ERC32 patches untested.

Signed-off-by: Daniel Hellstrom <daniel@…>

Regenerate

  • Property mode set to 100644
File size: 9.3 KB
Line 
1/*  leon.h
2 *
3 *  LEON3 BSP data types and macros.
4 *
5 *  COPYRIGHT (c) 1989-1998.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  Modified for LEON3 BSP.
9 *  COPYRIGHT (c) 2004.
10 *  Gaisler Research.
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 *
16 *  $Id$
17 */
18
19#ifndef _INCLUDE_LEON_h
20#define _INCLUDE_LEON_h
21
22#include <rtems/score/sparc.h>
23#include <amba.h>
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#define LEON_INTERRUPT_EXTERNAL_1 5
30
31#ifndef ASM
32/*
33 *  Trap Types for on-chip peripherals
34 *
35 *  Source: Table 8 - Interrupt Trap Type and Default Priority Assignments
36 *
37 *  NOTE: The priority level for each source corresponds to the least
38 *        significant nibble of the trap type.
39 */
40
41#define LEON_TRAP_TYPE( _source ) SPARC_ASYNCHRONOUS_TRAP((_source) + 0x10)
42
43#define LEON_TRAP_SOURCE( _trap ) ((_trap) - 0x10)
44
45#define LEON_INT_TRAP( _trap ) \
46  ( (_trap) >= 0x11 && \
47    (_trap) <= 0x1F )
48
49typedef struct {
50  volatile unsigned int data;
51  volatile unsigned int status;
52  volatile unsigned int ctrl;
53} LEON3_UART_Regs_Map;
54
55typedef struct {
56  volatile unsigned int value;
57  volatile unsigned int reload;
58  volatile unsigned int conf;
59  volatile unsigned int notused;
60} LEON3_Timer_SubType;
61
62typedef struct {
63  volatile unsigned int scaler_value;   /* common timer registers */
64  volatile unsigned int scaler_reload;
65  volatile unsigned int status;
66  volatile unsigned int notused;
67  LEON3_Timer_SubType timer[8];
68} LEON3_Timer_Regs_Map;
69
70typedef struct {
71  volatile unsigned int iodata;
72  volatile unsigned int ioout;
73  volatile unsigned int iodir;
74  volatile unsigned int irqmask;
75  volatile unsigned int irqpol;
76  volatile unsigned int irqedge;
77} LEON3_IOPORT_Regs_Map;
78
79/* /\* */
80/*  *  This is used to manipulate the on-chip registers. */
81/*  * */
82/*  *  The following symbol must be defined in the linkcmds file and point */
83/*  *  to the correct location. */
84/*  *\/ */
85/* Leon uses dynamic register mapping using amba configuration records */
86/* LEON_Register_Map is obsolete */
87/* extern LEON_Register_Map LEON_REG; */
88
89#endif
90
91/*
92 *  The following defines the bits in Memory Configuration Register 1.
93 */
94
95#define LEON_MEMORY_CONFIGURATION_PROM_SIZE_MASK  0x0003C000
96
97/*
98 *  The following defines the bits in Memory Configuration Register 1.
99 */
100
101#define LEON_MEMORY_CONFIGURATION_RAM_SIZE_MASK  0x00001E00
102
103
104/*
105 *  The following defines the bits in the Timer Control Register.
106 */
107
108#define LEON_REG_TIMER_CONTROL_EN    0x00000001  /* 1 = enable counting */
109                                                 /* 0 = hold scalar and counter */
110#define LEON_REG_TIMER_CONTROL_RL    0x00000002  /* 1 = reload at 0 */
111                                                 /* 0 = stop at 0 */
112#define LEON_REG_TIMER_CONTROL_LD    0x00000004  /* 1 = load counter */
113                                                 /* 0 = no function */
114
115/*
116 *  The following defines the bits in the UART Control Registers.
117 *
118 */
119
120#define LEON_REG_UART_CONTROL_RTD  0x000000FF /* RX/TX data */
121
122/*
123 *  The following defines the bits in the LEON UART Status Registers.
124 */
125
126#define LEON_REG_UART_STATUS_DR   0x00000001 /* Data Ready */
127#define LEON_REG_UART_STATUS_TSE  0x00000002 /* TX Send Register Empty */
128#define LEON_REG_UART_STATUS_THE  0x00000004 /* TX Hold Register Empty */
129#define LEON_REG_UART_STATUS_BR   0x00000008 /* Break Error */
130#define LEON_REG_UART_STATUS_OE   0x00000010 /* RX Overrun Error */
131#define LEON_REG_UART_STATUS_PE   0x00000020 /* RX Parity Error */
132#define LEON_REG_UART_STATUS_FE   0x00000040 /* RX Framing Error */
133#define LEON_REG_UART_STATUS_ERR  0x00000078 /* Error Mask */
134
135/*
136 *  The following defines the bits in the LEON UART Status Registers.
137 */
138
139#define LEON_REG_UART_CTRL_RE     0x00000001 /* Receiver enable */
140#define LEON_REG_UART_CTRL_TE     0x00000002 /* Transmitter enable */
141#define LEON_REG_UART_CTRL_RI     0x00000004 /* Receiver interrupt enable */
142#define LEON_REG_UART_CTRL_TI     0x00000008 /* Transmitter interrupt enable */
143#define LEON_REG_UART_CTRL_PS     0x00000010 /* Parity select */
144#define LEON_REG_UART_CTRL_PE     0x00000020 /* Parity enable */
145#define LEON_REG_UART_CTRL_FL     0x00000040 /* Flow control enable */
146#define LEON_REG_UART_CTRL_LB     0x00000080 /* Loop Back enable */
147
148extern volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs;  /* LEON3 Interrupt Controller */
149extern volatile LEON3_Timer_Regs_Map *LEON3_Timer_Regs; /* LEON3 GP Timer */
150extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
151
152/* LEON3 CPU Index of boot CPU */
153extern int LEON3_Cpu_Index;
154
155/* The external IRQ number, -1 if not external interrupts */
156extern int LEON3_IrqCtrl_EIrq;
157
158static __inline__ int bsp_irq_fixup(int irq)
159{
160       int eirq;
161
162       if (LEON3_IrqCtrl_EIrq != 0 && irq == LEON3_IrqCtrl_EIrq) {
163               /* Get interrupt number from IRQ controller */
164               eirq = LEON3_IrqCtrl_Regs->intid[LEON3_Cpu_Index] & 0x1f;
165               if (eirq & 0x10)
166                       irq = eirq;
167       }
168
169       return irq;
170}
171
172/* Macros used for manipulating bits in LEON3 GP Timer Control Register */
173
174#define LEON3_GPTIMER_EN 1
175#define LEON3_GPTIMER_RL 2
176#define LEON3_GPTIMER_LD 4
177#define LEON3_GPTIMER_IRQEN 8
178
179#define LEON3_MP_IRQ    14        /* Irq used by shared memory driver */
180
181#define LEON3_IRQMPSTATUS_CPUNR     28
182#define LEON3_IRQMPSTATUS_BROADCAST 27
183
184
185#ifndef ASM
186
187/*
188 *  Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask,
189 *  and the Interrupt Pending Registers.
190 *
191 *  NOTE: For operations which are not atomic, this code disables interrupts
192 *        to guarantee there are no intervening accesses to the same register.
193 *        The operations which read the register, modify the value and then
194 *        store the result back are vulnerable.
195 */
196
197#define LEON_Clear_interrupt( _source ) \
198  do { \
199    LEON3_IrqCtrl_Regs->iclear = (1 << (_source)); \
200  } while (0)
201
202#define LEON_Force_interrupt( _source ) \
203  do { \
204    LEON3_IrqCtrl_Regs->iforce = (1 << (_source)); \
205  } while (0)
206
207#define LEON_Is_interrupt_pending( _source ) \
208  (LEON3_IrqCtrl_Regs->ipend & (1 << (_source)))
209
210#define LEON_Is_interrupt_masked( _source ) \
211  do {\
212     (LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] & (1 << (_source))); \
213   } while (0)
214
215#define LEON_Mask_interrupt( _source ) \
216  do { \
217    uint32_t _level; \
218    _level = sparc_disable_interrupts(); \
219     LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index]  &= ~(1 << (_source)); \
220    sparc_enable_interrupts( _level ); \
221  } while (0)
222
223#define LEON_Unmask_interrupt( _source ) \
224  do { \
225    uint32_t _level; \
226    _level = sparc_disable_interrupts(); \
227    LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index]  |= (1 << (_source)); \
228    sparc_enable_interrupts( _level ); \
229  } while (0)
230
231#define LEON_Disable_interrupt( _source, _previous ) \
232  do { \
233    uint32_t _level; \
234    uint32_t _mask = 1 << (_source); \
235    _level = sparc_disable_interrupts(); \
236     (_previous) = LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index]; \
237     LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] = _previous & ~_mask; \
238    sparc_enable_interrupts( _level ); \
239    (_previous) &= _mask; \
240  } while (0)
241
242#define LEON_Restore_interrupt( _source, _previous ) \
243  do { \
244    uint32_t _level; \
245    uint32_t _mask = 1 << (_source); \
246    _level = sparc_disable_interrupts(); \
247      LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] = \
248        (LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] & ~_mask) | (_previous); \
249    sparc_enable_interrupts( _level ); \
250  } while (0)
251
252/* Make all SPARC BSPs have common macros for interrupt handling */
253#define BSP_Clear_interrupt(_source) LEON_Clear_interrupt(_source)
254#define BSP_Force_interrupt(_source) LEON_Force_interrupt(_source)
255#define BSP_Is_interrupt_pending(_source) LEON_Is_interrupt_pending(_source)
256#define BSP_Is_interrupt_masked(_source) LEON_Is_interrupt_masked(_source)
257#define BSP_Unmask_interrupt(_source) LEON_Unmask_interrupt(_source)
258#define BSP_Mask_interrupt(_source) LEON_Mask_interrupt(_source)
259#define BSP_Disable_interrupt(_source, _previous) \
260        LEON_Disable_interrupt(_source, _prev)
261#define BSP_Restore_interrupt(_source, _previous) \
262        LEON_Restore_interrupt(_source, _previous)
263
264/*
265 *  Each timer control register is organized as follows:
266 *
267 *    D0 - Enable
268 *          1 = enable counting
269 *          0 = hold scaler and counter
270 *
271 *    D1 - Counter Reload
272 *          1 = reload counter at zero and restart
273 *          0 = stop counter at zero
274 *
275 *    D2 - Counter Load
276 *          1 = load counter with preset value
277 *          0 = no function
278 *
279 */
280
281#define LEON_REG_TIMER_COUNTER_RELOAD_AT_ZERO     0x00000002
282#define LEON_REG_TIMER_COUNTER_STOP_AT_ZERO       0x00000000
283
284#define LEON_REG_TIMER_COUNTER_LOAD_COUNTER       0x00000004
285
286#define LEON_REG_TIMER_COUNTER_ENABLE_COUNTING    0x00000001
287#define LEON_REG_TIMER_COUNTER_DISABLE_COUNTING   0x00000000
288
289#define LEON_REG_TIMER_COUNTER_RELOAD_MASK        0x00000002
290#define LEON_REG_TIMER_COUNTER_ENABLE_MASK        0x00000001
291
292#define LEON_REG_TIMER_COUNTER_DEFINED_MASK       0x00000003
293#define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK  0x00000003
294
295/* Load 32-bit word by forcing a cache-miss */
296static inline unsigned int leon_r32_no_cache(uintptr_t addr)
297{
298        unsigned int tmp;
299        asm volatile (" lda [%1] 1, %0\n" : "=r"(tmp) : "r"(addr));
300        return tmp;
301}
302
303#endif /* !ASM */
304
305#ifdef __cplusplus
306}
307#endif
308
309#endif /* !_INCLUDE_LEON_h */
310/* end of include file */
311
Note: See TracBrowser for help on using the repository browser.