RTEMS  5.0.0
cpu.h
Go to the documentation of this file.
1 
7 /*
8  * Conversion to MIPS port by Alan Cudmore <alanc@linuxstart.com> and
9  * Joel Sherrill <joel@OARcorp.com>.
10  *
11  * These changes made the code conditional on standard cpp predefines,
12  * merged the mips1 and mips3 code sequences as much as possible,
13  * and moved some of the assembly code to C. Alan did much of the
14  * initial analysis and rework. Joel took over from there and
15  * wrote the JMR3904 BSP so this could be tested. Joel also
16  * added the new interrupt vectoring support in libcpu and
17  * tried to better support the various interrupt controllers.
18  *
19  */
20 
21 /*
22  * Original MIP64ORION port by Craig Lebakken <craigl@transition.com>
23  * COPYRIGHT (c) 1996 by Transition Networks Inc.
24  *
25  * To anyone who acknowledges that this file is provided "AS IS"
26  * without any express or implied warranty:
27  * permission to use, copy, modify, and distribute this file
28  * for any purpose is hereby granted without fee, provided that
29  * the above copyright notice and this notice appears in all
30  * copies, and that the name of Transition Networks not be used in
31  * advertising or publicity pertaining to distribution of the
32  * software without specific, written prior permission.
33  * Transition Networks makes no representations about the suitability
34  * of this software for any purpose.
35  *
36  * COPYRIGHT (c) 1989-2012.
37  * On-Line Applications Research Corporation (OAR).
38  *
39  * The license and distribution terms for this file may be
40  * found in the file LICENSE in this distribution or at
41  * http://www.rtems.org/license/LICENSE.
42  */
43 
44 #ifndef _RTEMS_SCORE_CPU_H
45 #define _RTEMS_SCORE_CPU_H
46 
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55 
56 #include <rtems/score/basedefs.h>
57 #include <rtems/score/mips.h>
58 
59 /* conditional compilation parameters */
60 
61 /*
62  * Does the CPU follow the simple vectored interrupt model?
63  *
64  * If TRUE, then RTEMS allocates the vector table it internally manages.
65  * If FALSE, then the BSP is assumed to allocate and manage the vector
66  * table
67  *
68  * MIPS Specific Information:
69  *
70  * Up to and including RTEMS 4.10, the MIPS port used simple vectored
71  * interrupts. But this was changed to the PIC model after 4.10.
72  */
73 #define CPU_SIMPLE_VECTORED_INTERRUPTS FALSE
74 
75 /*
76  * Does the RTEMS invoke the user's ISR with the vector number and
77  * a pointer to the saved interrupt frame (1) or just the vector
78  * number (0)?
79  *
80  */
81 
82 #define CPU_ISR_PASSES_FRAME_POINTER TRUE
83 
84 
85 
86 /*
87  * Does the CPU have hardware floating point?
88  *
89  * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
90  * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
91  *
92  * If there is a FP coprocessor such as the i387 or mc68881, then
93  * the answer is TRUE.
94  *
95  * The macro name "MIPS_HAS_FPU" should be made CPU specific.
96  * It indicates whether or not this CPU model has FP support. For
97  * example, it would be possible to have an i386_nofp CPU model
98  * which set this to false to indicate that you have an i386 without
99  * an i387 and wish to leave floating point support out of RTEMS.
100  */
101 
102 #if ( MIPS_HAS_FPU == 1 )
103 #define CPU_HARDWARE_FP TRUE
104 #else
105 #define CPU_HARDWARE_FP FALSE
106 #endif
107 
108 /*
109  * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
110  *
111  * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
112  * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
113  *
114  * So far, the only CPU in which this option has been used is the
115  * HP PA-RISC. The HP C compiler and gcc both implicitly use the
116  * floating point registers to perform integer multiplies. If
117  * a function which you would not think utilize the FP unit DOES,
118  * then one can not easily predict which tasks will use the FP hardware.
119  * In this case, this option should be TRUE.
120  *
121  * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
122  *
123  * Mips Note: It appears the GCC can implicitly generate FPU
124  * and Altivec instructions when you least expect them. So make
125  * all tasks floating point.
126  */
127 
128 #define CPU_ALL_TASKS_ARE_FP CPU_HARDWARE_FP
129 
130 /*
131  * Should the IDLE task have a floating point context?
132  *
133  * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
134  * and it has a floating point context which is switched in and out.
135  * If FALSE, then the IDLE task does not have a floating point context.
136  *
137  * Setting this to TRUE negatively impacts the time required to preempt
138  * the IDLE task from an interrupt because the floating point context
139  * must be saved as part of the preemption.
140  */
141 
142 #define CPU_IDLE_TASK_IS_FP FALSE
143 
144 /*
145  * Should the saving of the floating point registers be deferred
146  * until a context switch is made to another different floating point
147  * task?
148  *
149  * If TRUE, then the floating point context will not be stored until
150  * necessary. It will remain in the floating point registers and not
151  * disturned until another floating point task is switched to.
152  *
153  * If FALSE, then the floating point context is saved when a floating
154  * point task is switched out and restored when the next floating point
155  * task is restored. The state of the floating point registers between
156  * those two operations is not specified.
157  *
158  * If the floating point context does NOT have to be saved as part of
159  * interrupt dispatching, then it should be safe to set this to TRUE.
160  *
161  * Setting this flag to TRUE results in using a different algorithm
162  * for deciding when to save and restore the floating point context.
163  * The deferred FP switch algorithm minimizes the number of times
164  * the FP context is saved and restored. The FP context is not saved
165  * until a context switch is made to another, different FP task.
166  * Thus in a system with only one FP task, the FP context will never
167  * be saved or restored.
168  */
169 
170 #define CPU_USE_DEFERRED_FP_SWITCH TRUE
171 
172 #define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
173 
174 /*
175  * Does the stack grow up (toward higher addresses) or down
176  * (toward lower addresses)?
177  *
178  * If TRUE, then the grows upward.
179  * If FALSE, then the grows toward smaller addresses.
180  */
181 
182 /* our stack grows down */
183 #define CPU_STACK_GROWS_UP FALSE
184 
185 /* FIXME: Is this the right value? */
186 #define CPU_CACHE_LINE_BYTES 16
187 
188 #define CPU_STRUCTURE_ALIGNMENT RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES )
189 
190 /*
191  * The following defines the number of bits actually used in the
192  * interrupt field of the task mode. How those bits map to the
193  * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
194  */
195 
196 #define CPU_MODES_INTERRUPT_MASK 0x000000ff
197 
198 #define CPU_SIZEOF_POINTER 4
199 
200 #define CPU_MAXIMUM_PROCESSORS 32
201 
202 /*
203  * Processor defined structures
204  *
205  * Examples structures include the descriptor tables from the i386
206  * and the processor control structure on the i960ca.
207  */
208 
209 /* may need to put some structures here. */
210 
211 /*
212  * Contexts
213  *
214  * Generally there are 2 types of context to save.
215  * 1. Interrupt registers to save
216  * 2. Task level registers to save
217  *
218  * This means we have the following 3 context items:
219  * 1. task level context stuff:: Context_Control
220  * 2. floating point task stuff:: Context_Control_fp
221  * 3. special interrupt level context :: Context_Control_interrupt
222  *
223  * On some processors, it is cost-effective to save only the callee
224  * preserved registers during a task context switch. This means
225  * that the ISR code needs to save those registers which do not
226  * persist across function calls. It is not mandatory to make this
227  * distinctions between the caller/callee saves registers for the
228  * purpose of minimizing context saved during task switch and on interrupts.
229  * If the cost of saving extra registers is minimal, simplicity is the
230  * choice. Save the same context on interrupt entry as for tasks in
231  * this case.
232  *
233  * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
234  * care should be used in designing the context area.
235  *
236  * On some CPUs with hardware floating point support, the Context_Control_fp
237  * structure will not be used or it simply consist of an array of a
238  * fixed number of bytes. This is done when the floating point context
239  * is dumped by a "FP save context" type instruction and the format
240  * is not really defined by the CPU. In this case, there is no need
241  * to figure out the exact format -- only the size. Of course, although
242  * this is enough information for RTEMS, it is probably not enough for
243  * a debugger such as gdb. But that is another problem.
244  */
245 
246 #ifndef ASM
247 
248 /* WARNING: If this structure is modified, the constants in cpu.h must be updated. */
249 #if (__mips == 1) || (__mips == 32)
250 #define __MIPS_REGISTER_TYPE uint32_t
251 #define __MIPS_FPU_REGISTER_TYPE uint32_t
252 #elif __mips == 3
253 #define __MIPS_REGISTER_TYPE uint64_t
254 #define __MIPS_FPU_REGISTER_TYPE uint64_t
255 #else
256 #error "mips register size: unknown architecture level!!"
257 #endif
258 typedef struct {
259  __MIPS_REGISTER_TYPE s0;
260  __MIPS_REGISTER_TYPE s1;
261  __MIPS_REGISTER_TYPE s2;
262  __MIPS_REGISTER_TYPE s3;
263  __MIPS_REGISTER_TYPE s4;
264  __MIPS_REGISTER_TYPE s5;
265  __MIPS_REGISTER_TYPE s6;
266  __MIPS_REGISTER_TYPE s7;
267  __MIPS_REGISTER_TYPE sp;
268  __MIPS_REGISTER_TYPE fp;
269  __MIPS_REGISTER_TYPE ra;
270  __MIPS_REGISTER_TYPE c0_sr;
271  __MIPS_REGISTER_TYPE c0_epc;
273 
274 #define _CPU_Context_Get_SP( _context ) \
275  (uintptr_t) (_context)->sp
276 
277 /* WARNING: If this structure is modified, the constants in cpu.h
278  * must also be updated.
279  */
280 
281 typedef struct {
282 #if ( CPU_HARDWARE_FP == TRUE )
283  __MIPS_FPU_REGISTER_TYPE fp0;
284  __MIPS_FPU_REGISTER_TYPE fp1;
285  __MIPS_FPU_REGISTER_TYPE fp2;
286  __MIPS_FPU_REGISTER_TYPE fp3;
287  __MIPS_FPU_REGISTER_TYPE fp4;
288  __MIPS_FPU_REGISTER_TYPE fp5;
289  __MIPS_FPU_REGISTER_TYPE fp6;
290  __MIPS_FPU_REGISTER_TYPE fp7;
291  __MIPS_FPU_REGISTER_TYPE fp8;
292  __MIPS_FPU_REGISTER_TYPE fp9;
293  __MIPS_FPU_REGISTER_TYPE fp10;
294  __MIPS_FPU_REGISTER_TYPE fp11;
295  __MIPS_FPU_REGISTER_TYPE fp12;
296  __MIPS_FPU_REGISTER_TYPE fp13;
297  __MIPS_FPU_REGISTER_TYPE fp14;
298  __MIPS_FPU_REGISTER_TYPE fp15;
299  __MIPS_FPU_REGISTER_TYPE fp16;
300  __MIPS_FPU_REGISTER_TYPE fp17;
301  __MIPS_FPU_REGISTER_TYPE fp18;
302  __MIPS_FPU_REGISTER_TYPE fp19;
303  __MIPS_FPU_REGISTER_TYPE fp20;
304  __MIPS_FPU_REGISTER_TYPE fp21;
305  __MIPS_FPU_REGISTER_TYPE fp22;
306  __MIPS_FPU_REGISTER_TYPE fp23;
307  __MIPS_FPU_REGISTER_TYPE fp24;
308  __MIPS_FPU_REGISTER_TYPE fp25;
309  __MIPS_FPU_REGISTER_TYPE fp26;
310  __MIPS_FPU_REGISTER_TYPE fp27;
311  __MIPS_FPU_REGISTER_TYPE fp28;
312  __MIPS_FPU_REGISTER_TYPE fp29;
313  __MIPS_FPU_REGISTER_TYPE fp30;
314  __MIPS_FPU_REGISTER_TYPE fp31;
315  uint32_t fpcs;
316 #endif
318 
319 /*
320  * This struct reflects the stack frame employed in ISR_Handler. Note
321  * that the ISR routine save some of the registers to this frame for
322  * all interrupts and exceptions. Other registers are saved only on
323  * exceptions, while others are not touched at all. The untouched
324  * registers are not normally disturbed by high-level language
325  * programs so they can be accessed when required.
326  *
327  * The registers and their ordering in this struct must directly
328  * correspond to the layout and ordering of * shown in iregdef.h,
329  * as cpu_asm.S uses those definitions to fill the stack frame.
330  * This struct provides access to the stack frame for C code.
331  *
332  * Similarly, this structure is used by debugger stubs and exception
333  * processing routines so be careful when changing the format.
334  *
335  * NOTE: The comments with this structure and cpu_asm.S should be kept
336  * in sync. When in doubt, look in the code to see if the
337  * registers you're interested in are actually treated as expected.
338  * The order of the first portion of this structure follows the
339  * order of registers expected by gdb.
340  */
341 
342 typedef struct
343 {
344  __MIPS_REGISTER_TYPE r0; /* 0 -- NOT FILLED IN */
345  __MIPS_REGISTER_TYPE at; /* 1 -- saved always */
346  __MIPS_REGISTER_TYPE v0; /* 2 -- saved always */
347  __MIPS_REGISTER_TYPE v1; /* 3 -- saved always */
348  __MIPS_REGISTER_TYPE a0; /* 4 -- saved always */
349  __MIPS_REGISTER_TYPE a1; /* 5 -- saved always */
350  __MIPS_REGISTER_TYPE a2; /* 6 -- saved always */
351  __MIPS_REGISTER_TYPE a3; /* 7 -- saved always */
352  __MIPS_REGISTER_TYPE t0; /* 8 -- saved always */
353  __MIPS_REGISTER_TYPE t1; /* 9 -- saved always */
354  __MIPS_REGISTER_TYPE t2; /* 10 -- saved always */
355  __MIPS_REGISTER_TYPE t3; /* 11 -- saved always */
356  __MIPS_REGISTER_TYPE t4; /* 12 -- saved always */
357  __MIPS_REGISTER_TYPE t5; /* 13 -- saved always */
358  __MIPS_REGISTER_TYPE t6; /* 14 -- saved always */
359  __MIPS_REGISTER_TYPE t7; /* 15 -- saved always */
360  __MIPS_REGISTER_TYPE s0; /* 16 -- saved on exceptions */
361  __MIPS_REGISTER_TYPE s1; /* 17 -- saved on exceptions */
362  __MIPS_REGISTER_TYPE s2; /* 18 -- saved on exceptions */
363  __MIPS_REGISTER_TYPE s3; /* 19 -- saved on exceptions */
364  __MIPS_REGISTER_TYPE s4; /* 20 -- saved on exceptions */
365  __MIPS_REGISTER_TYPE s5; /* 21 -- saved on exceptions */
366  __MIPS_REGISTER_TYPE s6; /* 22 -- saved on exceptions */
367  __MIPS_REGISTER_TYPE s7; /* 23 -- saved on exceptions */
368  __MIPS_REGISTER_TYPE t8; /* 24 -- saved always */
369  __MIPS_REGISTER_TYPE t9; /* 25 -- saved always */
370  __MIPS_REGISTER_TYPE k0; /* 26 -- NOT FILLED IN, kernel tmp reg */
371  __MIPS_REGISTER_TYPE k1; /* 27 -- NOT FILLED IN, kernel tmp reg */
372  __MIPS_REGISTER_TYPE gp; /* 28 -- saved always */
373  __MIPS_REGISTER_TYPE sp; /* 29 -- saved on exceptions NOT RESTORED */
374  __MIPS_REGISTER_TYPE fp; /* 30 -- saved always */
375  __MIPS_REGISTER_TYPE ra; /* 31 -- saved always */
376  __MIPS_REGISTER_TYPE c0_sr; /* 32 -- saved always, some bits are */
377  /* manipulated per-thread */
378  __MIPS_REGISTER_TYPE mdlo; /* 33 -- saved always */
379  __MIPS_REGISTER_TYPE mdhi; /* 34 -- saved always */
380  __MIPS_REGISTER_TYPE badvaddr; /* 35 -- saved on exceptions, read-only */
381  __MIPS_REGISTER_TYPE cause; /* 36 -- saved on exceptions NOT restored */
382  __MIPS_REGISTER_TYPE epc; /* 37 -- saved always, read-only register */
383  /* but logically restored */
384  __MIPS_FPU_REGISTER_TYPE f0; /* 38 -- saved if FP enabled */
385  __MIPS_FPU_REGISTER_TYPE f1; /* 39 -- saved if FP enabled */
386  __MIPS_FPU_REGISTER_TYPE f2; /* 40 -- saved if FP enabled */
387  __MIPS_FPU_REGISTER_TYPE f3; /* 41 -- saved if FP enabled */
388  __MIPS_FPU_REGISTER_TYPE f4; /* 42 -- saved if FP enabled */
389  __MIPS_FPU_REGISTER_TYPE f5; /* 43 -- saved if FP enabled */
390  __MIPS_FPU_REGISTER_TYPE f6; /* 44 -- saved if FP enabled */
391  __MIPS_FPU_REGISTER_TYPE f7; /* 45 -- saved if FP enabled */
392  __MIPS_FPU_REGISTER_TYPE f8; /* 46 -- saved if FP enabled */
393  __MIPS_FPU_REGISTER_TYPE f9; /* 47 -- saved if FP enabled */
394  __MIPS_FPU_REGISTER_TYPE f10; /* 48 -- saved if FP enabled */
395  __MIPS_FPU_REGISTER_TYPE f11; /* 49 -- saved if FP enabled */
396  __MIPS_FPU_REGISTER_TYPE f12; /* 50 -- saved if FP enabled */
397  __MIPS_FPU_REGISTER_TYPE f13; /* 51 -- saved if FP enabled */
398  __MIPS_FPU_REGISTER_TYPE f14; /* 52 -- saved if FP enabled */
399  __MIPS_FPU_REGISTER_TYPE f15; /* 53 -- saved if FP enabled */
400  __MIPS_FPU_REGISTER_TYPE f16; /* 54 -- saved if FP enabled */
401  __MIPS_FPU_REGISTER_TYPE f17; /* 55 -- saved if FP enabled */
402  __MIPS_FPU_REGISTER_TYPE f18; /* 56 -- saved if FP enabled */
403  __MIPS_FPU_REGISTER_TYPE f19; /* 57 -- saved if FP enabled */
404  __MIPS_FPU_REGISTER_TYPE f20; /* 58 -- saved if FP enabled */
405  __MIPS_FPU_REGISTER_TYPE f21; /* 59 -- saved if FP enabled */
406  __MIPS_FPU_REGISTER_TYPE f22; /* 60 -- saved if FP enabled */
407  __MIPS_FPU_REGISTER_TYPE f23; /* 61 -- saved if FP enabled */
408  __MIPS_FPU_REGISTER_TYPE f24; /* 62 -- saved if FP enabled */
409  __MIPS_FPU_REGISTER_TYPE f25; /* 63 -- saved if FP enabled */
410  __MIPS_FPU_REGISTER_TYPE f26; /* 64 -- saved if FP enabled */
411  __MIPS_FPU_REGISTER_TYPE f27; /* 65 -- saved if FP enabled */
412  __MIPS_FPU_REGISTER_TYPE f28; /* 66 -- saved if FP enabled */
413  __MIPS_FPU_REGISTER_TYPE f29; /* 67 -- saved if FP enabled */
414  __MIPS_FPU_REGISTER_TYPE f30; /* 68 -- saved if FP enabled */
415  __MIPS_FPU_REGISTER_TYPE f31; /* 69 -- saved if FP enabled */
416  __MIPS_REGISTER_TYPE fcsr; /* 70 -- saved on exceptions */
417  /* (oddly not documented on MGV) */
418  __MIPS_REGISTER_TYPE feir; /* 71 -- saved on exceptions */
419  /* (oddly not documented on MGV) */
420 
421  /* GDB does not seem to care about anything past this point */
422 
423  __MIPS_REGISTER_TYPE tlbhi; /* 72 - NOT FILLED IN, doesn't exist on */
424  /* all MIPS CPUs (at least MGV) */
425 #if __mips == 1
426  __MIPS_REGISTER_TYPE tlblo; /* 73 - NOT FILLED IN, doesn't exist on */
427  /* all MIPS CPUs (at least MGV) */
428 #endif
429 #if (__mips == 3) || (__mips == 32)
430  __MIPS_REGISTER_TYPE tlblo0; /* 73 - NOT FILLED IN, doesn't exist on */
431  /* all MIPS CPUs (at least MGV) */
432 #endif
433 
434  __MIPS_REGISTER_TYPE inx; /* 74 -- NOT FILLED IN, doesn't exist on */
435  /* all MIPS CPUs (at least MGV) */
436  __MIPS_REGISTER_TYPE rand; /* 75 -- NOT FILLED IN, doesn't exist on */
437  /* all MIPS CPUs (at least MGV) */
438  __MIPS_REGISTER_TYPE ctxt; /* 76 -- NOT FILLED IN, doesn't exist on */
439  /* all MIPS CPUs (at least MGV) */
440  __MIPS_REGISTER_TYPE exctype; /* 77 -- NOT FILLED IN (not enough info) */
441  __MIPS_REGISTER_TYPE mode; /* 78 -- NOT FILLED IN (not enough info) */
442  __MIPS_REGISTER_TYPE prid; /* 79 -- NOT FILLED IN (not need to do so) */
443  __MIPS_REGISTER_TYPE tar ; /* 80 -- target address register, filled on exceptions */
444  /* end of __mips == 1 so NREGS == 81 */
445 #if (__mips == 3) || (__mips == 32)
446  __MIPS_REGISTER_TYPE tlblo1; /* 81 -- NOT FILLED IN */
447  __MIPS_REGISTER_TYPE pagemask; /* 82 -- NOT FILLED IN */
448  __MIPS_REGISTER_TYPE wired; /* 83 -- NOT FILLED IN */
449  __MIPS_REGISTER_TYPE count; /* 84 -- NOT FILLED IN */
450  __MIPS_REGISTER_TYPE compare; /* 85 -- NOT FILLED IN */
451  __MIPS_REGISTER_TYPE config; /* 86 -- NOT FILLED IN */
452  __MIPS_REGISTER_TYPE lladdr; /* 87 -- NOT FILLED IN */
453  __MIPS_REGISTER_TYPE watchlo; /* 88 -- NOT FILLED IN */
454  __MIPS_REGISTER_TYPE watchhi; /* 89 -- NOT FILLED IN */
455  __MIPS_REGISTER_TYPE ecc; /* 90 -- NOT FILLED IN */
456  __MIPS_REGISTER_TYPE cacheerr; /* 91 -- NOT FILLED IN */
457  __MIPS_REGISTER_TYPE taglo; /* 92 -- NOT FILLED IN */
458  __MIPS_REGISTER_TYPE taghi; /* 93 -- NOT FILLED IN */
459  __MIPS_REGISTER_TYPE errpc; /* 94 -- NOT FILLED IN */
460  __MIPS_REGISTER_TYPE xctxt; /* 95 -- NOT FILLED IN */
461  /* end of __mips == 3 so NREGS == 96 */
462 #endif
463 
465 
467 
468 /*
469  * This variable is optional. It is used on CPUs on which it is difficult
470  * to generate an "uninitialized" FP context. It is filled in by
471  * _CPU_Initialize and copied into the task's FP context area during
472  * _CPU_Context_Initialize.
473  */
474 
476 
477 /*
478  * Nothing prevents the porter from declaring more CPU specific variables.
479  */
480 
481 /* XXX: if needed, put more variables here */
482 
483 /*
484  * The size of the floating point context area. On some CPUs this
485  * will not be a "sizeof" because the format of the floating point
486  * area is not defined -- only the size is. This is usually on
487  * CPUs with a "floating point save context" instruction.
488  */
489 
490 #define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
491 
492 /*
493  * Amount of extra stack (above minimum stack size) required by
494  * system initialization thread. Remember that in a multiprocessor
495  * system the system intialization thread becomes the MP server thread.
496  */
497 
498 #define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
499 
500 /*
501  * Should be large enough to run all RTEMS tests. This ensures
502  * that a "reasonable" small application should not have any problems.
503  */
504 
505 #define CPU_STACK_MINIMUM_SIZE (8 * 1024)
506 
507 /*
508  * CPU's worst alignment requirement for data types on a byte boundary. This
509  * alignment does not take into account the requirements for the stack.
510  */
511 
512 #define CPU_ALIGNMENT 8
513 
514 /*
515  * This number corresponds to the byte alignment requirement for the
516  * heap handler. This alignment requirement may be stricter than that
517  * for the data types alignment specified by CPU_ALIGNMENT. It is
518  * common for the heap to follow the same alignment requirement as
519  * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
520  * then this should be set to CPU_ALIGNMENT.
521  *
522  * NOTE: This does not have to be a power of 2. It does have to
523  * be greater or equal to than CPU_ALIGNMENT.
524  */
525 
526 #define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
527 
528 /*
529  * This number corresponds to the byte alignment requirement for the
530  * stack. This alignment requirement may be stricter than that for the
531  * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
532  * is strict enough for the stack, then this should be set to 0.
533  *
534  * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
535  */
536 
537 #define CPU_STACK_ALIGNMENT CPU_ALIGNMENT
538 
539 #define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES
540 
541 void mips_vector_exceptions( CPU_Interrupt_frame *frame );
542 
543 /*
544  * ISR handler macros
545  */
546 
547 /*
548  * Declare the function that is present in the shared libcpu directory,
549  * that returns the processor dependent interrupt mask.
550  */
551 
552 uint32_t mips_interrupt_mask( void );
553 
554 /*
555  * Disable all interrupts for an RTEMS critical section. The previous
556  * level is returned in _level.
557  */
558 
559 #define _CPU_ISR_Disable( _level ) \
560  do { \
561  unsigned int _scratch; \
562  mips_get_sr( _scratch ); \
563  mips_set_sr( _scratch & ~SR_INTERRUPT_ENABLE_BITS ); \
564  _level = _scratch & SR_INTERRUPT_ENABLE_BITS; \
565  } while(0)
566 
567 /*
568  * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
569  * This indicates the end of an RTEMS critical section. The parameter
570  * _level is not modified.
571  */
572 
573 #define _CPU_ISR_Enable( _level ) \
574  do { \
575  unsigned int _scratch; \
576  mips_get_sr( _scratch ); \
577  mips_set_sr( (_scratch & ~SR_INTERRUPT_ENABLE_BITS) | (_level & SR_INTERRUPT_ENABLE_BITS) ); \
578  } while(0)
579 
580 /*
581  * This temporarily restores the interrupt to _level before immediately
582  * disabling them again. This is used to divide long RTEMS critical
583  * sections into two or more parts. The parameter _level is not
584  * modified.
585  */
586 
587 #define _CPU_ISR_Flash( _xlevel ) \
588  do { \
589  unsigned int _scratch2 = _xlevel; \
590  _CPU_ISR_Enable( _scratch2 ); \
591  _CPU_ISR_Disable( _scratch2 ); \
592  _xlevel = _scratch2; \
593  } while(0)
594 
595 RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint32_t level )
596 {
597  return ( level & SR_INTERRUPT_ENABLE_BITS ) != 0;
598 }
599 
600 /*
601  * Map interrupt level in task mode onto the hardware that the CPU
602  * actually provides. Currently, interrupt levels which do not
603  * map onto the CPU in a generic fashion are undefined. Someday,
604  * it would be nice if these were "mapped" by the application
605  * via a callout. For example, m68k has 8 levels 0 - 7, levels
606  * 8 - 255 would be available for bsp/application specific meaning.
607  * This could be used to manage a programmable interrupt controller
608  * via the rtems_task_mode directive.
609  *
610  * On the MIPS, 0 is all on. Non-zero is all off. This only
611  * manipulates the IEC.
612  */
613 
614 uint32_t _CPU_ISR_Get_level( void ); /* in cpu.c */
615 
616 void _CPU_ISR_Set_level( uint32_t ); /* in cpu.c */
617 
618 /* end of ISR handler macros */
619 
620 /* Context handler macros */
621 
622 /*
623  * Initialize the context to a state suitable for starting a
624  * task after a context restore operation. Generally, this
625  * involves:
626  *
627  * - setting a starting address
628  * - preparing the stack
629  * - preparing the stack and frame pointers
630  * - setting the proper interrupt level in the context
631  * - initializing the floating point context
632  *
633  * This routine generally does not set any unnecessary register
634  * in the context. The state of the "general data" registers is
635  * undefined at task start time.
636  *
637  * NOTE: This is_fp parameter is TRUE if the thread is to be a floating
638  * point thread. This is typically only used on CPUs where the
639  * FPU may be easily disabled by software such as on the SPARC
640  * where the PSR contains an enable FPU bit.
641  *
642  * The per-thread status register holds the interrupt enable, FP enable
643  * and global interrupt enable for that thread. It means each thread can
644  * enable its own set of interrupts. If interrupts are disabled, RTEMS
645  * can still dispatch via blocking calls. This is the function of the
646  * "Interrupt Level", and on the MIPS, it controls the IEC bit and all
647  * the hardware interrupts as defined in the SR. Software ints
648  * are automatically enabled for all threads, as they will only occur under
649  * program control anyhow. Besides, the interrupt level parm is only 8 bits,
650  * and controlling the software ints plus the others would require 9.
651  *
652  * If the Interrupt Level is 0, all ints are on. Otherwise, the
653  * Interrupt Level should supply a bit pattern to impose on the SR
654  * interrupt bits; bit 0 applies to the mips1 IEC bit/mips3 EXL&IE, bits 1 thru 6
655  * apply to the SR register Intr bits from bit 10 thru bit 15. Bit 7 of
656  * the Interrupt Level parameter is unused at this time.
657  *
658  * These are the only per-thread SR bits, the others are maintained
659  * globally & explicitly preserved by the Context Switch code in cpu_asm.s
660  */
661 
662 
663 #if (__mips == 3) || (__mips == 32)
664 #define _INTON SR_IE
665 #if __mips_fpr==64
666 #define _EXTRABITS SR_FR
667 #else
668 #define _EXTRABITS 0
669 #endif /* __mips_fpr==64 */
670 #endif /* __mips == 3 */
671 #if __mips == 1
672 #define _INTON SR_IEC
673 #define _EXTRABITS 0 /* make sure we're in user mode on MIPS1 processors */
674 #endif /* __mips == 1 */
675 
676 
678  Context_Control *the_context,
679  uintptr_t *stack_base,
680  uint32_t size,
681  uint32_t new_level,
682  void *entry_point,
683  bool is_fp,
684  void *tls_area
685 );
686 
687 
688 /*
689  * This routine is responsible for somehow restarting the currently
690  * executing task. If you are lucky, then all that is necessary
691  * is restoring the context. Otherwise, there will need to be
692  * a special assembly routine which does something special in this
693  * case. Context_Restore should work most of the time. It will
694  * not work if restarting self conflicts with the stack frame
695  * assumptions of restoring a context.
696  */
697 
698 #define _CPU_Context_Restart_self( _the_context ) \
699  _CPU_Context_restore( (_the_context) );
700 
701 /*
702  * This routine initializes the FP context area passed to it to.
703  * There are a few standard ways in which to initialize the
704  * floating point context. The code included for this macro assumes
705  * that this is a CPU in which a "initial" FP context was saved into
706  * _CPU_Null_fp_context and it simply copies it to the destination
707  * context passed to it.
708  *
709  * Other models include (1) not doing anything, and (2) putting
710  * a "null FP status word" in the correct place in the FP context.
711  */
712 
713 #if ( CPU_HARDWARE_FP == TRUE )
714 #define _CPU_Context_Initialize_fp( _destination ) \
715  { \
716  *(*(_destination)) = _CPU_Null_fp_context; \
717  }
718 #endif
719 
720 /* end of Context handler macros */
721 
722 /* Fatal Error manager macros */
723 
724 /*
725  * This routine copies _error into a known place -- typically a stack
726  * location or a register, optionally disables interrupts, and
727  * halts/stops the CPU.
728  */
729 
730 #define _CPU_Fatal_halt( _source, _error ) \
731  do { \
732  unsigned int _level; \
733  _CPU_ISR_Disable(_level); \
734  (void)_level; \
735  loop: goto loop; \
736  } while (0)
737 
738 
739 extern void mips_break( int error );
740 
741 #define CPU_USE_GENERIC_BITFIELD_CODE TRUE
742 
743 /* functions */
744 
745 /*
746  * _CPU_Initialize
747  *
748  * This routine performs CPU dependent initialization.
749  */
750 
751 void _CPU_Initialize(void);
752 
753 void *_CPU_Thread_Idle_body( uintptr_t ignored );
754 
755 /*
756  * _CPU_Context_switch
757  *
758  * This routine switches from the run context to the heir context.
759  */
760 
762  Context_Control *run,
763  Context_Control *heir
764 );
765 
766 /*
767  * _CPU_Context_restore
768  *
769  * This routine is generally used only to restart self in an
770  * efficient manner. It may simply be a label in _CPU_Context_switch.
771  *
772  * NOTE: May be unnecessary to reload some registers.
773  */
774 
776  Context_Control *new_context
778 
779 /*
780  * _CPU_Context_save_fp
781  *
782  * This routine saves the floating point context passed to it.
783  */
784 
786  Context_Control_fp **fp_context_ptr
787 );
788 
789 /*
790  * _CPU_Context_restore_fp
791  *
792  * This routine restores the floating point context passed to it.
793  */
794 
796  Context_Control_fp **fp_context_ptr
797 );
798 
799 void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
800 
801 /* The following routine swaps the endian format of an unsigned int.
802  * It must be static because it is referenced indirectly.
803  *
804  * This version will work on any processor, but if there is a better
805  * way for your CPU PLEASE use it. The most common way to do this is to:
806  *
807  * swap least significant two bytes with 16-bit rotate
808  * swap upper and lower 16-bits
809  * swap most significant two bytes with 16-bit rotate
810  *
811  * Some CPUs have special instructions which swap a 32-bit quantity in
812  * a single instruction (e.g. i486). It is probably best to avoid
813  * an "endian swapping control bit" in the CPU. One good reason is
814  * that interrupts would probably have to be disabled to ensure that
815  * an interrupt does not try to access the same "chunk" with the wrong
816  * endian. Another good reason is that on some CPUs, the endian bit
817  * endianness for ALL fetches -- both code and data -- so the code
818  * will be fetched incorrectly.
819  */
820 
821 static inline uint32_t CPU_swap_u32(
822  uint32_t value
823 )
824 {
825  uint32_t byte1, byte2, byte3, byte4, swapped;
826 
827  byte4 = (value >> 24) & 0xff;
828  byte3 = (value >> 16) & 0xff;
829  byte2 = (value >> 8) & 0xff;
830  byte1 = value & 0xff;
831 
832  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
833  return( swapped );
834 }
835 
836 #define CPU_swap_u16( value ) \
837  (((value&0xff) << 8) | ((value >> 8)&0xff))
838 
839 typedef uint32_t CPU_Counter_ticks;
840 
841 uint32_t _CPU_Counter_frequency( void );
842 
843 CPU_Counter_ticks _CPU_Counter_read( void );
844 
845 static inline CPU_Counter_ticks _CPU_Counter_difference(
846  CPU_Counter_ticks second,
847  CPU_Counter_ticks first
848 )
849 {
850  return second - first;
851 }
852 
854 typedef uintptr_t CPU_Uint32ptr;
855 
856 #endif
857 
858 #ifdef __cplusplus
859 }
860 #endif
861 
863 #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
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
#define fp
frame-pointer */
Definition: regs.h:65
#define k0
kernel private register 0 */
Definition: regs.h:61
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
Definition: bootldr.h:45
#define k1
kernel private register 1 */
Definition: regs.h:62
struct rtems_bsdnet_ifconfig * config
Network driver configuration.
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
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.
#define ra
return address */
Definition: regs.h:66
unsigned size
Definition: tte.h:74
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
Information to build RTEMS for a "no cpu" while in protected mode.
Context_Control_fp _CPU_Null_fp_context
Definition: cpu.c:45
#define gp
global data pointer */
Definition: regs.h:63