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

4.115
Last change on this file since 9b292ea was c1764100, checked in by Daniel Hellstrom <daniel@…>, on 12/16/11 at 10:39:23

LEON3: new Console driver, APBUART driver using Driver Manager

This patch reimplements the console driver of the LEON3 BSP, it
has split up the console driver in two parts: Console driver and
UART driver. Before the only UART supported was APBUART and only
on-chip APBUARTs found during startup. However splitting the
driver in two allows any UART interface to reuse the termios
attach code of the console driver, pratically this has always
been a problem when discovering APBUARTs after startup for
example the PCI board GR-RASTA-IO has APBUARTs and must wait
until after PCI has been setup.

Since the only current driver that supports the new console
driver uses the Driver Manager, the new console driver is
only enabled when Driver Manager is initialized during startup.

The new APBUART driver supports:

  • polling mode
  • interrupt mode
  • task-driven mode
  • set UART attributes
  • read UART attributes (system console inherit settings from boot loader)
  • Driver manager for finding/initialization of the hardware
  • 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 *irqmp_dev;
135
136/* LEON3 GP Timer */
137extern volatile struct gptimer_regs *LEON3_Timer_Regs;
138extern struct ambapp_dev *timer_dev;
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.