RTEMS 5.2
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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
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 = (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 */
350static 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 */
364extern 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 */
373extern 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 */
384extern 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 */
394extern unsigned int leon3_timer_prescaler;
395
396/* GRLIB extended IRQ controller register */
397void leon3_ext_irq_init(void);
398
399void leon3_power_down_loop(void) RTEMS_NO_RETURN;
400
401static 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
410static 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
419static 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
432static inline void leon3_set_cache_control_register(uint32_t val)
433{
434 leon3_set_system_register(0x0, val);
435}
436
437static inline uint32_t leon3_get_cache_control_register(void)
438{
439 return leon3_get_system_register(0x0);
440}
441
442static inline bool leon3_data_cache_snooping_enabled(void)
443{
444 return leon3_get_cache_control_register() & LEON3_REG_CACHE_CTRL_DS;
445}
446
447static inline uint32_t leon3_get_inst_cache_config_register(void)
448{
449 return leon3_get_system_register(0x8);
450}
451
452static inline uint32_t leon3_get_data_cache_config_register(void)
453{
454 return leon3_get_system_register(0xc);
455}
456
457static 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
464static 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
476static 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
488static inline void leon3_up_counter_enable(void)
489{
490 __asm__ volatile (
491 "mov %g0, %asr22"
492 );
493}
494
495static inline bool leon3_up_counter_is_available(void)
496{
497 return leon3_up_counter_low() != leon3_up_counter_low();
498}
499
500static 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
#define RTEMS_NO_RETURN
Definition: basedefs.h:102
register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__("g6")
The pointer to the current per-CPU control is available via register g6.
ISR lock control.
Definition: isrlock.h:56
Definition: ambapp.h:43
Definition: grlib.h:101
Definition: grlib.h:55
Definition: grlib.h:47