RTEMS  5.0.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
cpu.h
Go to the documentation of this file.
1 
5 /*
6  *
7  * Copyright (c) 2015 University of York.
8  * Hesham ALMatary <hmka501@york.ac.uk>
9  *
10  * COPYRIGHT (c) 1989-1999.
11  * On-Line Applications Research Corporation (OAR).
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 #ifndef _EPIPHANY_CPU_H
36 #define _EPIPHANY_CPU_H
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 #include <rtems/score/basedefs.h>
43 #include <rtems/score/epiphany.h> /* pick up machine definitions */
44 #ifndef ASM
45 #include <rtems/bspIo.h>
46 #include <stdint.h>
47 #include <stdio.h> /* for printk */
48 #endif
49 
55 /* conditional compilation parameters */
56 
57 /*
58  * Does the RTEMS invoke the user's ISR with the vector number and
59  * a pointer to the saved interrupt frame (1) or just the vector
60  * number (0)?
61  *
62  */
63 
64 #define CPU_ISR_PASSES_FRAME_POINTER TRUE
65 
66 /*
67  * Does the CPU have hardware floating point?
68  *
69  * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
70  * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
71  *
72  * If there is a FP coprocessor such as the i387 or mc68881, then
73  * the answer is TRUE.
74  *
75  * The macro name "epiphany_HAS_FPU" should be made CPU specific.
76  * It indicates whether or not this CPU model has FP support. For
77  * example, it would be possible to have an i386_nofp CPU model
78  * which set this to false to indicate that you have an i386 without
79  * an i387 and wish to leave floating point support out of RTEMS.
80  *
81  * The CPU_SOFTWARE_FP is used to indicate whether or not there
82  * is software implemented floating point that must be context
83  * switched. The determination of whether or not this applies
84  * is very tool specific and the state saved/restored is also
85  * compiler specific.
86  *
87  * epiphany Specific Information:
88  *
89  * At this time there are no implementations of Epiphany that are
90  * expected to implement floating point.
91  */
92 
93 #define CPU_HARDWARE_FP FALSE
94 #define CPU_SOFTWARE_FP FALSE
95 
96 /*
97  * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
98  *
99  * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
100  * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
101  *
102  * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
103  *
104  */
105 
106 #define CPU_ALL_TASKS_ARE_FP FALSE
107 
108 /*
109  * Should the IDLE task have a floating point context?
110  *
111  * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
112  * and it has a floating point context which is switched in and out.
113  * If FALSE, then the IDLE task does not have a floating point context.
114  *
115  * Setting this to TRUE negatively impacts the time required to preempt
116  * the IDLE task from an interrupt because the floating point context
117  * must be saved as part of the preemption.
118  *
119  */
120 
121 #define CPU_IDLE_TASK_IS_FP FALSE
122 
123 /*
124  * Should the saving of the floating point registers be deferred
125  * until a context switch is made to another different floating point
126  * task?
127  *
128  * If TRUE, then the floating point context will not be stored until
129  * necessary. It will remain in the floating point registers and not
130  * disturned until another floating point task is switched to.
131  *
132  * If FALSE, then the floating point context is saved when a floating
133  * point task is switched out and restored when the next floating point
134  * task is restored. The state of the floating point registers between
135  * those two operations is not specified.
136  *
137  * If the floating point context does NOT have to be saved as part of
138  * interrupt dispatching, then it should be safe to set this to TRUE.
139  *
140  * Setting this flag to TRUE results in using a different algorithm
141  * for deciding when to save and restore the floating point context.
142  * The deferred FP switch algorithm minimizes the number of times
143  * the FP context is saved and restored. The FP context is not saved
144  * until a context switch is made to another, different FP task.
145  * Thus in a system with only one FP task, the FP context will never
146  * be saved or restored.
147  *
148  */
149 
150 #define CPU_USE_DEFERRED_FP_SWITCH FALSE
151 
152 #define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
153 
154 /*
155  * Does the stack grow up (toward higher addresses) or down
156  * (toward lower addresses)?
157  *
158  * If TRUE, then the grows upward.
159  * If FALSE, then the grows toward smaller addresses.
160  *
161  */
162 
163 #define CPU_STACK_GROWS_UP FALSE
164 
165 /* FIXME: Is this the right value? */
166 #define CPU_CACHE_LINE_BYTES 64
167 
168 #define CPU_STRUCTURE_ALIGNMENT RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES )
169 
170 /*
171  * The following defines the number of bits actually used in the
172  * interrupt field of the task mode. How those bits map to the
173  * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
174  *
175  */
176 
177 #define CPU_MODES_INTERRUPT_MASK 0x00000001
178 
179 /*
180  * Processor defined structures required for cpukit/score.
181  */
182 
183 /*
184  * Contexts
185  *
186  * Generally there are 2 types of context to save.
187  * 1. Interrupt registers to save
188  * 2. Task level registers to save
189  *
190  * This means we have the following 3 context items:
191  * 1. task level context stuff:: Context_Control
192  * 2. floating point task stuff:: Context_Control_fp
193  * 3. special interrupt level context :: Context_Control_interrupt
194  *
195  * On some processors, it is cost-effective to save only the callee
196  * preserved registers during a task context switch. This means
197  * that the ISR code needs to save those registers which do not
198  * persist across function calls. It is not mandatory to make this
199  * distinctions between the caller/callee saves registers for the
200  * purpose of minimizing context saved during task switch and on interrupts.
201  * If the cost of saving extra registers is minimal, simplicity is the
202  * choice. Save the same context on interrupt entry as for tasks in
203  * this case.
204  *
205  * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
206  * care should be used in designing the context area.
207  *
208  * On some CPUs with hardware floating point support, the Context_Control_fp
209  * structure will not be used or it simply consist of an array of a
210  * fixed number of bytes. This is done when the floating point context
211  * is dumped by a "FP save context" type instruction and the format
212  * is not really defined by the CPU. In this case, there is no need
213  * to figure out the exact format -- only the size. Of course, although
214  * this is enough information for RTEMS, it is probably not enough for
215  * a debugger such as gdb. But that is another problem.
216  *
217  *
218  */
219 #ifndef ASM
220 
221 typedef struct {
222  uint32_t r[64];
223 
224  uint32_t status;
225  uint32_t config;
226  uint32_t iret;
227 
228 #ifdef RTEMS_SMP
229 
266  volatile bool is_executing;
267 #endif
269 
270 #define _CPU_Context_Get_SP( _context ) \
271  (_context)->r[13]
272 
273 typedef struct {
277 
279 
280 /*
281  * The size of the floating point context area. On some CPUs this
282  * will not be a "sizeof" because the format of the floating point
283  * area is not defined -- only the size is. This is usually on
284  * CPUs with a "floating point save context" instruction.
285  *
286  * epiphany Specific Information:
287  *
288  */
289 
290 #define CPU_CONTEXT_FP_SIZE 0
291 
292 /*
293  * Amount of extra stack (above minimum stack size) required by
294  * MPCI receive server thread. Remember that in a multiprocessor
295  * system this thread must exist and be able to process all directives.
296  *
297  */
298 
299 #define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
300 
301 /*
302  * Should be large enough to run all RTEMS tests. This insures
303  * that a "reasonable" small application should not have any problems.
304  *
305  */
306 
307 #define CPU_STACK_MINIMUM_SIZE 4096
308 
309 /*
310  * CPU's worst alignment requirement for data types on a byte boundary. This
311  * alignment does not take into account the requirements for the stack.
312  *
313  */
314 
315 #define CPU_ALIGNMENT 8
316 
317 /*
318  * This is defined if the port has a special way to report the ISR nesting
319  * level. Most ports maintain the variable _ISR_Nest_level.
320  */
321 #define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
322 
323 /*
324  * This number corresponds to the byte alignment requirement for the
325  * heap handler. This alignment requirement may be stricter than that
326  * for the data types alignment specified by CPU_ALIGNMENT. It is
327  * common for the heap to follow the same alignment requirement as
328  * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
329  * then this should be set to CPU_ALIGNMENT.
330  *
331  * NOTE: This does not have to be a power of 2 although it should be
332  * a multiple of 2 greater than or equal to 2. The requirement
333  * to be a multiple of 2 is because the heap uses the least
334  * significant field of the front and back flags to indicate
335  * that a block is in use or free. So you do not want any odd
336  * length blocks really putting length data in that bit.
337  *
338  * On byte oriented architectures, CPU_HEAP_ALIGNMENT normally will
339  * have to be greater or equal to than CPU_ALIGNMENT to ensure that
340  * elements allocated from the heap meet all restrictions.
341  *
342  */
343 
344 #define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
345 
346 /*
347  * This number corresponds to the byte alignment requirement for the
348  * stack. This alignment requirement may be stricter than that for the
349  * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
350  * is strict enough for the stack, then this should be set to 0.
351  *
352  * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
353  *
354  */
355 
356 #define CPU_STACK_ALIGNMENT 8
357 
358 #define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES
359 
360 /* ISR handler macros */
361 
362 /*
363  * Support routine to initialize the RTEMS vector table after it is allocated.
364  *
365  * NO_CPU Specific Information:
366  *
367  * XXX document implementation including references if appropriate
368  */
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  */
377 
378 static inline uint32_t epiphany_interrupt_disable( void )
379 {
380  uint32_t sr;
381  __asm__ __volatile__ ("movfs %[sr], status \n" : [sr] "=r" (sr):);
382  __asm__ __volatile__("gid \n");
383  return sr;
384 }
385 
386 static inline void epiphany_interrupt_enable(uint32_t level)
387 {
388  __asm__ __volatile__("gie \n");
389  __asm__ __volatile__ ("movts status, %[level] \n" :: [level] "r" (level):);
390 }
391 
392 #define _CPU_ISR_Disable( _level ) \
393  _level = epiphany_interrupt_disable()
394 
395 /*
396  * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
397  * This indicates the end of an RTEMS critical section. The parameter
398  * _level is not modified.
399  *
400  */
401 
402 #define _CPU_ISR_Enable( _level ) \
403  epiphany_interrupt_enable( _level )
404 
405 /*
406  * This temporarily restores the interrupt to _level before immediately
407  * disabling them again. This is used to divide long RTEMS critical
408  * sections into two or more parts. The parameter _level is not
409  * modified.
410  *
411  */
412 
413 #define _CPU_ISR_Flash( _level ) \
414  do{ \
415  if ( (_level & 0x2) != 0 ) \
416  _CPU_ISR_Enable( _level ); \
417  epiphany_interrupt_disable(); \
418  } while(0)
419 
420 RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint32_t level )
421 {
422  return ( level & 0x2 ) != 0;
423 }
424 
425 /*
426  * Map interrupt level in task mode onto the hardware that the CPU
427  * actually provides. Currently, interrupt levels which do not
428  * map onto the CPU in a generic fashion are undefined. Someday,
429  * it would be nice if these were "mapped" by the application
430  * via a callout. For example, m68k has 8 levels 0 - 7, levels
431  * 8 - 255 would be available for bsp/application specific meaning.
432  * This could be used to manage a programmable interrupt controller
433  * via the rtems_task_mode directive.
434  *
435  * The get routine usually must be implemented as a subroutine.
436  *
437  */
438 
439 void _CPU_ISR_Set_level( uint32_t level );
440 
441 uint32_t _CPU_ISR_Get_level( void );
442 
443 /* end of ISR handler macros */
444 
445 /* Context handler macros */
446 
447 /*
448  * Initialize the context to a state suitable for starting a
449  * task after a context restore operation. Generally, this
450  * involves:
451  *
452  * - setting a starting address
453  * - preparing the stack
454  * - preparing the stack and frame pointers
455  * - setting the proper interrupt level in the context
456  * - initializing the floating point context
457  *
458  * This routine generally does not set any unnecessary register
459  * in the context. The state of the "general data" registers is
460  * undefined at task start time.
461  *
462  * NOTE: This is_fp parameter is TRUE if the thread is to be a floating
463  * point thread. This is typically only used on CPUs where the
464  * FPU may be easily disabled by software such as on the SPARC
465  * where the PSR contains an enable FPU bit.
466  *
467  */
468 
476 #define EPIPHANY_GCC_RED_ZONE_SIZE 128
477 
497  void *stack_area_begin,
498  size_t stack_area_size,
499  uint32_t new_level,
500  void (*entry_point)( void ),
501  bool is_fp,
502  void *tls_area
503 );
504 
505 /*
506  * This routine is responsible for somehow restarting the currently
507  * executing task. If you are lucky, then all that is necessary
508  * is restoring the context. Otherwise, there will need to be
509  * a special assembly routine which does something special in this
510  * case. Context_Restore should work most of the time. It will
511  * not work if restarting self conflicts with the stack frame
512  * assumptions of restoring a context.
513  *
514  */
515 
516 #define _CPU_Context_Restart_self( _the_context ) \
517  _CPU_Context_restore( (_the_context) )
518 
519 #define _CPU_Context_Initialize_fp( _destination ) \
520  memset( *( _destination ), 0, CPU_CONTEXT_FP_SIZE );
521 
522 /* end of Context handler macros */
523 
524 /* Fatal Error manager macros */
525 
526 /*
527  * This routine copies _error into a known place -- typically a stack
528  * location or a register, optionally disables interrupts, and
529  * halts/stops the CPU.
530  *
531  */
532 
533 #include <inttypes.h>
534 
535 #define _CPU_Fatal_halt(_source, _error ) \
536  printk("Fatal Error %d.%" PRIu32 " Halted\n",_source, _error); \
537  asm("trap 3" :: "r" (_error)); \
538  for(;;)
539 
540 /* end of Fatal Error manager macros */
541 
542 #define CPU_USE_GENERIC_BITFIELD_CODE TRUE
543 
544 #endif /* ASM */
545 
553 #define CPU_SIZEOF_POINTER 4
554 #define CPU_EXCEPTION_FRAME_SIZE 260
555 
556 #define CPU_MAXIMUM_PROCESSORS 32
557 
558 #ifndef ASM
559 
560 typedef struct {
561  uint32_t r[62];
562  uint32_t status;
563  uint32_t config;
564  uint32_t iret;
566 
573 
574 
575 /* end of Priority handler macros */
576 
577 /* functions */
578 
579 /*
580  * _CPU_Initialize
581  *
582  * This routine performs CPU dependent initialization.
583  *
584  */
585 
586 void _CPU_Initialize(
587  void
588 );
589 
590 void *_CPU_Thread_Idle_body( uintptr_t ignored );
591 
592 /*
593  * _CPU_Context_switch
594  *
595  * This routine switches from the run context to the heir context.
596  *
597  * epiphany Specific Information:
598  *
599  * Please see the comments in the .c file for a description of how
600  * this function works. There are several things to be aware of.
601  */
602 
604  Context_Control *run,
605  Context_Control *heir
606 );
607 
608 /*
609  * _CPU_Context_restore
610  *
611  * This routine is generally used only to restart self in an
612  * efficient manner. It may simply be a label in _CPU_Context_switch.
613  *
614  * NOTE: May be unnecessary to reload some registers.
615  *
616  */
617 
619  Context_Control *new_context
621 
622 /*
623  * _CPU_Context_save_fp
624  *
625  * This routine saves the floating point context passed to it.
626  *
627  */
628 
630  void **fp_context_ptr
631 );
632 
633 /*
634  * _CPU_Context_restore_fp
635  *
636  * This routine restores the floating point context passed to it.
637  *
638  */
639 
641  void **fp_context_ptr
642 );
643 
644 /* The following routine swaps the endian format of an unsigned int.
645  * It must be static because it is referenced indirectly.
646  *
647  * This version will work on any processor, but if there is a better
648  * way for your CPU PLEASE use it. The most common way to do this is to:
649  *
650  * swap least significant two bytes with 16-bit rotate
651  * swap upper and lower 16-bits
652  * swap most significant two bytes with 16-bit rotate
653  *
654  * Some CPUs have special instructions which swap a 32-bit quantity in
655  * a single instruction (e.g. i486). It is probably best to avoid
656  * an "endian swapping control bit" in the CPU. One good reason is
657  * that interrupts would probably have to be disabled to insure that
658  * an interrupt does not try to access the same "chunk" with the wrong
659  * endian. Another good reason is that on some CPUs, the endian bit
660  * endianness for ALL fetches -- both code and data -- so the code
661  * will be fetched incorrectly.
662  *
663  */
664 
665 static inline unsigned int CPU_swap_u32(
666  unsigned int value
667 )
668 {
669  uint32_t byte1, byte2, byte3, byte4, swapped;
670 
671  byte4 = (value >> 24) & 0xff;
672  byte3 = (value >> 16) & 0xff;
673  byte2 = (value >> 8) & 0xff;
674  byte1 = value & 0xff;
675 
676  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
677  return( swapped );
678 }
679 
680 #define CPU_swap_u16( value ) \
681  (((value&0xff) << 8) | ((value >> 8)&0xff))
682 
683 typedef uint32_t CPU_Counter_ticks;
684 
685 uint32_t _CPU_Counter_frequency( void );
686 
687 CPU_Counter_ticks _CPU_Counter_read( void );
688 
689 static inline CPU_Counter_ticks _CPU_Counter_difference(
690  CPU_Counter_ticks second,
691  CPU_Counter_ticks first
692 )
693 {
694  return second - first;
695 }
696 
698 typedef uintptr_t CPU_Uint32ptr;
699 
700 #endif /* ASM */
701 
702 #ifdef __cplusplus
703 }
704 #endif
705 
706 #endif
707 
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: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
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
struct rtems_bsdnet_ifconfig * config
Network driver configuration.
double some_float_register
Definition: cpu.h:275
void _CPU_Initialize(void)
CPU initialization.
Definition: cpu.c:45
SPARC basic context.
Definition: cpu.h:242
register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__("g6")
The pointer to the current per-CPU control is available via register g6.
Provide printf() PRIxxx Constante Beyond Standards.
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
unsigned context
Definition: tlb.h:108
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.
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