RTEMS  5.1
cpu.h
Go to the documentation of this file.
1 
7 /*
8  * This include file contains information pertaining to the Moxie
9  * processor.
10  *
11  * Copyright (c) 2013 Anthony Green
12  *
13  * Based on code with the following copyright..
14  * COPYRIGHT (c) 1989-2006, 2010.
15  * On-Line Applications Research Corporation (OAR).
16  *
17  * The license and distribution terms for this file may be
18  * found in the file LICENSE in this distribution or at
19  * http://www.rtems.org/license/LICENSE.
20  */
21 
22 #ifndef _RTEMS_SCORE_CPU_H
23 #define _RTEMS_SCORE_CPU_H
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 #include <rtems/score/basedefs.h>
30 #include <rtems/score/moxie.h> /* pick up machine definitions */
31 
32 #include <rtems/bspIo.h> /* printk */
33 
34 /* conditional compilation parameters */
35 
36 /*
37  * Should this target use 16 or 32 bit object Ids?
38  *
39  */
40 #define RTEMS_USE_32_BIT_OBJECT
41 
42 /*
43  * Does the CPU follow the simple vectored interrupt model?
44  *
45  * If TRUE, then RTEMS allocates the vector table it internally manages.
46  * If FALSE, then the BSP is assumed to allocate and manage the vector
47  * table
48  *
49  * MOXIE Specific Information:
50  *
51  * XXX document implementation including references if appropriate
52  */
53 #define CPU_SIMPLE_VECTORED_INTERRUPTS TRUE
54 
55 #define CPU_HARDWARE_FP FALSE
56 
57 #define CPU_SOFTWARE_FP FALSE
58 
59 #define CPU_ALL_TASKS_ARE_FP FALSE
60 
61 #define CPU_IDLE_TASK_IS_FP FALSE
62 
63 #define CPU_USE_DEFERRED_FP_SWITCH FALSE
64 
65 #define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
66 
67 /*
68  * Does the stack grow up (toward higher addresses) or down
69  * (toward lower addresses)?
70  *
71  * If TRUE, then the grows upward.
72  * If FALSE, then the grows toward smaller addresses.
73  *
74  * MOXIE Specific Information:
75  *
76  * XXX
77  */
78 #define CPU_STACK_GROWS_UP FALSE
79 
80 /* FIXME: Is this the right value? */
81 #define CPU_CACHE_LINE_BYTES 32
82 
83 #define CPU_STRUCTURE_ALIGNMENT
84 
85 /*
86  * The following defines the number of bits actually used in the
87  * interrupt field of the task mode. How those bits map to the
88  * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
89  *
90  * MOXIE Specific Information:
91  *
92  * XXX
93  */
94 #define CPU_MODES_INTERRUPT_MASK 0x00000001
95 
96 #define CPU_MAXIMUM_PROCESSORS 32
97 
98 /*
99  * Processor defined structures required for cpukit/score.
100  *
101  * MOXIE Specific Information:
102  *
103  * XXX
104  */
105 
106 /* may need to put some structures here. */
107 
108 /*
109  * Contexts
110  *
111  * Generally there are 2 types of context to save.
112  * 1. Interrupt registers to save
113  * 2. Task level registers to save
114  *
115  * This means we have the following 3 context items:
116  * 1. task level context stuff:: Context_Control
117  * 2. floating point task stuff:: Context_Control_fp
118  * 3. special interrupt level context :: Context_Control_interrupt
119  *
120  * On some processors, it is cost-effective to save only the callee
121  * preserved registers during a task context switch. This means
122  * that the ISR code needs to save those registers which do not
123  * persist across function calls. It is not mandatory to make this
124  * distinctions between the caller/callee saves registers for the
125  * purpose of minimizing context saved during task switch and on interrupts.
126  * If the cost of saving extra registers is minimal, simplicity is the
127  * choice. Save the same context on interrupt entry as for tasks in
128  * this case.
129  *
130  * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
131  * care should be used in designing the context area.
132  *
133  * On some CPUs with hardware floating point support, the Context_Control_fp
134  * structure will not be used or it simply consist of an array of a
135  * fixed number of bytes. This is done when the floating point context
136  * is dumped by a "FP save context" type instruction and the format
137  * is not really defined by the CPU. In this case, there is no need
138  * to figure out the exact format -- only the size. Of course, although
139  * this is enough information for RTEMS, it is probably not enough for
140  * a debugger such as gdb. But that is another problem.
141  *
142  * MOXIE Specific Information:
143  *
144  * XXX
145  */
146 
147 #define nogap __attribute__ ((packed))
148 
149 typedef struct {
150  void *fp nogap;
151  void *sp nogap;
152  uint32_t r0 nogap;
153  uint32_t r1 nogap;
154  uint32_t r2 nogap;
155  uint32_t r3 nogap;
156  uint32_t r4 nogap;
157  uint32_t r5 nogap;
158  uint32_t r6 nogap;
159  uint32_t r7 nogap;
160  uint32_t r8 nogap;
161  uint32_t r9 nogap;
162  uint32_t r10 nogap;
163  uint32_t r11 nogap;
164  uint32_t r12 nogap;
165  uint32_t r13 nogap;
167 
168 #define _CPU_Context_Get_SP( _context ) \
169  (_context)->sp
170 
171 typedef struct {
174 
175 /*
176  * Amount of extra stack (above minimum stack size) required by
177  * system initialization thread. Remember that in a multiprocessor
178  * system the system intialization thread becomes the MP server thread.
179  *
180  * MOXIE Specific Information:
181  *
182  * It is highly unlikely the MOXIE will get used in a multiprocessor system.
183  */
184 #define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
185 
186 /*
187  * This defines the number of entries in the ISR_Vector_table managed
188  * by RTEMS.
189  *
190  * MOXIE Specific Information:
191  *
192  * XXX
193  */
194 #define CPU_INTERRUPT_NUMBER_OF_VECTORS 64
195 #define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER \
196  (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
197 
198 /*
199  * This is defined if the port has a special way to report the ISR nesting
200  * level. Most ports maintain the variable _ISR_Nest_level.
201  */
202 #define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
203 
204 /*
205  * Should be large enough to run all RTEMS tests. This ensures
206  * that a "reasonable" small application should not have any problems.
207  *
208  * MOXIE Specific Information:
209  *
210  * XXX
211  */
212 #define CPU_STACK_MINIMUM_SIZE (1536)
213 
221 #define CPU_SIZEOF_POINTER 4
222 
223 /*
224  * CPU's worst alignment requirement for data types on a byte boundary. This
225  * alignment does not take into account the requirements for the stack.
226  *
227  * MOXIE Specific Information:
228  *
229  * XXX
230  */
231 #define CPU_ALIGNMENT 8
232 
233 /*
234  * This number corresponds to the byte alignment requirement for the
235  * heap handler. This alignment requirement may be stricter than that
236  * for the data types alignment specified by CPU_ALIGNMENT. It is
237  * common for the heap to follow the same alignment requirement as
238  * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
239  * then this should be set to CPU_ALIGNMENT.
240  *
241  * NOTE: This does not have to be a power of 2. It does have to
242  * be greater or equal to than CPU_ALIGNMENT.
243  *
244  * MOXIE Specific Information:
245  *
246  * XXX
247  */
248 #define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
249 
250 /*
251  * This number corresponds to the byte alignment requirement for the
252  * stack. This alignment requirement may be stricter than that for the
253  * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
254  * is strict enough for the stack, then this should be set to 0.
255  *
256  * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
257  *
258  * MOXIE Specific Information:
259  *
260  * XXX
261  */
262 #define CPU_STACK_ALIGNMENT 0
263 
264 #define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES
265 
266 /*
267  * ISR handler macros
268  */
269 
270 /*
271  * Support routine to initialize the RTEMS vector table after it is allocated.
272  */
273 #define _CPU_Initialize_vectors()
274 
275 /*
276  * Disable all interrupts for an RTEMS critical section. The previous
277  * level is returned in _level.
278  *
279  * MOXIE Specific Information:
280  *
281  * TODO: As of 7 October 2014, this method is not implemented.
282  */
283 #define _CPU_ISR_Disable( _isr_cookie ) \
284  do { \
285  (_isr_cookie) = 0; \
286  } while (0)
287 
288 /*
289  * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
290  * This indicates the end of an RTEMS critical section. The parameter
291  * _level is not modified.
292  *
293  * MOXIE Specific Information:
294  *
295  * TODO: As of 7 October 2014, this method is not implemented.
296  */
297 #define _CPU_ISR_Enable( _isr_cookie ) \
298  do { \
299  (_isr_cookie) = (_isr_cookie); \
300  } while (0)
301 
302 /*
303  * This temporarily restores the interrupt to _level before immediately
304  * disabling them again. This is used to divide long RTEMS critical
305  * sections into two or more parts. The parameter _level is not
306  * modified.
307  *
308  * MOXIE Specific Information:
309  *
310  * TODO: As of 7 October 2014, this method is not implemented.
311  */
312 #define _CPU_ISR_Flash( _isr_cookie ) \
313  do { \
314  _CPU_ISR_Enable( _isr_cookie ); \
315  _CPU_ISR_Disable( _isr_cookie ); \
316  } while (0)
317 
318 RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint32_t level )
319 {
320  return true;
321 }
322 
323 /*
324  * Map interrupt level in task mode onto the hardware that the CPU
325  * actually provides. Currently, interrupt levels which do not
326  * map onto the CPU in a generic fashion are undefined. Someday,
327  * it would be nice if these were "mapped" by the application
328  * via a callout. For example, m68k has 8 levels 0 - 7, levels
329  * 8 - 255 would be available for bsp/application specific meaning.
330  * This could be used to manage a programmable interrupt controller
331  * via the rtems_task_mode directive.
332  *
333  * MOXIE Specific Information:
334  *
335  * TODO: As of 7 October 2014, this method is not implemented.
336  */
337 #define _CPU_ISR_Set_level( _new_level ) \
338  { \
339  if (_new_level) asm volatile ( "nop\n" ); \
340  else asm volatile ( "nop\n" ); \
341  }
342 
343 uint32_t _CPU_ISR_Get_level( void );
344 
345 /* end of ISR handler macros */
346 
347 /* Context handler macros */
348 
349 /*
350  * Initialize the context to a state suitable for starting a
351  * task after a context restore operation. Generally, this
352  * involves:
353  *
354  * - setting a starting address
355  * - preparing the stack
356  * - preparing the stack and frame pointers
357  * - setting the proper interrupt level in the context
358  * - initializing the floating point context
359  *
360  * This routine generally does not set any unnecessary register
361  * in the context. The state of the "general data" registers is
362  * undefined at task start time.
363  *
364  * NOTE: This is_fp parameter is TRUE if the thread is to be a floating
365  * point thread. This is typically only used on CPUs where the
366  * FPU may be easily disabled by software such as on the SPARC
367  * where the PSR contains an enable FPU bit.
368  *
369  * MOXIE Specific Information:
370  *
371  * TODO: As of 7 October 2014, this method does not ensure that the context
372  * is set up with interrupts disabled/enabled as requested.
373  */
374 #define CPU_CCR_INTERRUPTS_ON 0x80
375 #define CPU_CCR_INTERRUPTS_OFF 0x00
376 
377 #define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
378  _isr, _entry_point, _is_fp, _tls_area ) \
379  /* Locate Me */ \
380  do { \
381  uintptr_t _stack; \
382  \
383  (void) _is_fp; /* avoid warning for being unused */ \
384  (void) _isr; /* avoid warning for being unused */ \
385  _stack = ((uintptr_t)(_stack_base)) + (_size) - 8; \
386  *((void (**)(void))(_stack)) = (_entry_point); \
387  _stack -= 4; \
388  (_the_context)->fp = (void *)_stack; \
389  (_the_context)->sp = (void *)_stack; \
390  } while (0)
391 
392 
393 /*
394  * This routine is responsible for somehow restarting the currently
395  * executing task. If you are lucky, then all that is necessary
396  * is restoring the context. Otherwise, there will need to be
397  * a special assembly routine which does something special in this
398  * case. Context_Restore should work most of the time. It will
399  * not work if restarting self conflicts with the stack frame
400  * assumptions of restoring a context.
401  *
402  * MOXIE Specific Information:
403  *
404  * XXX
405  */
406 #define _CPU_Context_Restart_self( _the_context ) \
407  _CPU_Context_restore( (_the_context) );
408 
409 /* end of Context handler macros */
410 
411 /* Fatal Error manager macros */
412 
413 /*
414  * This routine copies _error into a known place -- typically a stack
415  * location or a register, optionally disables interrupts, and
416  * halts/stops the CPU.
417  *
418  * MOXIE Specific Information:
419  *
420  * XXX
421  */
422 #define _CPU_Fatal_halt( _source, _error ) \
423  printk("Fatal Error %d.%lu Halted\n",_source,_error); \
424  for(;;)
425 
426 /* end of Fatal Error manager macros */
427 
428 #define CPU_USE_GENERIC_BITFIELD_CODE TRUE
429 
430 /* functions */
431 
432 /*
433  * _CPU_Initialize
434  *
435  * This routine performs CPU dependent initialization.
436  *
437  * MOXIE Specific Information:
438  *
439  * XXX
440  */
441 void _CPU_Initialize(void);
442 
443 typedef void ( *CPU_ISR_handler )( uint32_t );
444 
446  uint32_t vector,
447  CPU_ISR_handler new_handler,
448  CPU_ISR_handler *old_handler
449 );
450 
451 void *_CPU_Thread_Idle_body( uintptr_t );
452 
453 /*
454  * _CPU_Context_switch
455  *
456  * This routine switches from the run context to the heir context.
457  *
458  * MOXIE Specific Information:
459  *
460  * XXX
461  */
463  Context_Control *run,
464  Context_Control *heir
465 );
466 
467 /*
468  * _CPU_Context_restore
469  *
470  * This routine is generallu used only to restart self in an
471  * efficient manner. It may simply be a label in _CPU_Context_switch.
472  *
473  * NOTE: May be unnecessary to reload some registers.
474  *
475  * MOXIE Specific Information:
476  *
477  * XXX
478  */
480  Context_Control *new_context
482 
492 typedef struct {
493  uint32_t integer_registers [16];
495 
502 
503 /* The following routine swaps the endian format of an unsigned int.
504  * It must be static because it is referenced indirectly.
505  *
506  * This version will work on any processor, but if there is a better
507  * way for your CPU PLEASE use it. The most common way to do this is to:
508  *
509  * swap least significant two bytes with 16-bit rotate
510  * swap upper and lower 16-bits
511  * swap most significant two bytes with 16-bit rotate
512  *
513  * Some CPUs have special instructions which swap a 32-bit quantity in
514  * a single instruction (e.g. i486). It is probably best to avoid
515  * an "endian swapping control bit" in the CPU. One good reason is
516  * that interrupts would probably have to be disabled to ensure that
517  * an interrupt does not try to access the same "chunk" with the wrong
518  * endian. Another good reason is that on some CPUs, the endian bit
519  * endianness for ALL fetches -- both code and data -- so the code
520  * will be fetched incorrectly.
521  *
522  * MOXIE Specific Information:
523  *
524  * This is the generic implementation.
525  */
526 static inline uint32_t CPU_swap_u32(
527  uint32_t value
528 )
529 {
530  uint32_t byte1, byte2, byte3, byte4, swapped;
531 
532  byte4 = (value >> 24) & 0xff;
533  byte3 = (value >> 16) & 0xff;
534  byte2 = (value >> 8) & 0xff;
535  byte1 = value & 0xff;
536 
537  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
538  return( swapped );
539 }
540 
541 #define CPU_swap_u16( value ) \
542  (((value&0xff) << 8) | ((value >> 8)&0xff))
543 
544 typedef uint32_t CPU_Counter_ticks;
545 
546 uint32_t _CPU_Counter_frequency( void );
547 
548 CPU_Counter_ticks _CPU_Counter_read( void );
549 
550 static inline CPU_Counter_ticks _CPU_Counter_difference(
551  CPU_Counter_ticks second,
552  CPU_Counter_ticks first
553 )
554 {
555  return second - first;
556 }
557 
559 typedef uintptr_t CPU_Uint32ptr;
560 
561 #ifdef __cplusplus
562 }
563 #endif
564 
565 #endif
#define sp
stack-pointer */
Definition: regs.h:64
void _CPU_Exception_frame_print(const CPU_Exception_frame *frame)
Prints the exception frame via printk().
Definition: vectorexceptions.c:45
CPU_Counter_ticks _CPU_Counter_read(void)
Returns the current CPU counter value.
Definition: system-clocks.c:117
Thread register context.
Definition: cpu.h:194
void * _CPU_Thread_Idle_body(uintptr_t ignored)
Definition: idle-mcf5272.c:20
Interrupt stack frame (ISF).
Definition: cpu.h:191
#define RTEMS_NO_RETURN
Definition: basedefs.h:102
#define fp
frame-pointer */
Definition: regs.h:65
void _CPU_Context_switch(Context_Control *run, Context_Control *heir)
CPU switch context.
Definition: cpu_asm.c:91
uint32_t special_interrupt_register
Definition: cpu.h:172
void _CPU_Initialize(void)
CPU initialization.
Definition: cpu.c:45
uint32_t CPU_Counter_ticks
Unsigned integer type for CPU counter values.
Definition: cpu.h:1210
Interface to Kernel Print Methods.
uint32_t _CPU_ISR_Get_level(void)
Definition: cpu.c:88
bool _CPU_ISR_Is_enabled(uint32_t level)
Returns true if interrupts are enabled in the specified ISR level, otherwise returns false.
Definition: cpu.h:375
void _CPU_Context_restore(Context_Control *new_context) RTEMS_NO_RETURN
Definition: cpu_asm.c:111
uintptr_t CPU_Uint32ptr
Definition: cpu.h:662
uint32_t _CPU_Counter_frequency(void)
Returns the current CPU counter frequency in Hz.
Definition: system-clocks.c:112
Basic Definitions.
RTEMS_INLINE_ROUTINE void _CPU_ISR_install_vector(uint32_t vector, CPU_ISR_handler new_handler, CPU_ISR_handler *old_handler)
SPARC specific RTEMS ISR installer.
Definition: cpu.h:493
The set of registers that specifies the complete processor state.
Definition: cpu.h:629
#define RTEMS_INLINE_ROUTINE
Definition: basedefs.h:66