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