source: rtems/cpukit/score/cpu/nios2/include/rtems/score/cpu.h @ c8df844

5
Last change on this file since c8df844 was c8df844, checked in by Sebastian Huber <sebastian.huber@…>, on 06/19/18 at 12:59:51

score: Add CPU_INTERRUPT_STACK_ALIGNMENT

Add CPU port define for the interrupt stack alignment. The alignment
should take the stack ABI and the cache line size into account.

Update #3459.

  • Property mode set to 100644
File size: 9.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief Altera Nios II CPU Department Source
5 */
6
7/*
8 *  Copyright (c) 2011 embedded brains GmbH
9 *
10 *  Copyright (c) 2006 Kolja Waschk (rtemsdev/ixo.de)
11 *
12 *  COPYRIGHT (c) 1989-2004.
13 *  On-Line Applications Research Corporation (OAR).
14 *
15 *  The license and distribution terms for this file may be
16 *  found in the file LICENSE in this distribution or at
17 *  http://www.rtems.org/license/LICENSE.
18 */
19
20#ifndef _RTEMS_SCORE_CPU_H
21#define _RTEMS_SCORE_CPU_H
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27#include <rtems/score/basedefs.h>
28#include <rtems/score/nios2.h>
29
30#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE
31
32#define CPU_SIMPLE_VECTORED_INTERRUPTS TRUE
33
34#define CPU_INTERRUPT_NUMBER_OF_VECTORS 32
35
36#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
37
38#define CPU_PROVIDES_ISR_IS_IN_PROGRESS TRUE
39
40#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
41
42#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
43
44#define CPU_ISR_PASSES_FRAME_POINTER FALSE
45
46#define CPU_HARDWARE_FP FALSE
47
48#define CPU_SOFTWARE_FP FALSE
49
50#define CPU_CONTEXT_FP_SIZE 0
51
52#define CPU_ALL_TASKS_ARE_FP FALSE
53
54#define CPU_IDLE_TASK_IS_FP FALSE
55
56#define CPU_USE_DEFERRED_FP_SWITCH FALSE
57
58#define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
59
60#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE
61
62#define CPU_STACK_GROWS_UP FALSE
63
64/* FIXME: Is this the right value? */
65#define CPU_CACHE_LINE_BYTES 32
66
67#define CPU_STRUCTURE_ALIGNMENT \
68  RTEMS_SECTION( ".sdata" ) RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES )
69
70#define CPU_STACK_MINIMUM_SIZE (4 * 1024)
71
72#define CPU_SIZEOF_POINTER 4
73
74/*
75 * Alignment value according to "Nios II Processor Reference" chapter 7
76 * "Application Binary Interface" section "Memory Alignment".
77 */
78#define CPU_ALIGNMENT 4
79
80#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
81
82#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
83
84/*
85 * Alignment value according to "Nios II Processor Reference" chapter 7
86 * "Application Binary Interface" section "Stacks".
87 */
88#define CPU_STACK_ALIGNMENT 4
89
90#define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES
91
92/*
93 * A Nios II configuration with an external interrupt controller (EIC) supports
94 * up to 64 interrupt levels.  A Nios II configuration with an internal
95 * interrupt controller (IIC) has only two interrupt levels (enabled and
96 * disabled).  The _CPU_ISR_Get_level() and _CPU_ISR_Set_level() functions will
97 * take care about configuration specific mappings.
98 */
99#define CPU_MODES_INTERRUPT_MASK 0x3f
100
101#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
102
103#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
104
105#define CPU_MAXIMUM_PROCESSORS 32
106
107#ifndef ASM
108
109/**
110 * @brief Thread register context.
111 *
112 * The thread register context covers the non-volatile registers, the thread
113 * stack pointer, the return address, and the processor status.
114 *
115 * There is no need to save the global pointer (gp) since it is a system wide
116 * constant and set-up with the C runtime environment.
117 *
118 * The @a thread_dispatch_disabled field is used for the external interrupt
119 * controller (EIC) support.
120 *
121 * @see _Nios2_Thread_dispatch_disabled
122 */
123typedef struct {
124  uint32_t r16;
125  uint32_t r17;
126  uint32_t r18;
127  uint32_t r19;
128  uint32_t r20;
129  uint32_t r21;
130  uint32_t r22;
131  uint32_t r23;
132  uint32_t fp;
133  uint32_t status;
134  uint32_t sp;
135  uint32_t ra;
136  uint32_t thread_dispatch_disabled;
137  uint32_t stack_mpubase;
138  uint32_t stack_mpuacc;
139} Context_Control;
140
141#define _CPU_Context_Get_SP( _context ) \
142  (_context)->sp
143
144typedef void CPU_Interrupt_frame;
145
146typedef struct {
147  uint32_t r1;
148  uint32_t r2;
149  uint32_t r3;
150  uint32_t r4;
151  uint32_t r5;
152  uint32_t r6;
153  uint32_t r7;
154  uint32_t r8;
155  uint32_t r9;
156  uint32_t r10;
157  uint32_t r11;
158  uint32_t r12;
159  uint32_t r13;
160  uint32_t r14;
161  uint32_t r15;
162  uint32_t r16;
163  uint32_t r17;
164  uint32_t r18;
165  uint32_t r19;
166  uint32_t r20;
167  uint32_t r21;
168  uint32_t r22;
169  uint32_t r23;
170  uint32_t gp;
171  uint32_t fp;
172  uint32_t sp;
173  uint32_t ra;
174  uint32_t et;
175  uint32_t ea;
176  uint32_t status;
177  uint32_t ienable;
178  uint32_t ipending;
179} CPU_Exception_frame;
180
181#define _CPU_Initialize_vectors()
182
183/**
184 * @brief Macro to disable interrupts.
185 *
186 * The processor status before disabling the interrupts will be stored in
187 * @a _isr_cookie.  This value will be used in _CPU_ISR_Flash() and
188 * _CPU_ISR_Enable().
189 *
190 * The global symbol _Nios2_ISR_Status_mask will be used to clear the bits in
191 * the status register representing the interrupt level.  The global symbol
192 * _Nios2_ISR_Status_bits will be used to set the bits representing an
193 * interrupt level that disables interrupts.  Both global symbols must be
194 * provided by the board support package.
195 *
196 * In case the Nios II uses the internal interrupt controller (IIC), then only
197 * the PIE status bit is used.
198 *
199 * In case the Nios II uses the external interrupt controller (EIC), then the
200 * RSIE status bit or the IL status field is used depending on the interrupt
201 * handling variant and the shadow register usage.
202 */
203#define _CPU_ISR_Disable( _isr_cookie ) \
204  do { \
205    int _tmp; \
206    __asm__ volatile ( \
207      "rdctl %0, status\n" \
208      "movhi %1, %%hiadj(_Nios2_ISR_Status_mask)\n" \
209      "addi %1, %1, %%lo(_Nios2_ISR_Status_mask)\n" \
210      "and %1, %0, %1\n" \
211      "ori %1, %1, %%lo(_Nios2_ISR_Status_bits)\n" \
212      "wrctl status, %1" \
213      : "=&r" (_isr_cookie), "=&r" (_tmp) \
214    ); \
215  } while ( 0 )
216
217/**
218 * @brief Macro to restore the processor status.
219 *
220 * The @a _isr_cookie must contain the processor status returned by
221 * _CPU_ISR_Disable().  The value is not modified.
222 */
223#define _CPU_ISR_Enable( _isr_cookie ) \
224  __builtin_wrctl( 0, (int) _isr_cookie )
225
226/**
227 * @brief Macro to restore the processor status and disable the interrupts
228 * again.
229 *
230 * The @a _isr_cookie must contain the processor status returned by
231 * _CPU_ISR_Disable().  The value is not modified.
232 *
233 * This flash code is optimal for all Nios II configurations.  The rdctl does
234 * not flush the pipeline and has only a late result penalty.  The wrctl on
235 * the other hand leads to a pipeline flush.
236 */
237#define _CPU_ISR_Flash( _isr_cookie ) \
238  do { \
239    int _status = __builtin_rdctl( 0 ); \
240    __builtin_wrctl( 0, (int) _isr_cookie ); \
241    __builtin_wrctl( 0, _status ); \
242  } while ( 0 )
243
244bool _CPU_ISR_Is_enabled( uint32_t level );
245
246/**
247 * @brief Sets the interrupt level for the executing thread.
248 *
249 * The valid values of @a new_level depend on the Nios II configuration.  A
250 * value of zero represents enabled interrupts in all configurations.
251 *
252 * @see _CPU_ISR_Get_level()
253 */
254void _CPU_ISR_Set_level( uint32_t new_level );
255
256/**
257 * @brief Returns the interrupt level of the executing thread.
258 *
259 * @retval 0 Interrupts are enabled.
260 * @retval otherwise The value depends on the Nios II configuration.  In case
261 * of an internal interrupt controller (IIC) the only valid value is one which
262 * indicates disabled interrupts.  In case of an external interrupt controller
263 * (EIC) there are two possibilities.  Firstly if the RSIE status bit is used
264 * to disable interrupts, then one is the only valid value indicating disabled
265 * interrupts.  Secondly if the IL status field is used to disable interrupts,
266 * then this value will be returned.  Interrupts are disabled at the maximum
267 * level specified by the _Nios2_ISR_Status_bits.
268 */
269uint32_t _CPU_ISR_Get_level( void );
270
271/**
272 * @brief Initializes the CPU context.
273 *
274 * The following steps are performed:
275 *  - setting a starting address
276 *  - preparing the stack
277 *  - preparing the stack and frame pointers
278 *  - setting the proper interrupt level in the context
279 *
280 * @param[in] context points to the context area
281 * @param[in] stack_area_begin is the low address of the allocated stack area
282 * @param[in] stack_area_size is the size of the stack area in bytes
283 * @param[in] new_level is the interrupt level for the task
284 * @param[in] entry_point is the task's entry point
285 * @param[in] is_fp is set to @c true if the task is a floating point task
286 * @param[in] tls_area is the thread-local storage (TLS) area
287 */
288void _CPU_Context_Initialize(
289  Context_Control *context,
290  void *stack_area_begin,
291  size_t stack_area_size,
292  uint32_t new_level,
293  void (*entry_point)( void ),
294  bool is_fp,
295  void *tls_area
296);
297
298#define _CPU_Context_Restart_self( _the_context ) \
299  _CPU_Context_restore( (_the_context) );
300
301void _CPU_Fatal_halt( uint32_t _source, uint32_t _error )
302  RTEMS_NO_RETURN;
303
304/**
305 * @brief CPU initialization.
306 */
307void _CPU_Initialize( void );
308
309/**
310 * @brief CPU ISR install raw handler.
311 */
312void _CPU_ISR_install_raw_handler(
313  uint32_t vector,
314  proc_ptr new_handler,
315  proc_ptr *old_handler
316);
317
318/**
319 * @brief CPU ISR install vector.
320 */
321void _CPU_ISR_install_vector(
322  uint32_t vector,
323  proc_ptr new_handler,
324  proc_ptr *old_handler
325);
326
327void _CPU_Context_switch( Context_Control *run, Context_Control *heir );
328
329void _CPU_Context_restore(
330  Context_Control *new_context
331) RTEMS_NO_RETURN;
332
333void _CPU_Context_volatile_clobber( uintptr_t pattern );
334
335void _CPU_Context_validate( uintptr_t pattern );
336
337void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
338
339static inline uint32_t CPU_swap_u32( uint32_t value )
340{
341  uint32_t byte1, byte2, byte3, byte4, swapped;
342
343  byte4 = (value >> 24) & 0xff;
344  byte3 = (value >> 16) & 0xff;
345  byte2 = (value >> 8)  & 0xff;
346  byte1 =  value        & 0xff;
347
348  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
349
350  return swapped;
351}
352
353#define CPU_swap_u16( value ) \
354  (((value&0xff) << 8) | ((value >> 8)&0xff))
355
356typedef uint32_t CPU_Counter_ticks;
357
358uint32_t _CPU_Counter_frequency( void );
359
360CPU_Counter_ticks _CPU_Counter_read( void );
361
362static inline CPU_Counter_ticks _CPU_Counter_difference(
363  CPU_Counter_ticks second,
364  CPU_Counter_ticks first
365)
366{
367  return second - first;
368}
369
370/** Type that can store a 32-bit integer or a pointer. */
371typedef uintptr_t CPU_Uint32ptr;
372
373#endif /* ASM */
374
375#ifdef __cplusplus
376}
377#endif
378
379#endif
Note: See TracBrowser for help on using the repository browser.