RTEMS 5.2
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
29extern "C" {
30#endif
31
32
33#include <rtems/score/or1k.h> /* pick up machine definitions */
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
138typedef 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
277static 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
287static 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
344void _CPU_ISR_Set_level( uint32_t level );
345
346uint32_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
445typedef 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
479void _CPU_Initialize(
480 void
481);
482
483typedef 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
491typedef 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
506void *_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
581static 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
599typedef uint32_t CPU_Counter_ticks;
600
601uint32_t _CPU_Counter_frequency( void );
602
603CPU_Counter_ticks _CPU_Counter_read( void );
604
605static 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
614typedef uintptr_t CPU_Uint32ptr;
615
616#endif /* ASM */
617
618#ifdef __cplusplus
619}
620#endif
621
622#endif
Basic Definitions.
Interface to Kernel Print Methods.
#define RTEMS_NO_RETURN
Definition: basedefs.h:102
#define RTEMS_INLINE_ROUTINE
Definition: basedefs.h:66
void _CPU_ISR_Set_level(uint32_t level)
Sets the hardware interrupt level by the level value.
Definition: cpu.c:57
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_Thread_Idle_body(uintptr_t ignored)
Definition: idle-mcf5272.c:20
void _CPU_Initialize(void)
CPU initialization.
Definition: cpu.c:45
uintptr_t CPU_Uint32ptr
Definition: cpu.h:662
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
uint32_t _CPU_Counter_frequency(void)
Returns the current CPU counter frequency in Hz.
Definition: system-clocks.c:112
void _CPU_Context_switch(Context_Control *run, Context_Control *heir)
CPU switch context.
Definition: cpu_asm.c:91
CPU_Counter_ticks _CPU_Counter_read(void)
Returns the current CPU counter value.
Definition: system-clocks.c:117
void _CPU_Context_restore(Context_Control *new_context) RTEMS_NO_RETURN
Definition: cpu_asm.c:111
uint32_t _CPU_ISR_Get_level(void)
Definition: cpu.c:88
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_Exception_frame_print(const CPU_Exception_frame *frame)
Prints the exception frame via printk().
Definition: vectorexceptions.c:45
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
Provide printf() PRIxxx Constante Beyond Standards.
uint32_t CPU_Counter_ticks
Unsigned integer type for CPU counter values.
Definition: cpu.h:1210
OR1K utility.
#define _CPU_Context_restore_fp(_fp_context_ptr)
Nothing to do due to the synchronous or lazy floating point switch.
Definition: cpu.h:904
#define _CPU_Context_save_fp(_fp_context_ptr)
Nothing to do due to the synchronous or lazy floating point switch.
Definition: cpu.h:898
The set of registers that specifies the complete processor state.
Definition: cpu.h:629
Interrupt stack frame (ISF).
Definition: cpu.h:191
Thread register context.
Definition: cpu.h:194
unsigned context
Definition: tlb.h:1