RTEMS  5.0.0
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 /*
56  * Does the CPU have hardware floating point?
57  *
58  * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
59  * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
60  *
61  * If there is a FP coprocessor such as the i387 or mc68881, then
62  * the answer is TRUE.
63  *
64  * The macro name "MOXIE_HAS_FPU" should be made CPU specific.
65  * It indicates whether or not this CPU model has FP support. For
66  * example, it would be possible to have an i386_nofp CPU model
67  * which set this to false to indicate that you have an i386 without
68  * an i387 and wish to leave floating point support out of RTEMS.
69  *
70  * MOXIE Specific Information:
71  *
72  * XXX
73  */
74 #define CPU_HARDWARE_FP FALSE
75 
76 /*
77  * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
78  *
79  * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
80  * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
81  *
82  * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
83  *
84  * MOXIE Specific Information:
85  *
86  * XXX
87  */
88 #define CPU_ALL_TASKS_ARE_FP FALSE
89 
90 /*
91  * Should the IDLE task have a floating point context?
92  *
93  * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
94  * and it has a floating point context which is switched in and out.
95  * If FALSE, then the IDLE task does not have a floating point context.
96  *
97  * Setting this to TRUE negatively impacts the time required to preempt
98  * the IDLE task from an interrupt because the floating point context
99  * must be saved as part of the preemption.
100  *
101  * MOXIE Specific Information:
102  *
103  * XXX
104  */
105 #define CPU_IDLE_TASK_IS_FP FALSE
106 
107 /*
108  * Should the saving of the floating point registers be deferred
109  * until a context switch is made to another different floating point
110  * task?
111  *
112  * If TRUE, then the floating point context will not be stored until
113  * necessary. It will remain in the floating point registers and not
114  * disturned until another floating point task is switched to.
115  *
116  * If FALSE, then the floating point context is saved when a floating
117  * point task is switched out and restored when the next floating point
118  * task is restored. The state of the floating point registers between
119  * those two operations is not specified.
120  *
121  * If the floating point context does NOT have to be saved as part of
122  * interrupt dispatching, then it should be safe to set this to TRUE.
123  *
124  * Setting this flag to TRUE results in using a different algorithm
125  * for deciding when to save and restore the floating point context.
126  * The deferred FP switch algorithm minimizes the number of times
127  * the FP context is saved and restored. The FP context is not saved
128  * until a context switch is made to another, different FP task.
129  * Thus in a system with only one FP task, the FP context will never
130  * be saved or restored.
131  *
132  * MOXIE Specific Information:
133  *
134  * XXX
135  */
136 #define CPU_USE_DEFERRED_FP_SWITCH TRUE
137 
138 #define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
139 
140 /*
141  * Does the stack grow up (toward higher addresses) or down
142  * (toward lower addresses)?
143  *
144  * If TRUE, then the grows upward.
145  * If FALSE, then the grows toward smaller addresses.
146  *
147  * MOXIE Specific Information:
148  *
149  * XXX
150  */
151 #define CPU_STACK_GROWS_UP FALSE
152 
153 /* FIXME: Is this the right value? */
154 #define CPU_CACHE_LINE_BYTES 32
155 
156 #define CPU_STRUCTURE_ALIGNMENT
157 
158 /*
159  * The following defines the number of bits actually used in the
160  * interrupt field of the task mode. How those bits map to the
161  * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
162  *
163  * MOXIE Specific Information:
164  *
165  * XXX
166  */
167 #define CPU_MODES_INTERRUPT_MASK 0x00000001
168 
169 #define CPU_MAXIMUM_PROCESSORS 32
170 
171 /*
172  * Processor defined structures required for cpukit/score.
173  *
174  * MOXIE Specific Information:
175  *
176  * XXX
177  */
178 
179 /* may need to put some structures here. */
180 
181 /*
182  * Contexts
183  *
184  * Generally there are 2 types of context to save.
185  * 1. Interrupt registers to save
186  * 2. Task level registers to save
187  *
188  * This means we have the following 3 context items:
189  * 1. task level context stuff:: Context_Control
190  * 2. floating point task stuff:: Context_Control_fp
191  * 3. special interrupt level context :: Context_Control_interrupt
192  *
193  * On some processors, it is cost-effective to save only the callee
194  * preserved registers during a task context switch. This means
195  * that the ISR code needs to save those registers which do not
196  * persist across function calls. It is not mandatory to make this
197  * distinctions between the caller/callee saves registers for the
198  * purpose of minimizing context saved during task switch and on interrupts.
199  * If the cost of saving extra registers is minimal, simplicity is the
200  * choice. Save the same context on interrupt entry as for tasks in
201  * this case.
202  *
203  * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
204  * care should be used in designing the context area.
205  *
206  * On some CPUs with hardware floating point support, the Context_Control_fp
207  * structure will not be used or it simply consist of an array of a
208  * fixed number of bytes. This is done when the floating point context
209  * is dumped by a "FP save context" type instruction and the format
210  * is not really defined by the CPU. In this case, there is no need
211  * to figure out the exact format -- only the size. Of course, although
212  * this is enough information for RTEMS, it is probably not enough for
213  * a debugger such as gdb. But that is another problem.
214  *
215  * MOXIE Specific Information:
216  *
217  * XXX
218  */
219 
220 #define nogap __attribute__ ((packed))
221 
222 typedef struct {
223  void *fp nogap;
224  void *sp nogap;
225  uint32_t r0 nogap;
226  uint32_t r1 nogap;
227  uint32_t r2 nogap;
228  uint32_t r3 nogap;
229  uint32_t r4 nogap;
230  uint32_t r5 nogap;
231  uint32_t r6 nogap;
232  uint32_t r7 nogap;
233  uint32_t r8 nogap;
234  uint32_t r9 nogap;
235  uint32_t r10 nogap;
236  uint32_t r11 nogap;
237  uint32_t r12 nogap;
238  uint32_t r13 nogap;
240 
241 #define _CPU_Context_Get_SP( _context ) \
242  (_context)->sp
243 
244 typedef struct {
245  double some_float_register[2];
247 
248 typedef struct {
251 
252 /*
253  * Nothing prevents the porter from declaring more CPU specific variables.
254  *
255  * MOXIE Specific Information:
256  *
257  * XXX
258  */
259 
260 /*
261  * The size of the floating point context area. On some CPUs this
262  * will not be a "sizeof" because the format of the floating point
263  * area is not defined -- only the size is. This is usually on
264  * CPUs with a "floating point save context" instruction.
265  *
266  * MOXIE Specific Information:
267  *
268  * XXX
269  */
270 #define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
271 
272 /*
273  * Amount of extra stack (above minimum stack size) required by
274  * system initialization thread. Remember that in a multiprocessor
275  * system the system intialization thread becomes the MP server thread.
276  *
277  * MOXIE Specific Information:
278  *
279  * It is highly unlikely the MOXIE will get used in a multiprocessor system.
280  */
281 #define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
282 
283 /*
284  * This defines the number of entries in the ISR_Vector_table managed
285  * by RTEMS.
286  *
287  * MOXIE Specific Information:
288  *
289  * XXX
290  */
291 #define CPU_INTERRUPT_NUMBER_OF_VECTORS 64
292 #define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER \
293  (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
294 
295 /*
296  * This is defined if the port has a special way to report the ISR nesting
297  * level. Most ports maintain the variable _ISR_Nest_level.
298  */
299 #define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
300 
301 /*
302  * Should be large enough to run all RTEMS tests. This ensures
303  * that a "reasonable" small application should not have any problems.
304  *
305  * MOXIE Specific Information:
306  *
307  * XXX
308  */
309 #define CPU_STACK_MINIMUM_SIZE (1536)
310 
318 #define CPU_SIZEOF_POINTER 4
319 
320 /*
321  * CPU's worst alignment requirement for data types on a byte boundary. This
322  * alignment does not take into account the requirements for the stack.
323  *
324  * MOXIE Specific Information:
325  *
326  * XXX
327  */
328 #define CPU_ALIGNMENT 8
329 
330 /*
331  * This number corresponds to the byte alignment requirement for the
332  * heap handler. This alignment requirement may be stricter than that
333  * for the data types alignment specified by CPU_ALIGNMENT. It is
334  * common for the heap to follow the same alignment requirement as
335  * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
336  * then this should be set to CPU_ALIGNMENT.
337  *
338  * NOTE: This does not have to be a power of 2. It does have to
339  * be greater or equal to than CPU_ALIGNMENT.
340  *
341  * MOXIE Specific Information:
342  *
343  * XXX
344  */
345 #define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
346 
347 /*
348  * This number corresponds to the byte alignment requirement for the
349  * stack. This alignment requirement may be stricter than that for the
350  * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
351  * is strict enough for the stack, then this should be set to 0.
352  *
353  * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
354  *
355  * MOXIE Specific Information:
356  *
357  * XXX
358  */
359 #define CPU_STACK_ALIGNMENT 0
360 
361 #define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES
362 
363 /*
364  * ISR handler macros
365  */
366 
367 /*
368  * Support routine to initialize the RTEMS vector table after it is allocated.
369  */
370 #define _CPU_Initialize_vectors()
371 
372 /*
373  * Disable all interrupts for an RTEMS critical section. The previous
374  * level is returned in _level.
375  *
376  * MOXIE Specific Information:
377  *
378  * TODO: As of 7 October 2014, this method is not implemented.
379  */
380 #define _CPU_ISR_Disable( _isr_cookie ) \
381  do { \
382  (_isr_cookie) = 0; \
383  } while (0)
384 
385 /*
386  * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
387  * This indicates the end of an RTEMS critical section. The parameter
388  * _level is not modified.
389  *
390  * MOXIE Specific Information:
391  *
392  * TODO: As of 7 October 2014, this method is not implemented.
393  */
394 #define _CPU_ISR_Enable( _isr_cookie ) \
395  do { \
396  (_isr_cookie) = (_isr_cookie); \
397  } while (0)
398 
399 /*
400  * This temporarily restores the interrupt to _level before immediately
401  * disabling them again. This is used to divide long RTEMS critical
402  * sections into two or more parts. The parameter _level is not
403  * modified.
404  *
405  * MOXIE Specific Information:
406  *
407  * TODO: As of 7 October 2014, this method is not implemented.
408  */
409 #define _CPU_ISR_Flash( _isr_cookie ) \
410  do { \
411  _CPU_ISR_Enable( _isr_cookie ); \
412  _CPU_ISR_Disable( _isr_cookie ); \
413  } while (0)
414 
415 RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint32_t level )
416 {
417  return true;
418 }
419 
420 /*
421  * Map interrupt level in task mode onto the hardware that the CPU
422  * actually provides. Currently, interrupt levels which do not
423  * map onto the CPU in a generic fashion are undefined. Someday,
424  * it would be nice if these were "mapped" by the application
425  * via a callout. For example, m68k has 8 levels 0 - 7, levels
426  * 8 - 255 would be available for bsp/application specific meaning.
427  * This could be used to manage a programmable interrupt controller
428  * via the rtems_task_mode directive.
429  *
430  * MOXIE Specific Information:
431  *
432  * TODO: As of 7 October 2014, this method is not implemented.
433  */
434 #define _CPU_ISR_Set_level( _new_level ) \
435  { \
436  if (_new_level) asm volatile ( "nop\n" ); \
437  else asm volatile ( "nop\n" ); \
438  }
439 
440 uint32_t _CPU_ISR_Get_level( void );
441 
442 /* end of ISR handler macros */
443 
444 /* Context handler macros */
445 
446 /*
447  * Initialize the context to a state suitable for starting a
448  * task after a context restore operation. Generally, this
449  * involves:
450  *
451  * - setting a starting address
452  * - preparing the stack
453  * - preparing the stack and frame pointers
454  * - setting the proper interrupt level in the context
455  * - initializing the floating point context
456  *
457  * This routine generally does not set any unnecessary register
458  * in the context. The state of the "general data" registers is
459  * undefined at task start time.
460  *
461  * NOTE: This is_fp parameter is TRUE if the thread is to be a floating
462  * point thread. This is typically only used on CPUs where the
463  * FPU may be easily disabled by software such as on the SPARC
464  * where the PSR contains an enable FPU bit.
465  *
466  * MOXIE Specific Information:
467  *
468  * TODO: As of 7 October 2014, this method does not ensure that the context
469  * is set up with interrupts disabled/enabled as requested.
470  */
471 #define CPU_CCR_INTERRUPTS_ON 0x80
472 #define CPU_CCR_INTERRUPTS_OFF 0x00
473 
474 #define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
475  _isr, _entry_point, _is_fp, _tls_area ) \
476  /* Locate Me */ \
477  do { \
478  uintptr_t _stack; \
479  \
480  (void) _is_fp; /* avoid warning for being unused */ \
481  (void) _isr; /* avoid warning for being unused */ \
482  _stack = ((uintptr_t)(_stack_base)) + (_size) - 8; \
483  *((void (**)(void))(_stack)) = (_entry_point); \
484  _stack -= 4; \
485  (_the_context)->fp = (void *)_stack; \
486  (_the_context)->sp = (void *)_stack; \
487  } while (0)
488 
489 
490 /*
491  * This routine is responsible for somehow restarting the currently
492  * executing task. If you are lucky, then all that is necessary
493  * is restoring the context. Otherwise, there will need to be
494  * a special assembly routine which does something special in this
495  * case. Context_Restore should work most of the time. It will
496  * not work if restarting self conflicts with the stack frame
497  * assumptions of restoring a context.
498  *
499  * MOXIE Specific Information:
500  *
501  * XXX
502  */
503 #define _CPU_Context_Restart_self( _the_context ) \
504  _CPU_Context_restore( (_the_context) );
505 
506 #define _CPU_Context_Initialize_fp( _destination ) \
507  memset( *( _destination ), 0, CPU_CONTEXT_FP_SIZE );
508 
509 /* end of Context handler macros */
510 
511 /* Fatal Error manager macros */
512 
513 /*
514  * This routine copies _error into a known place -- typically a stack
515  * location or a register, optionally disables interrupts, and
516  * halts/stops the CPU.
517  *
518  * MOXIE Specific Information:
519  *
520  * XXX
521  */
522 #define _CPU_Fatal_halt( _source, _error ) \
523  printk("Fatal Error %d.%lu Halted\n",_source,_error); \
524  for(;;)
525 
526 /* end of Fatal Error manager macros */
527 
528 #define CPU_USE_GENERIC_BITFIELD_CODE TRUE
529 
530 /* functions */
531 
532 /*
533  * _CPU_Initialize
534  *
535  * This routine performs CPU dependent initialization.
536  *
537  * MOXIE Specific Information:
538  *
539  * XXX
540  */
541 void _CPU_Initialize(void);
542 
543 typedef void ( *CPU_ISR_handler )( uint32_t );
544 
546  uint32_t vector,
547  CPU_ISR_handler new_handler,
548  CPU_ISR_handler *old_handler
549 );
550 
551 void *_CPU_Thread_Idle_body( uintptr_t );
552 
553 /*
554  * _CPU_Context_switch
555  *
556  * This routine switches from the run context to the heir context.
557  *
558  * MOXIE Specific Information:
559  *
560  * XXX
561  */
563  Context_Control *run,
564  Context_Control *heir
565 );
566 
567 /*
568  * _CPU_Context_restore
569  *
570  * This routine is generallu used only to restart self in an
571  * efficient manner. It may simply be a label in _CPU_Context_switch.
572  *
573  * NOTE: May be unnecessary to reload some registers.
574  *
575  * MOXIE Specific Information:
576  *
577  * XXX
578  */
580  Context_Control *new_context
582 
583 /*
584  * _CPU_Context_save_fp
585  *
586  * This routine saves the floating point context passed to it.
587  *
588  * MOXIE Specific Information:
589  *
590  * XXX
591  */
593  Context_Control_fp **fp_context_ptr
594 );
595 
596 /*
597  * _CPU_Context_restore_fp
598  *
599  * This routine restores the floating point context passed to it.
600  *
601  * MOXIE Specific Information:
602  *
603  * XXX
604  */
606  Context_Control_fp **fp_context_ptr
607 );
608 
618 typedef struct {
619  uint32_t integer_registers [16];
621 
628 
629 /* The following routine swaps the endian format of an unsigned int.
630  * It must be static because it is referenced indirectly.
631  *
632  * This version will work on any processor, but if there is a better
633  * way for your CPU PLEASE use it. The most common way to do this is to:
634  *
635  * swap least significant two bytes with 16-bit rotate
636  * swap upper and lower 16-bits
637  * swap most significant two bytes with 16-bit rotate
638  *
639  * Some CPUs have special instructions which swap a 32-bit quantity in
640  * a single instruction (e.g. i486). It is probably best to avoid
641  * an "endian swapping control bit" in the CPU. One good reason is
642  * that interrupts would probably have to be disabled to ensure that
643  * an interrupt does not try to access the same "chunk" with the wrong
644  * endian. Another good reason is that on some CPUs, the endian bit
645  * endianness for ALL fetches -- both code and data -- so the code
646  * will be fetched incorrectly.
647  *
648  * MOXIE Specific Information:
649  *
650  * This is the generic implementation.
651  */
652 static inline uint32_t CPU_swap_u32(
653  uint32_t value
654 )
655 {
656  uint32_t byte1, byte2, byte3, byte4, swapped;
657 
658  byte4 = (value >> 24) & 0xff;
659  byte3 = (value >> 16) & 0xff;
660  byte2 = (value >> 8) & 0xff;
661  byte1 = value & 0xff;
662 
663  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
664  return( swapped );
665 }
666 
667 #define CPU_swap_u16( value ) \
668  (((value&0xff) << 8) | ((value >> 8)&0xff))
669 
670 typedef uint32_t CPU_Counter_ticks;
671 
672 uint32_t _CPU_Counter_frequency( void );
673 
674 CPU_Counter_ticks _CPU_Counter_read( void );
675 
676 static inline CPU_Counter_ticks _CPU_Counter_difference(
677  CPU_Counter_ticks second,
678  CPU_Counter_ticks first
679 )
680 {
681  return second - first;
682 }
683 
685 typedef uintptr_t CPU_Uint32ptr;
686 
687 #ifdef __cplusplus
688 }
689 #endif
690 
691 #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:196
void * _CPU_Thread_Idle_body(uintptr_t ignored)
Definition: idle-mcf5272.c:20
#define RTEMS_INLINE_ROUTINE
Definition: basedefs.h:65
void _CPU_Context_restore_fp(Context_Control_fp **fp_context_ptr)
Definition: cpu.c:207
Interrupt stack frame (ISF).
Definition: cpu.h:306
#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:249
void _CPU_Initialize(void)
CPU initialization.
Definition: cpu.c:45
SPARC basic context.
Definition: cpu.h:242
uint32_t CPU_Counter_ticks
Unsigned integer type for CPU counter values.
Definition: cpu.h:1202
#define RTEMS_NO_RETURN
Definition: basedefs.h:101
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:381
void _CPU_Context_restore(Context_Control *new_context) RTEMS_NO_RETURN
Definition: cpu_asm.c:111
uintptr_t CPU_Uint32ptr
Definition: cpu.h:668
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:605
void _CPU_Context_save_fp(Context_Control_fp **fp_context_ptr)
Definition: cpu.c:198
The set of registers that specifies the complete processor state.
Definition: cpu.h:635