RTEMS  5.1
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
cpu.h
Go to the documentation of this file.
1 
7 /*
8  * This include file contains macros pertaining to the Opencores
9  * or1k processor family.
10  *
11  * COPYRIGHT (c) 2014 Hesham ALMatary <heshamelmatary@gmail.com>
12  * COPYRIGHT (c) 1989-1999.
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  * This file adapted from no_cpu example of the RTEMS distribution.
20  * The body has been modified for the Opencores OR1k implementation by
21  * Chris Ziomkowski. <chris@asics.ws>
22  *
23  */
24 
25 #ifndef _OR1K_CPU_H
26 #define _OR1K_CPU_H
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 
33 #include <rtems/score/or1k.h> /* pick up machine definitions */
35 #include <rtems/score/basedefs.h>
36 #ifndef ASM
37 #include <rtems/bspIo.h>
38 #include <stdint.h>
39 #include <stdio.h> /* for printk */
40 #endif
41 
42 /* conditional compilation parameters */
43 
44 /*
45  * Does the RTEMS invoke the user's ISR with the vector number and
46  * a pointer to the saved interrupt frame (1) or just the vector
47  * number (0)?
48  *
49  */
50 
51 #define CPU_ISR_PASSES_FRAME_POINTER TRUE
52 
53 #define CPU_HARDWARE_FP FALSE
54 
55 #define CPU_SOFTWARE_FP FALSE
56 
57 #define CPU_ALL_TASKS_ARE_FP FALSE
58 
59 #define CPU_IDLE_TASK_IS_FP FALSE
60 
61 #define CPU_USE_DEFERRED_FP_SWITCH TRUE
62 
63 #define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
64 
65 /*
66  * Does the stack grow up (toward higher addresses) or down
67  * (toward lower addresses)?
68  *
69  * If TRUE, then the grows upward.
70  * If FALSE, then the grows toward smaller addresses.
71  *
72  */
73 
74 #define CPU_STACK_GROWS_UP FALSE
75 
76 /* FIXME: Is this the right value? */
77 #define CPU_CACHE_LINE_BYTES 32
78 
79 #define CPU_STRUCTURE_ALIGNMENT RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES )
80 
81 /*
82  * The following defines the number of bits actually used in the
83  * interrupt field of the task mode. How those bits map to the
84  * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
85  *
86  */
87 
88 #define CPU_MODES_INTERRUPT_MASK 0x00000001
89 
90 /*
91  * Processor defined structures required for cpukit/score.
92  */
93 
94 
95 /*
96  * Contexts
97  *
98  * Generally there are 2 types of context to save.
99  * 1. Interrupt registers to save
100  * 2. Task level registers to save
101  *
102  * This means we have the following 3 context items:
103  * 1. task level context stuff:: Context_Control
104  * 2. floating point task stuff:: Context_Control_fp
105  * 3. special interrupt level context :: Context_Control_interrupt
106  *
107  * On some processors, it is cost-effective to save only the callee
108  * preserved registers during a task context switch. This means
109  * that the ISR code needs to save those registers which do not
110  * persist across function calls. It is not mandatory to make this
111  * distinctions between the caller/callee saves registers for the
112  * purpose of minimizing context saved during task switch and on interrupts.
113  * If the cost of saving extra registers is minimal, simplicity is the
114  * choice. Save the same context on interrupt entry as for tasks in
115  * this case.
116  *
117  * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
118  * care should be used in designing the context area.
119  *
120  * On some CPUs with hardware floating point support, the Context_Control_fp
121  * structure will not be used or it simply consist of an array of a
122  * fixed number of bytes. This is done when the floating point context
123  * is dumped by a "FP save context" type instruction and the format
124  * is not really defined by the CPU. In this case, there is no need
125  * to figure out the exact format -- only the size. Of course, although
126  * this is enough information for RTEMS, it is probably not enough for
127  * a debugger such as gdb. But that is another problem.
128  *
129  *
130  */
131 #ifndef ASM
132 #ifdef OR1K_64BIT_ARCH
133 #define or1kreg uint64_t
134 #else
135 #define or1kreg uint32_t
136 #endif
137 
138 typedef struct {
139  uint32_t r1; /* Stack pointer */
140  uint32_t r2; /* Frame pointer */
141  uint32_t r3;
142  uint32_t r4;
143  uint32_t r5;
144  uint32_t r6;
145  uint32_t r7;
146  uint32_t r8;
147  uint32_t r9;
148  uint32_t r10;
149  uint32_t r11;
150  uint32_t r12;
151  uint32_t r13;
152  uint32_t r14;
153  uint32_t r15;
154  uint32_t r16;
155  uint32_t r17;
156  uint32_t r18;
157  uint32_t r19;
158  uint32_t r20;
159  uint32_t r21;
160  uint32_t r22;
161  uint32_t r23;
162  uint32_t r24;
163  uint32_t r25;
164  uint32_t r26;
165  uint32_t r27;
166  uint32_t r28;
167  uint32_t r29;
168  uint32_t r30;
169  uint32_t r31;
170 
171  uint32_t sr; /* Current supervision register non persistent values */
172  uint32_t epcr;
173  uint32_t eear;
174  uint32_t esr;
176 
177 #define _CPU_Context_Get_SP( _context ) \
178  (_context)->r1
179 
181 
182 /*
183  * Amount of extra stack (above minimum stack size) required by
184  * MPCI receive server thread. Remember that in a multiprocessor
185  * system this thread must exist and be able to process all directives.
186  *
187  */
188 
189 #define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
190 
191 /*
192  * Should be large enough to run all RTEMS tests. This insures
193  * that a "reasonable" small application should not have any problems.
194  *
195  */
196 
197 #define CPU_STACK_MINIMUM_SIZE 4096
198 
199 /*
200  * CPU's worst alignment requirement for data types on a byte boundary. This
201  * alignment does not take into account the requirements for the stack.
202  *
203  */
204 
205 #define CPU_ALIGNMENT 8
206 
207 /*
208  * This is defined if the port has a special way to report the ISR nesting
209  * level. Most ports maintain the variable _ISR_Nest_level.
210  */
211 #define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
212 
220 #define CPU_SIZEOF_POINTER 4
221 
222 /*
223  * This number corresponds to the byte alignment requirement for the
224  * heap handler. This alignment requirement may be stricter than that
225  * for the data types alignment specified by CPU_ALIGNMENT. It is
226  * common for the heap to follow the same alignment requirement as
227  * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
228  * then this should be set to CPU_ALIGNMENT.
229  *
230  * NOTE: This does not have to be a power of 2 although it should be
231  * a multiple of 2 greater than or equal to 2. The requirement
232  * to be a multiple of 2 is because the heap uses the least
233  * significant field of the front and back flags to indicate
234  * that a block is in use or free. So you do not want any odd
235  * length blocks really putting length data in that bit.
236  *
237  * On byte oriented architectures, CPU_HEAP_ALIGNMENT normally will
238  * have to be greater or equal to than CPU_ALIGNMENT to ensure that
239  * elements allocated from the heap meet all restrictions.
240  *
241  */
242 
243 #define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
244 
245 /*
246  * This number corresponds to the byte alignment requirement for the
247  * stack. This alignment requirement may be stricter than that for the
248  * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
249  * is strict enough for the stack, then this should be set to 0.
250  *
251  * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
252  *
253  */
254 
255 #define CPU_STACK_ALIGNMENT 0
256 
257 #define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES
258 
259 /* ISR handler macros */
260 
261 /*
262  * Support routine to initialize the RTEMS vector table after it is allocated.
263  *
264  * NO_CPU Specific Information:
265  *
266  * XXX document implementation including references if appropriate
267  */
268 
269 #define _CPU_Initialize_vectors()
270 
271 /*
272  * Disable all interrupts for an RTEMS critical section. The previous
273  * level is returned in _level.
274  *
275  */
276 
277 static inline uint32_t or1k_interrupt_disable( void )
278 {
279  uint32_t sr;
280  sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
281 
282  _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr & ~CPU_OR1K_SPR_SR_IEE));
283 
284  return sr;
285 }
286 
287 static inline void or1k_interrupt_enable(uint32_t level)
288 {
289  uint32_t sr;
290 
291  /* Enable interrupts and restore rs */
292  sr = level | CPU_OR1K_SPR_SR_IEE | CPU_OR1K_SPR_SR_TEE;
293  _OR1K_mtspr(CPU_OR1K_SPR_SR, sr);
294 
295 }
296 
297 #define _CPU_ISR_Disable( _level ) \
298  _level = or1k_interrupt_disable()
299 
300 
301 /*
302  * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
303  * This indicates the end of an RTEMS critical section. The parameter
304  * _level is not modified.
305  *
306  */
307 
308 #define _CPU_ISR_Enable( _level ) \
309  or1k_interrupt_enable( _level )
310 
311 /*
312  * This temporarily restores the interrupt to _level before immediately
313  * disabling them again. This is used to divide long RTEMS critical
314  * sections into two or more parts. The parameter _level is not
315  * modified.
316  *
317  */
318 
319 #define _CPU_ISR_Flash( _level ) \
320  do{ \
321  _CPU_ISR_Enable( _level ); \
322  _OR1K_mtspr(CPU_OR1K_SPR_SR, (_level & ~CPU_OR1K_SPR_SR_IEE)); \
323  } while(0)
324 
326 {
327  return ( level & CPU_OR1K_SPR_SR ) != 0;
328 }
329 
330 /*
331  * Map interrupt level in task mode onto the hardware that the CPU
332  * actually provides. Currently, interrupt levels which do not
333  * map onto the CPU in a generic fashion are undefined. Someday,
334  * it would be nice if these were "mapped" by the application
335  * via a callout. For example, m68k has 8 levels 0 - 7, levels
336  * 8 - 255 would be available for bsp/application specific meaning.
337  * This could be used to manage a programmable interrupt controller
338  * via the rtems_task_mode directive.
339  *
340  * The get routine usually must be implemented as a subroutine.
341  *
342  */
343 
344 void _CPU_ISR_Set_level( uint32_t level );
345 
346 uint32_t _CPU_ISR_Get_level( void );
347 
348 /* end of ISR handler macros */
349 
350 /* Context handler macros */
351 
352 #define OR1K_FAST_CONTEXT_SWITCH_ENABLED FALSE
353 /*
354  * Initialize the context to a state suitable for starting a
355  * task after a context restore operation. Generally, this
356  * involves:
357  *
358  * - setting a starting address
359  * - preparing the stack
360  * - preparing the stack and frame pointers
361  * - setting the proper interrupt level in the context
362  * - initializing the floating point context
363  *
364  * This routine generally does not set any unnecessary register
365  * in the context. The state of the "general data" registers is
366  * undefined at task start time.
367  *
368  * NOTE: This is_fp parameter is TRUE if the thread is to be a floating
369  * point thread. This is typically only used on CPUs where the
370  * FPU may be easily disabled by software such as on the SPARC
371  * where the PSR contains an enable FPU bit.
372  *
373  */
374 
394  void *stack_area_begin,
395  size_t stack_area_size,
396  uint32_t new_level,
397  void (*entry_point)( void ),
398  bool is_fp,
399  void *tls_area
400 );
401 
402 /*
403  * This routine is responsible for somehow restarting the currently
404  * executing task. If you are lucky, then all that is necessary
405  * is restoring the context. Otherwise, there will need to be
406  * a special assembly routine which does something special in this
407  * case. Context_Restore should work most of the time. It will
408  * not work if restarting self conflicts with the stack frame
409  * assumptions of restoring a context.
410  *
411  */
412 
413 #define _CPU_Context_Restart_self( _the_context ) \
414  _CPU_Context_restore( (_the_context) );
415 
416 /* end of Context handler macros */
417 
418 /* Fatal Error manager macros */
419 
420 /*
421  * This routine copies _error into a known place -- typically a stack
422  * location or a register, optionally disables interrupts, and
423  * halts/stops the CPU.
424  *
425  */
426 
427 #include <inttypes.h>
428 
429 #define _CPU_Fatal_halt(_source, _error ) \
430  printk("Fatal Error %d.%" PRId32 " Halted\n",_source, _error); \
431  _OR1KSIM_CPU_Halt(); \
432  for(;;)
433 
434 /* end of Fatal Error manager macros */
435 
436 #define CPU_USE_GENERIC_BITFIELD_CODE TRUE
437 
438 #endif /* ASM */
439 
440 #define CPU_SIZEOF_POINTER 4
441 
442 #define CPU_MAXIMUM_PROCESSORS 32
443 
444 #ifndef ASM
445 typedef struct {
446  uint32_t r[32];
447 
448  /* The following registers must be saved if we have
449  fast context switch disabled and nested interrupt
450  levels are enabled.
451  */
452 #if !OR1K_FAST_CONTEXT_SWITCH_ENABLED
453  uint32_t epcr; /* exception PC register */
454  uint32_t eear; /* exception effective address register */
455  uint32_t esr; /* exception supervision register */
456 #endif
457 
459 
466 
467 
468 /* end of Priority handler macros */
469 
470 /* functions */
471 
472 /*
473  * _CPU_Initialize
474  *
475  * This routine performs CPU dependent initialization.
476  *
477  */
478 
479 void _CPU_Initialize(
480  void
481 );
482 
483 typedef void ( *CPU_ISR_raw_handler )( uint32_t, CPU_Exception_frame * );
484 
486  uint32_t vector,
487  CPU_ISR_raw_handler new_handler,
488  CPU_ISR_raw_handler *old_handler
489 );
490 
491 typedef void ( *CPU_ISR_handler )( uint32_t );
492 
494  uint32_t vector,
495  CPU_ISR_handler new_handler,
496  CPU_ISR_handler *old_handler
497 )
498 {
500  vector,
501  (CPU_ISR_raw_handler) new_handler,
502  (CPU_ISR_raw_handler *) old_handler
503  );
504 }
505 
506 void *_CPU_Thread_Idle_body( uintptr_t ignored );
507 
508 /*
509  * _CPU_Context_switch
510  *
511  * This routine switches from the run context to the heir context.
512  *
513  * Or1k Specific Information:
514  *
515  * Please see the comments in the .c file for a description of how
516  * this function works. There are several things to be aware of.
517  */
518 
520  Context_Control *run,
521  Context_Control *heir
522 );
523 
524 /*
525  * _CPU_Context_restore
526  *
527  * This routine is generally used only to restart self in an
528  * efficient manner. It may simply be a label in _CPU_Context_switch.
529  *
530  * NOTE: May be unnecessary to reload some registers.
531  *
532  */
533 
535  Context_Control *new_context
537 
538 /*
539  * _CPU_Context_save_fp
540  *
541  * This routine saves the floating point context passed to it.
542  *
543  */
544 
546  void **fp_context_ptr
547 );
548 
549 /*
550  * _CPU_Context_restore_fp
551  *
552  * This routine restores the floating point context passed to it.
553  *
554  */
555 
557  void **fp_context_ptr
558 );
559 
560 /* The following routine swaps the endian format of an unsigned int.
561  * It must be static because it is referenced indirectly.
562  *
563  * This version will work on any processor, but if there is a better
564  * way for your CPU PLEASE use it. The most common way to do this is to:
565  *
566  * swap least significant two bytes with 16-bit rotate
567  * swap upper and lower 16-bits
568  * swap most significant two bytes with 16-bit rotate
569  *
570  * Some CPUs have special instructions which swap a 32-bit quantity in
571  * a single instruction (e.g. i486). It is probably best to avoid
572  * an "endian swapping control bit" in the CPU. One good reason is
573  * that interrupts would probably have to be disabled to insure that
574  * an interrupt does not try to access the same "chunk" with the wrong
575  * endian. Another good reason is that on some CPUs, the endian bit
576  * endianness for ALL fetches -- both code and data -- so the code
577  * will be fetched incorrectly.
578  *
579  */
580 
581 static inline unsigned int CPU_swap_u32(
582  unsigned int value
583 )
584 {
585  uint32_t byte1, byte2, byte3, byte4, swapped;
586 
587  byte4 = (value >> 24) & 0xff;
588  byte3 = (value >> 16) & 0xff;
589  byte2 = (value >> 8) & 0xff;
590  byte1 = value & 0xff;
591 
592  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
593  return( swapped );
594 }
595 
596 #define CPU_swap_u16( value ) \
597  (((value&0xff) << 8) | ((value >> 8)&0xff))
598 
599 typedef uint32_t CPU_Counter_ticks;
600 
601 uint32_t _CPU_Counter_frequency( void );
602 
603 CPU_Counter_ticks _CPU_Counter_read( void );
604 
605 static inline CPU_Counter_ticks _CPU_Counter_difference(
606  CPU_Counter_ticks second,
607  CPU_Counter_ticks first
608 )
609 {
610  return second - first;
611 }
612 
614 typedef uintptr_t CPU_Uint32ptr;
615 
616 #endif /* ASM */
617 
618 #ifdef __cplusplus
619 }
620 #endif
621 
622 #endif
#define _CPU_Context_restore_fp(_fp_context_ptr)
Nothing to do due to the synchronous or lazy floating point switch.
Definition: cpu.h:904
void _CPU_Exception_frame_print(const CPU_Exception_frame *frame)
Prints the exception frame via printk().
Definition: vectorexceptions.c:45
void _CPU_ISR_Set_level(uint32_t level)
Sets the hardware interrupt level by the level value.
Definition: cpu.c:57
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
void _CPU_Context_Initialize(Context_Control *context, void *stack_area_begin, size_t stack_area_size, uint32_t new_level, void(*entry_point)(void), bool is_fp, void *tls_area)
Initializes the CPU context.
Definition: epiphany-context-initialize.c:40
void _CPU_Context_switch(Context_Control *run, Context_Control *heir)
CPU switch context.
Definition: cpu_asm.c:91
#define _CPU_Context_save_fp(_fp_context_ptr)
Nothing to do due to the synchronous or lazy floating point switch.
Definition: cpu.h:898
OR1K utility.
void _CPU_Initialize(void)
CPU initialization.
Definition: cpu.c:45
Provide printf() PRIxxx Constante Beyond Standards.
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
unsigned context
Definition: tlb.h:108
RTEMS_INLINE_ROUTINE void _CPU_ISR_install_raw_handler(uint32_t vector, CPU_ISR_raw_handler new_handler, CPU_ISR_raw_handler *old_handler)
SPARC specific raw ISR installer.
Definition: cpu.h:649
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