source: rtems/cpukit/score/cpu/bfin/rtems/score/cpu.h @ dace69bf

4.104.115
Last change on this file since dace69bf was dace69bf, checked in by Joel Sherrill <joel.sherrill@…>, on 04/17/10 at 19:24:16

2010-04-17 Allan Hessenflow <allanh@…>

  • cpu.c, cpu_asm.S, rtems/score/cpu.h: Fine tune registers saved in the context. The sp and imask registers need to be saved. Also allocated 12 bytes on the stack at thread entry as the abi requires that.
  • Property mode set to 100644
File size: 41.4 KB
Line 
1/**
2 * @file rtems/score/cpu.h
3 */
4
5/*
6 *  This include file contains information pertaining to the Blackfin
7 *  processor.
8 *
9 *  COPYRIGHT (c) 1989-2006.
10 *  On-Line Applications Research Corporation (OAR).
11 *  adapted to Blackfin by Alain Schaefer <alain.schaefer@easc.ch>
12 *                     and Antonio Giovanini <antonio@atos.com.br>
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.com/license/LICENSE.
17 *
18 *  $Id$
19 */
20
21#ifndef _RTEMS_SCORE_CPU_H
22#define _RTEMS_SCORE_CPU_H
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28#include <rtems/score/bfin.h>            /* pick up machine definitions */
29#ifndef ASM
30#include <rtems/score/types.h>
31#endif
32
33/* conditional compilation parameters */
34
35/**
36 *  Should the calls to @ref _Thread_Enable_dispatch be inlined?
37 *
38 *  If TRUE, then they are inlined.
39 *  If FALSE, then a subroutine call is made.
40 *
41 *  This conditional is an example of the classic trade-off of size
42 *  versus speed.  Inlining the call (TRUE) typically increases the
43 *  size of RTEMS while speeding up the enabling of dispatching.
44 *
45 *  @note In general, the @ref _Thread_Dispatch_disable_level will
46 *  only be 0 or 1 unless you are in an interrupt handler and that
47 *  interrupt handler invokes the executive.]  When not inlined
48 *  something calls @ref _Thread_Enable_dispatch which in turns calls
49 *  @ref _Thread_Dispatch.  If the enable dispatch is inlined, then
50 *  one subroutine call is avoided entirely.
51 *
52 *  Port Specific Information:
53 *
54 *  XXX document implementation including references if appropriate
55 */
56#define CPU_INLINE_ENABLE_DISPATCH       FALSE
57
58/**
59 *  Should the body of the search loops in _Thread_queue_Enqueue_priority
60 *  be unrolled one time?  In unrolled each iteration of the loop examines
61 *  two "nodes" on the chain being searched.  Otherwise, only one node
62 *  is examined per iteration.
63 *
64 *  If TRUE, then the loops are unrolled.
65 *  If FALSE, then the loops are not unrolled.
66 *
67 *  The primary factor in making this decision is the cost of disabling
68 *  and enabling interrupts (_ISR_Flash) versus the cost of rest of the
69 *  body of the loop.  On some CPUs, the flash is more expensive than
70 *  one iteration of the loop body.  In this case, it might be desirable
71 *  to unroll the loop.  It is important to note that on some CPUs, this
72 *  code is the longest interrupt disable period in RTEMS.  So it is
73 *  necessary to strike a balance when setting this parameter.
74 *
75 *  Port Specific Information:
76 *
77 *  XXX document implementation including references if appropriate
78 */
79#define CPU_UNROLL_ENQUEUE_PRIORITY      TRUE
80
81/**
82 *  Does RTEMS manage a dedicated interrupt stack in software?
83 *
84 *  If TRUE, then a stack is allocated in @ref _ISR_Handler_initialization.
85 *  If FALSE, nothing is done.
86 *
87 *  If the CPU supports a dedicated interrupt stack in hardware,
88 *  then it is generally the responsibility of the BSP to allocate it
89 *  and set it up.
90 *
91 *  If the CPU does not support a dedicated interrupt stack, then
92 *  the porter has two options: (1) execute interrupts on the
93 *  stack of the interrupted task, and (2) have RTEMS manage a dedicated
94 *  interrupt stack.
95 *
96 *  If this is TRUE, @ref CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
97 *
98 *  Only one of @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK and
99 *  @ref CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE.  It is
100 *  possible that both are FALSE for a particular CPU.  Although it
101 *  is unclear what that would imply about the interrupt processing
102 *  procedure on that CPU.
103 *
104 *  Port Specific Information:
105 *
106 *  XXX document implementation including references if appropriate
107 */
108#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE
109
110/*
111 *  Does the CPU follow the simple vectored interrupt model?
112 *
113 *  If TRUE, then RTEMS allocates the vector table it internally manages.
114 *  If FALSE, then the BSP is assumed to allocate and manage the vector
115 *  table
116 *
117 *  BFIN Specific Information:
118 *
119 *  XXX document implementation including references if appropriate
120 */
121#define CPU_SIMPLE_VECTORED_INTERRUPTS TRUE
122
123/*
124 *  Does the CPU follow the simple vectored interrupt model?
125 *
126 *  If TRUE, then RTEMS allocates the vector table it internally manages.
127 *  If FALSE, then the BSP is assumed to allocate and manage the vector
128 *  table
129 *
130 *  BFIN Specific Information:
131 *
132 *  XXX document implementation including references if appropriate
133 */
134#define CPU_SIMPLE_VECTORED_INTERRUPTS TRUE
135
136/**
137 *  Does this CPU have hardware support for a dedicated interrupt stack?
138 *
139 *  If TRUE, then it must be installed during initialization.
140 *  If FALSE, then no installation is performed.
141 *
142 *  If this is TRUE, @ref CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
143 *
144 *  Only one of @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK and
145 *  @ref CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE.  It is
146 *  possible that both are FALSE for a particular CPU.  Although it
147 *  is unclear what that would imply about the interrupt processing
148 *  procedure on that CPU.
149 *
150 *  Port Specific Information:
151 *
152 *  XXX document implementation including references if appropriate
153 */
154#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
155
156/**
157 *  Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
158 *
159 *  If TRUE, then the memory is allocated during initialization.
160 *  If FALSE, then the memory is allocated during initialization.
161 *
162 *  This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE.
163 *
164 *  Port Specific Information:
165 *
166 *  XXX document implementation including references if appropriate
167 */
168#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
169
170/**
171 *  Does the RTEMS invoke the user's ISR with the vector number and
172 *  a pointer to the saved interrupt frame (1) or just the vector
173 *  number (0)?
174 *
175 *  Port Specific Information:
176 *
177 *  XXX document implementation including references if appropriate
178 */
179#define CPU_ISR_PASSES_FRAME_POINTER 1
180
181/**
182 *  @def CPU_HARDWARE_FP
183 *
184 *  Does the CPU have hardware floating point?
185 *
186 *  If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
187 *  If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
188 *
189 *  If there is a FP coprocessor such as the i387 or mc68881, then
190 *  the answer is TRUE.
191 *
192 *  The macro name "NO_CPU_HAS_FPU" should be made CPU specific.
193 *  It indicates whether or not this CPU model has FP support.  For
194 *  example, it would be possible to have an i386_nofp CPU model
195 *  which set this to false to indicate that you have an i386 without
196 *  an i387 and wish to leave floating point support out of RTEMS.
197 */
198
199/**
200 *  @def CPU_SOFTWARE_FP
201 *
202 *  Does the CPU have no hardware floating point and GCC provides a
203 *  software floating point implementation which must be context
204 *  switched?
205 *
206 *  This feature conditional is used to indicate whether or not there
207 *  is software implemented floating point that must be context
208 *  switched.  The determination of whether or not this applies
209 *  is very tool specific and the state saved/restored is also
210 *  compiler specific.
211 *
212 *  Port Specific Information:
213 *
214 *  XXX document implementation including references if appropriate
215 */
216#if ( BLACKFIN_CPU_HAS_FPU == 1 )
217#define CPU_HARDWARE_FP     TRUE
218#else
219#define CPU_HARDWARE_FP     FALSE
220#endif
221#define CPU_SOFTWARE_FP     FALSE
222
223/**
224 *  Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
225 *
226 *  If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
227 *  If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
228 *
229 *  So far, the only CPUs in which this option has been used are the
230 *  HP PA-RISC and PowerPC.  On the PA-RISC, The HP C compiler and
231 *  gcc both implicitly used the floating point registers to perform
232 *  integer multiplies.  Similarly, the PowerPC port of gcc has been
233 *  seen to allocate floating point local variables and touch the FPU
234 *  even when the flow through a subroutine (like vfprintf()) might
235 *  not use floating point formats.
236 *
237 *  If a function which you would not think utilize the FP unit DOES,
238 *  then one can not easily predict which tasks will use the FP hardware.
239 *  In this case, this option should be TRUE.
240 *
241 *  If @ref CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
242 *
243 *  Port Specific Information:
244 *
245 *  XXX document implementation including references if appropriate
246 */
247#define CPU_ALL_TASKS_ARE_FP     FALSE
248
249/**
250 *  Should the IDLE task have a floating point context?
251 *
252 *  If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
253 *  and it has a floating point context which is switched in and out.
254 *  If FALSE, then the IDLE task does not have a floating point context.
255 *
256 *  Setting this to TRUE negatively impacts the time required to preempt
257 *  the IDLE task from an interrupt because the floating point context
258 *  must be saved as part of the preemption.
259 *
260 *  Port Specific Information:
261 *
262 *  XXX document implementation including references if appropriate
263 */
264#define CPU_IDLE_TASK_IS_FP      FALSE
265
266/**
267 *  Should the saving of the floating point registers be deferred
268 *  until a context switch is made to another different floating point
269 *  task?
270 *
271 *  If TRUE, then the floating point context will not be stored until
272 *  necessary.  It will remain in the floating point registers and not
273 *  disturned until another floating point task is switched to.
274 *
275 *  If FALSE, then the floating point context is saved when a floating
276 *  point task is switched out and restored when the next floating point
277 *  task is restored.  The state of the floating point registers between
278 *  those two operations is not specified.
279 *
280 *  If the floating point context does NOT have to be saved as part of
281 *  interrupt dispatching, then it should be safe to set this to TRUE.
282 *
283 *  Setting this flag to TRUE results in using a different algorithm
284 *  for deciding when to save and restore the floating point context.
285 *  The deferred FP switch algorithm minimizes the number of times
286 *  the FP context is saved and restored.  The FP context is not saved
287 *  until a context switch is made to another, different FP task.
288 *  Thus in a system with only one FP task, the FP context will never
289 *  be saved or restored.
290 *
291 *  Port Specific Information:
292 *
293 *  XXX document implementation including references if appropriate
294 */
295#define CPU_USE_DEFERRED_FP_SWITCH       TRUE
296
297/**
298 *  Does this port provide a CPU dependent IDLE task implementation?
299 *
300 *  If TRUE, then the routine @ref _CPU_Thread_Idle_body
301 *  must be provided and is the default IDLE thread body instead of
302 *  @ref _CPU_Thread_Idle_body.
303 *
304 *  If FALSE, then use the generic IDLE thread body if the BSP does
305 *  not provide one.
306 *
307 *  This is intended to allow for supporting processors which have
308 *  a low power or idle mode.  When the IDLE thread is executed, then
309 *  the CPU can be powered down.
310 *
311 *  The order of precedence for selecting the IDLE thread body is:
312 *
313 *    -#  BSP provided
314 *    -#  CPU dependent (if provided)
315 *    -#  generic (if no BSP and no CPU dependent)
316 *
317 *  Port Specific Information:
318 *
319 *  XXX document implementation including references if appropriate
320 */
321#define CPU_PROVIDES_IDLE_THREAD_BODY    TRUE
322
323/**
324 *  Does the stack grow up (toward higher addresses) or down
325 *  (toward lower addresses)?
326 *
327 *  If TRUE, then the grows upward.
328 *  If FALSE, then the grows toward smaller addresses.
329 *
330 *  Port Specific Information:
331 *
332 *  XXX document implementation including references if appropriate
333 */
334#define CPU_STACK_GROWS_UP               FALSE
335
336/**
337 *  The following is the variable attribute used to force alignment
338 *  of critical RTEMS structures.  On some processors it may make
339 *  sense to have these aligned on tighter boundaries than
340 *  the minimum requirements of the compiler in order to have as
341 *  much of the critical data area as possible in a cache line.
342 *
343 *  The placement of this macro in the declaration of the variables
344 *  is based on the syntactically requirements of the GNU C
345 *  "__attribute__" extension.  For example with GNU C, use
346 *  the following to force a structures to a 32 byte boundary.
347 *
348 *      __attribute__ ((aligned (32)))
349 *
350 *  @note Currently only the Priority Bit Map table uses this feature.
351 *        To benefit from using this, the data must be heavily
352 *        used so it will stay in the cache and used frequently enough
353 *        in the executive to justify turning this on.
354 *
355 *  Port Specific Information:
356 *
357 *  XXX document implementation including references if appropriate
358 */
359#define CPU_STRUCTURE_ALIGNMENT
360
361/**
362 *  @defgroup CPUEndian Processor Dependent Endianness Support
363 *
364 *  This group assists in issues related to processor endianness.
365 */
366
367/**
368 *  @ingroup CPUEndian
369 *  Define what is required to specify how the network to host conversion
370 *  routines are handled.
371 *
372 *  @note @a CPU_BIG_ENDIAN and @a CPU_LITTLE_ENDIAN should NOT have the
373 *  same values.
374 *
375 *  @see CPU_LITTLE_ENDIAN
376 *
377 *  Port Specific Information:
378 *
379 *  XXX document implementation including references if appropriate
380 */
381#define CPU_BIG_ENDIAN                           FALSE
382
383/**
384 *  @ingroup CPUEndian
385 *  Define what is required to specify how the network to host conversion
386 *  routines are handled.
387 *
388 *  @note @ref CPU_BIG_ENDIAN and @ref CPU_LITTLE_ENDIAN should NOT have the
389 *  same values.
390 *
391 *  @see CPU_BIG_ENDIAN
392 *
393 *  Port Specific Information:
394 *
395 *  XXX document implementation including references if appropriate
396 */
397#define CPU_LITTLE_ENDIAN                        TRUE
398
399/**
400 *  @ingroup CPUInterrupt
401 *  The following defines the number of bits actually used in the
402 *  interrupt field of the task mode.  How those bits map to the
403 *  CPU interrupt levels is defined by the routine @ref _CPU_ISR_Set_level.
404 *
405 *  Port Specific Information:
406 *
407 *  XXX document implementation including references if appropriate
408 */
409#define CPU_MODES_INTERRUPT_MASK   0x00000001
410
411/*
412 *  Processor defined structures required for cpukit/score.
413 *
414 *  Port Specific Information:
415 *
416 *  XXX document implementation including references if appropriate
417 */
418
419/* may need to put some structures here.  */
420
421/**
422 * @defgroup CPUContext Processor Dependent Context Management
423 *
424 *  From the highest level viewpoint, there are 2 types of context to save.
425 *
426 *     -# Interrupt registers to save
427 *     -# Task level registers to save
428 *
429 *  Since RTEMS handles integer and floating point contexts separately, this
430 *  means we have the following 3 context items:
431 *
432 *     -# task level context stuff::  Context_Control
433 *     -# floating point task stuff:: Context_Control_fp
434 *     -# special interrupt level context :: CPU_Interrupt_frame
435 *
436 *  On some processors, it is cost-effective to save only the callee
437 *  preserved registers during a task context switch.  This means
438 *  that the ISR code needs to save those registers which do not
439 *  persist across function calls.  It is not mandatory to make this
440 *  distinctions between the caller/callee saves registers for the
441 *  purpose of minimizing context saved during task switch and on interrupts.
442 *  If the cost of saving extra registers is minimal, simplicity is the
443 *  choice.  Save the same context on interrupt entry as for tasks in
444 *  this case.
445 *
446 *  Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
447 *  care should be used in designing the context area.
448 *
449 *  On some CPUs with hardware floating point support, the Context_Control_fp
450 *  structure will not be used or it simply consist of an array of a
451 *  fixed number of bytes.   This is done when the floating point context
452 *  is dumped by a "FP save context" type instruction and the format
453 *  is not really defined by the CPU.  In this case, there is no need
454 *  to figure out the exact format -- only the size.  Of course, although
455 *  this is enough information for RTEMS, it is probably not enough for
456 *  a debugger such as gdb.  But that is another problem.
457 *
458 *  Port Specific Information:
459 *
460 *  XXX document implementation including references if appropriate
461 */
462
463/**
464 *  @ingroup CPUContext Management
465 *  This defines the minimal set of integer and processor state registers
466 *  that must be saved during a voluntary context switch from one thread
467 *  to another.
468 */
469
470/* make sure this stays in sync with the assembly function
471   __CPU_Context_switch in cpu_asm.S  */
472typedef struct {
473    uint32_t   register_r4;
474    uint32_t   register_r5;
475    uint32_t   register_r6;
476    uint32_t   register_r7;
477
478    uint32_t   register_p3;
479    uint32_t   register_p4;
480    uint32_t   register_p5;
481    uint32_t   register_fp;
482    uint32_t   register_sp;
483
484    uint32_t   register_rets;
485
486    uint32_t   imask;
487} Context_Control;
488
489#define _CPU_Context_Get_SP( _context ) \
490  (_context)->register_sp
491
492/**
493 *  @ingroup CPUContext Management
494 *  This defines the complete set of floating point registers that must
495 *  be saved during any context switch from one thread to another.
496 */
497typedef struct {
498    /* FPU registers are listed here */
499    /* Blackfin has no Floating Point */
500} Context_Control_fp;
501
502/**
503 *  @ingroup CPUContext Management
504 *  This defines the set of integer and processor state registers that must
505 *  be saved during an interrupt.  This set does not include any which are
506 *  in @ref Context_Control.
507 */
508typedef struct {
509    /** This field is a hint that a port will have a number of integer
510     *  registers that need to be saved when an interrupt occurs or
511     *  when a context switch occurs at the end of an ISR.
512     */
513    /*uint32_t   special_interrupt_register;*/
514} CPU_Interrupt_frame;
515
516/**
517 *  This variable is optional.  It is used on CPUs on which it is difficult
518 *  to generate an "uninitialized" FP context.  It is filled in by
519 *  @ref _CPU_Initialize and copied into the task's FP context area during
520 *  @ref _CPU_Context_Initialize.
521 *
522 *  Port Specific Information:
523 *
524 *  XXX document implementation including references if appropriate
525 */
526SCORE_EXTERN Context_Control_fp  _CPU_Null_fp_context;
527
528/**
529 *  @defgroup CPUInterrupt Processor Dependent Interrupt Management
530 *
531 *  On some CPUs, RTEMS supports a software managed interrupt stack.
532 *  This stack is allocated by the Interrupt Manager and the switch
533 *  is performed in @ref _ISR_Handler.  These variables contain pointers
534 *  to the lowest and highest addresses in the chunk of memory allocated
535 *  for the interrupt stack.  Since it is unknown whether the stack
536 *  grows up or down (in general), this give the CPU dependent
537 *  code the option of picking the version it wants to use.
538 *
539 *  @note These two variables are required if the macro
540 *        @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
541 *
542 *  Port Specific Information:
543 *
544 *  XXX document implementation including references if appropriate
545 */
546
547/**
548 *  @ingroup CPUInterrupt
549 *  This variable points to the lowest physical address of the interrupt
550 *  stack.
551 */
552SCORE_EXTERN void               *_CPU_Interrupt_stack_low;
553
554/**
555 *  @ingroup CPUInterrupt
556 *  This variable points to the lowest physical address of the interrupt
557 *  stack.
558 */
559SCORE_EXTERN void               *_CPU_Interrupt_stack_high;
560
561/*
562 *  Nothing prevents the porter from declaring more CPU specific variables.
563 *
564 *  Port Specific Information:
565 *
566 *  XXX document implementation including references if appropriate
567 */
568
569/* XXX: if needed, put more variables here */
570
571/**
572 *  @ingroup CPUContext
573 *  The size of the floating point context area.  On some CPUs this
574 *  will not be a "sizeof" because the format of the floating point
575 *  area is not defined -- only the size is.  This is usually on
576 *  CPUs with a "floating point save context" instruction.
577 *
578 *  Port Specific Information:
579 *
580 *  XXX document implementation including references if appropriate
581 */
582#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
583
584/**
585 *  Amount of extra stack (above minimum stack size) required by
586 *  MPCI receive server thread.  Remember that in a multiprocessor
587 *  system this thread must exist and be able to process all directives.
588 *
589 *  Port Specific Information:
590 *
591 *  XXX document implementation including references if appropriate
592 */
593#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
594
595/**
596 *  @ingroup CPUInterrupt
597 *  This defines the number of entries in the @ref _ISR_Vector_table managed
598 *  by RTEMS.
599 *
600 *  Port Specific Information:
601 *
602 *  XXX document implementation including references if appropriate
603 */
604#define CPU_INTERRUPT_NUMBER_OF_VECTORS      16
605
606/**
607 *  @ingroup CPUInterrupt
608 *  This defines the highest interrupt vector number for this port.
609 */
610#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER  (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
611
612/**
613 *  @ingroup CPUInterrupt
614 *  This is defined if the port has a special way to report the ISR nesting
615 *  level.  Most ports maintain the variable @a _ISR_Nest_level.
616 */
617#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
618
619/**
620 *  @ingroup CPUContext
621 *  Should be large enough to run all RTEMS tests.  This ensures
622 *  that a "reasonable" small application should not have any problems.
623 *
624 *  Port Specific Information:
625 *
626 *  XXX document implementation including references if appropriate
627 */
628#define CPU_STACK_MINIMUM_SIZE          (1024*4)
629
630/**
631 *  CPU's worst alignment requirement for data types on a byte boundary.  This
632 *  alignment does not take into account the requirements for the stack.
633 *
634 *  Port Specific Information:
635 *
636 *  XXX document implementation including references if appropriate
637 */
638#define CPU_ALIGNMENT              8
639
640/**
641 *  This number corresponds to the byte alignment requirement for the
642 *  heap handler.  This alignment requirement may be stricter than that
643 *  for the data types alignment specified by @ref CPU_ALIGNMENT.  It is
644 *  common for the heap to follow the same alignment requirement as
645 *  @ref CPU_ALIGNMENT.  If the @ref CPU_ALIGNMENT is strict enough for
646 *  the heap, then this should be set to @ref CPU_ALIGNMENT.
647 *
648 *  @note  This does not have to be a power of 2 although it should be
649 *         a multiple of 2 greater than or equal to 2.  The requirement
650 *         to be a multiple of 2 is because the heap uses the least
651 *         significant field of the front and back flags to indicate
652 *         that a block is in use or free.  So you do not want any odd
653 *         length blocks really putting length data in that bit.
654 *
655 *         On byte oriented architectures, @ref CPU_HEAP_ALIGNMENT normally will
656 *         have to be greater or equal to than @ref CPU_ALIGNMENT to ensure that
657 *         elements allocated from the heap meet all restrictions.
658 *
659 *  Port Specific Information:
660 *
661 *  XXX document implementation including references if appropriate
662 */
663#define CPU_HEAP_ALIGNMENT         CPU_ALIGNMENT
664
665/**
666 *  This number corresponds to the byte alignment requirement for memory
667 *  buffers allocated by the partition manager.  This alignment requirement
668 *  may be stricter than that for the data types alignment specified by
669 *  @ref CPU_ALIGNMENT.  It is common for the partition to follow the same
670 *  alignment requirement as @ref CPU_ALIGNMENT.  If the @ref CPU_ALIGNMENT is
671 *  strict enough for the partition, then this should be set to
672 *  @ref CPU_ALIGNMENT.
673 *
674 *  @note  This does not have to be a power of 2.  It does have to
675 *         be greater or equal to than @ref CPU_ALIGNMENT.
676 *
677 *  Port Specific Information:
678 *
679 *  XXX document implementation including references if appropriate
680 */
681#define CPU_PARTITION_ALIGNMENT    CPU_ALIGNMENT
682
683/**
684 *  This number corresponds to the byte alignment requirement for the
685 *  stack.  This alignment requirement may be stricter than that for the
686 *  data types alignment specified by @ref CPU_ALIGNMENT.  If the
687 *  @ref CPU_ALIGNMENT is strict enough for the stack, then this should be
688 *  set to 0.
689 *
690 *  @note This must be a power of 2 either 0 or greater than @ref CPU_ALIGNMENT.
691 *
692 *  Port Specific Information:
693 *
694 *  XXX document implementation including references if appropriate
695 */
696#define CPU_STACK_ALIGNMENT        0
697
698/*
699 *  ISR handler macros
700 */
701
702/**
703 *  @ingroup CPUInterrupt
704 *  Support routine to initialize the RTEMS vector table after it is allocated.
705 *
706 *  Port Specific Information:
707 *
708 *  XXX document implementation including references if appropriate
709 */
710#define _CPU_Initialize_vectors()
711
712/**
713 *  @ingroup CPUInterrupt
714 *  Disable all interrupts for an RTEMS critical section.  The previous
715 *  level is returned in @a _isr_cookie.
716 *
717 *  @param[out] _isr_cookie will contain the previous level cookie
718 *
719 *  Port Specific Information:
720 *
721 *  XXX document implementation including references if appropriate
722 */
723#define _CPU_ISR_Disable( _level ) \
724  {                                     \
725       asm volatile ("cli %0; csync \n" : "=d" (_level) );     \
726  }
727
728
729/**
730 *  @ingroup CPUInterrupt
731 *  Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
732 *  This indicates the end of an RTEMS critical section.  The parameter
733 *  @a _isr_cookie is not modified.
734 *
735 *  @param[in] _isr_cookie contain the previous level cookie
736 *
737 *  Port Specific Information:
738 *
739 *  XXX document implementation including references if appropriate
740 */
741#define _CPU_ISR_Enable( _level ) { \
742    __asm__ __volatile__ ("sti %0; csync \n" : : "d" (_level) );   \
743  }
744
745/**
746 *  @ingroup CPUInterrupt
747 *  This temporarily restores the interrupt to @a _isr_cookie before immediately
748 *  disabling them again.  This is used to divide long RTEMS critical
749 *  sections into two or more parts.  The parameter @a _isr_cookie is not
750 *  modified.
751 *
752 *  @param[in] _isr_cookie contain the previous level cookie
753 *
754 *  Port Specific Information:
755 *
756 *  XXX document implementation including references if appropriate
757 */
758#define _CPU_ISR_Flash( _level ) { \
759    __asm__ __volatile__ ("sti %0; csync; cli r0; csync" \
760                          : : "d"(_level) : "R0" ); \
761  }
762
763/**
764 *  @ingroup CPUInterrupt
765 *
766 *  This routine and @ref _CPU_ISR_Get_level
767 *  Map the interrupt level in task mode onto the hardware that the CPU
768 *  actually provides.  Currently, interrupt levels which do not
769 *  map onto the CPU in a generic fashion are undefined.  Someday,
770 *  it would be nice if these were "mapped" by the application
771 *  via a callout.  For example, m68k has 8 levels 0 - 7, levels
772 *  8 - 255 would be available for bsp/application specific meaning.
773 *  This could be used to manage a programmable interrupt controller
774 *  via the rtems_task_mode directive.
775 *
776 *  Port Specific Information:
777 *
778 *  XXX document implementation including references if appropriate
779 */
780#define _CPU_ISR_Set_level( _new_level ) \
781  { \
782    __asm__ __volatile__ ( "sti %0; csync" : : "d"(_new_level ? 0 : 0xffff) ); \
783  }
784
785
786/**
787 *  @ingroup CPUInterrupt
788 *  Return the current interrupt disable level for this task in
789 *  the format used by the interrupt level portion of the task mode.
790 *
791 *  @note This routine usually must be implemented as a subroutine.
792 *
793 *  Port Specific Information:
794 *
795 *  XXX document implementation including references if appropriate
796 */
797uint32_t   _CPU_ISR_Get_level( void );
798
799/* end of ISR handler macros */
800
801/* Context handler macros */
802
803/**
804 *  @ingroup CPUContext
805 *  Initialize the context to a state suitable for starting a
806 *  task after a context restore operation.  Generally, this
807 *  involves:
808 *
809 *     - setting a starting address
810 *     - preparing the stack
811 *     - preparing the stack and frame pointers
812 *     - setting the proper interrupt level in the context
813 *     - initializing the floating point context
814 *
815 *  This routine generally does not set any unnecessary register
816 *  in the context.  The state of the "general data" registers is
817 *  undefined at task start time.
818 *
819 *  @param[in] _the_context is the context structure to be initialized
820 *  @param[in] _stack_base is the lowest physical address of this task's stack
821 *  @param[in] _size is the size of this task's stack
822 *  @param[in] _isr is the interrupt disable level
823 *  @param[in] _entry_point is the thread's entry point.  This is
824 *         always @a _Thread_Handler
825 *  @param[in] _is_fp is TRUE if the thread is to be a floating
826 *        point thread.  This is typically only used on CPUs where the
827 *        FPU may be easily disabled by software such as on the SPARC
828 *        where the PSR contains an enable FPU bit.
829 *
830 *  Port Specific Information:
831 *
832 *  See implementation in cpu.c
833 */
834void _CPU_Context_Initialize(
835  Context_Control  *the_context,
836  uint32_t         *stack_base,
837  uint32_t          size,
838  uint32_t          new_level,
839  void             *entry_point,
840  bool              is_fp
841);
842
843/**
844 *  This routine is responsible for somehow restarting the currently
845 *  executing task.  If you are lucky, then all that is necessary
846 *  is restoring the context.  Otherwise, there will need to be
847 *  a special assembly routine which does something special in this
848 *  case.  For many ports, simply adding a label to the restore path
849 *  of @ref _CPU_Context_switch will work.  On other ports, it may be
850 *  possibly to load a few arguments and jump to the restore path. It will
851 *  not work if restarting self conflicts with the stack frame
852 *  assumptions of restoring a context.
853 *
854 *  Port Specific Information:
855 *
856 *  XXX document implementation including references if appropriate
857 */
858#define _CPU_Context_Restart_self( _the_context ) \
859   _CPU_Context_restore( (_the_context) );
860
861/**
862 *  @ingroup CPUContext
863 *  The purpose of this macro is to allow the initial pointer into
864 *  a floating point context area (used to save the floating point
865 *  context) to be at an arbitrary place in the floating point
866 *  context area.
867 *
868 *  This is necessary because some FP units are designed to have
869 *  their context saved as a stack which grows into lower addresses.
870 *  Other FP units can be saved by simply moving registers into offsets
871 *  from the base of the context area.  Finally some FP units provide
872 *  a "dump context" instruction which could fill in from high to low
873 *  or low to high based on the whim of the CPU designers.
874 *
875 *  @param[in] _base is the lowest physical address of the floating point
876 *         context area
877 *  @param[in] _offset is the offset into the floating point area
878 *
879 *  Port Specific Information:
880 *
881 *  XXX document implementation including references if appropriate
882 */
883#define _CPU_Context_Fp_start( _base, _offset ) \
884   ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
885
886/**
887 *  This routine initializes the FP context area passed to it to.
888 *  There are a few standard ways in which to initialize the
889 *  floating point context.  The code included for this macro assumes
890 *  that this is a CPU in which a "initial" FP context was saved into
891 *  @a _CPU_Null_fp_context and it simply copies it to the destination
892 *  context passed to it.
893 *
894 *  Other floating point context save/restore models include:
895 *    -# not doing anything, and
896 *    -# putting a "null FP status word" in the correct place in the FP context.
897 *
898 *  @param[in] _destination is the floating point context area
899 *
900 *  Port Specific Information:
901 *
902 *  XXX document implementation including references if appropriate
903 */
904#define _CPU_Context_Initialize_fp( _destination ) \
905  { \
906   *(*(_destination)) = _CPU_Null_fp_context; \
907  }
908
909/* end of Context handler macros */
910
911/* Fatal Error manager macros */
912
913/**
914 *  This routine copies _error into a known place -- typically a stack
915 *  location or a register, optionally disables interrupts, and
916 *  halts/stops the CPU.
917 *
918 *  Port Specific Information:
919 *
920 *  XXX document implementation including references if appropriate
921 */
922#define _CPU_Fatal_halt( _error ) \
923  { \
924    asm volatile ( "cli R1; \
925                    R1 = %0; \
926                    _halt: \
927                    idle; \
928                    jump _halt;"\
929                    : : "r" (_error) ); \
930  }
931
932/* end of Fatal Error manager macros */
933
934/* Bitfield handler macros */
935
936/**
937 *  @defgroup CPUBitfield Processor Dependent Bitfield Manipulation
938 *
939 *  This set of routines are used to implement fast searches for
940 *  the most important ready task.
941 */
942
943/**
944 *  @ingroup CPUBitfield
945 *  This definition is set to TRUE if the port uses the generic bitfield
946 *  manipulation implementation.
947 */
948#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
949
950/**
951 *  @ingroup CPUBitfield
952 *  This definition is set to TRUE if the port uses the data tables provided
953 *  by the generic bitfield manipulation implementation.
954 *  This can occur when actually using the generic bitfield manipulation
955 *  implementation or when implementing the same algorithm in assembly
956 *  language for improved performance.  It is unlikely that a port will use
957 *  the data if it has a bitfield scan instruction.
958 */
959#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
960
961/**
962 *  @ingroup CPUBitfield
963 *  This routine sets @a _output to the bit number of the first bit
964 *  set in @a _value.  @a _value is of CPU dependent type
965 *  @a Priority_Bit_map_control.  This type may be either 16 or 32 bits
966 *  wide although only the 16 least significant bits will be used.
967 *
968 *  There are a number of variables in using a "find first bit" type
969 *  instruction.
970 *
971 *    -# What happens when run on a value of zero?
972 *    -# Bits may be numbered from MSB to LSB or vice-versa.
973 *    -# The numbering may be zero or one based.
974 *    -# The "find first bit" instruction may search from MSB or LSB.
975 *
976 *  RTEMS guarantees that (1) will never happen so it is not a concern.
977 *  (2),(3), (4) are handled by the macros @ref _CPU_Priority_Mask and
978 *  @ref _CPU_Priority_bits_index.  These three form a set of routines
979 *  which must logically operate together.  Bits in the _value are
980 *  set and cleared based on masks built by @ref _CPU_Priority_Mask.
981 *  The basic major and minor values calculated by @ref _Priority_Major
982 *  and @ref _Priority_Minor are "massaged" by @ref _CPU_Priority_bits_index
983 *  to properly range between the values returned by the "find first bit"
984 *  instruction.  This makes it possible for @ref _Priority_Get_highest to
985 *  calculate the major and directly index into the minor table.
986 *  This mapping is necessary to ensure that 0 (a high priority major/minor)
987 *  is the first bit found.
988 *
989 *  This entire "find first bit" and mapping process depends heavily
990 *  on the manner in which a priority is broken into a major and minor
991 *  components with the major being the 4 MSB of a priority and minor
992 *  the 4 LSB.  Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
993 *  priority.  And (15 << 4) + 14 corresponds to priority 254 -- the next
994 *  to the lowest priority.
995 *
996 *  If your CPU does not have a "find first bit" instruction, then
997 *  there are ways to make do without it.  Here are a handful of ways
998 *  to implement this in software:
999 *
1000@verbatim
1001      - a series of 16 bit test instructions
1002      - a "binary search using if's"
1003      - _number = 0
1004        if _value > 0x00ff
1005          _value >>=8
1006          _number = 8;
1007
1008        if _value > 0x0000f
1009          _value >=8
1010          _number += 4
1011
1012        _number += bit_set_table[ _value ]
1013@endverbatim
1014
1015 *    where bit_set_table[ 16 ] has values which indicate the first
1016 *      bit set
1017 *
1018 *  @param[in] _value is the value to be scanned
1019 *  @param[in] _output is the first bit set
1020 *
1021 *  Port Specific Information:
1022 *
1023 *  XXX document implementation including references if appropriate
1024 */
1025
1026#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
1027#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
1028  { \
1029    asm ("bit(1);"):
1030    (_output) = 0;   /* do something to prevent warnings */ \
1031  }
1032#endif
1033
1034/* end of Bitfield handler macros */
1035
1036/**
1037 *  This routine builds the mask which corresponds to the bit fields
1038 *  as searched by @ref _CPU_Bitfield_Find_first_bit.  See the discussion
1039 *  for that routine.
1040 *
1041 *  Port Specific Information:
1042 *
1043 *  XXX document implementation including references if appropriate
1044 */
1045#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
1046
1047#define _CPU_Priority_Mask( _bit_number ) \
1048  ( 1 << (_bit_number) )
1049
1050#endif
1051
1052/**
1053 *  @ingroup CPUBitfield
1054 *  This routine translates the bit numbers returned by
1055 *  @ref _CPU_Bitfield_Find_first_bit into something suitable for use as
1056 *  a major or minor component of a priority.  See the discussion
1057 *  for that routine.
1058 *
1059 *  @param[in] _priority is the major or minor number to translate
1060 *
1061 *  Port Specific Information:
1062 *
1063 *  XXX document implementation including references if appropriate
1064 */
1065#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
1066
1067#define _CPU_Priority_bits_index( _priority ) \
1068  (_priority)
1069
1070#endif
1071
1072/* end of Priority handler macros */
1073
1074/* functions */
1075
1076/**
1077 *  This routine performs CPU dependent initialization.
1078 *
1079 *  Port Specific Information:
1080 *
1081 *  XXX document implementation including references if appropriate
1082 */
1083void _CPU_Initialize(void);
1084
1085/**
1086 *  @ingroup CPUInterrupt
1087 *  This routine installs a "raw" interrupt handler directly into the
1088 *  processor's vector table.
1089 *
1090 *  @param[in] vector is the vector number
1091 *  @param[in] new_handler is the raw ISR handler to install
1092 *  @param[in] old_handler is the previously installed ISR Handler
1093 *
1094 *  Port Specific Information:
1095 *
1096 *  XXX document implementation including references if appropriate
1097 */
1098void _CPU_ISR_install_raw_handler(
1099  uint32_t    vector,
1100  proc_ptr    new_handler,
1101  proc_ptr   *old_handler
1102);
1103
1104/**
1105 *  @ingroup CPUInterrupt
1106 *  This routine installs an interrupt vector.
1107 *
1108 *  @param[in] vector is the vector number
1109 *  @param[in] new_handler is the RTEMS ISR handler to install
1110 *  @param[in] old_handler is the previously installed ISR Handler
1111 *
1112 *  Port Specific Information:
1113 *
1114 *  XXX document implementation including references if appropriate
1115 */
1116void _CPU_ISR_install_vector(
1117  uint32_t    vector,
1118  proc_ptr    new_handler,
1119  proc_ptr   *old_handler
1120);
1121
1122/**
1123 *  @ingroup CPUInterrupt
1124 *  This routine installs the hardware interrupt stack pointer.
1125 *
1126 *  @note  It need only be provided if @ref CPU_HAS_HARDWARE_INTERRUPT_STACK
1127 *         is TRUE.
1128 *
1129 *  Port Specific Information:
1130 *
1131 *  XXX document implementation including references if appropriate
1132 */
1133void _CPU_Install_interrupt_stack( void );
1134
1135/**
1136 *  This routine is the CPU dependent IDLE thread body.
1137 *
1138 *  @note  It need only be provided if @ref CPU_PROVIDES_IDLE_THREAD_BODY
1139 *         is TRUE.
1140 *
1141 *  Port Specific Information:
1142 *
1143 *  XXX document implementation including references if appropriate
1144 */
1145void *_CPU_Thread_Idle_body( uintptr_t ignored );
1146
1147/**
1148 *  @ingroup CPUContext
1149 *  This routine switches from the run context to the heir context.
1150 *
1151 *  @param[in] run points to the context of the currently executing task
1152 *  @param[in] heir points to the context of the heir task
1153 *
1154 *  Port Specific Information:
1155 *
1156 *  XXX document implementation including references if appropriate
1157 */
1158void _CPU_Context_switch(
1159  Context_Control  *run,
1160  Context_Control  *heir
1161);
1162
1163/**
1164 *  @ingroup CPUContext
1165 *  This routine is generally used only to restart self in an
1166 *  efficient manner.  It may simply be a label in @ref _CPU_Context_switch.
1167 *
1168 *  @param[in] new_context points to the context to be restored.
1169 *
1170 *  @note May be unnecessary to reload some registers.
1171 *
1172 *  Port Specific Information:
1173 *
1174 *  XXX document implementation including references if appropriate
1175 */
1176void _CPU_Context_restore(
1177  Context_Control *new_context
1178);
1179
1180/**
1181 *  @ingroup CPUContext
1182 *  This routine saves the floating point context passed to it.
1183 *
1184 *  @param[in] fp_context_ptr is a pointer to a pointer to a floating
1185 *  point context area
1186 *
1187 *  @return on output @a *fp_context_ptr will contain the address that
1188 *  should be used with @ref _CPU_Context_restore_fp to restore this context.
1189 *
1190 *  Port Specific Information:
1191 *
1192 *  XXX document implementation including references if appropriate
1193 */
1194void _CPU_Context_save_fp(
1195  Context_Control_fp **fp_context_ptr
1196);
1197
1198/**
1199 *  @ingroup CPUContext
1200 *  This routine restores the floating point context passed to it.
1201 *
1202 *  @param[in] fp_context_ptr is a pointer to a pointer to a floating
1203 *  point context area to restore
1204 *
1205 *  @return on output @a *fp_context_ptr will contain the address that
1206 *  should be used with @ref _CPU_Context_save_fp to save this context.
1207 *
1208 *  Port Specific Information:
1209 *
1210 *  XXX document implementation including references if appropriate
1211 */
1212void _CPU_Context_restore_fp(
1213  Context_Control_fp **fp_context_ptr
1214);
1215
1216/**
1217 *  @ingroup CPUEndian
1218 *  The following routine swaps the endian format of an unsigned int.
1219 *  It must be static because it is referenced indirectly.
1220 *
1221 *  This version will work on any processor, but if there is a better
1222 *  way for your CPU PLEASE use it.  The most common way to do this is to:
1223 *
1224 *     swap least significant two bytes with 16-bit rotate
1225 *     swap upper and lower 16-bits
1226 *     swap most significant two bytes with 16-bit rotate
1227 *
1228 *  Some CPUs have special instructions which swap a 32-bit quantity in
1229 *  a single instruction (e.g. i486).  It is probably best to avoid
1230 *  an "endian swapping control bit" in the CPU.  One good reason is
1231 *  that interrupts would probably have to be disabled to ensure that
1232 *  an interrupt does not try to access the same "chunk" with the wrong
1233 *  endian.  Another good reason is that on some CPUs, the endian bit
1234 *  endianness for ALL fetches -- both code and data -- so the code
1235 *  will be fetched incorrectly.
1236 *
1237 *  @param[in] value is the value to be swapped
1238 *  @return the value after being endian swapped
1239 *
1240 *  Port Specific Information:
1241 *
1242 *  XXX document implementation including references if appropriate
1243 */
1244static inline uint32_t CPU_swap_u32(
1245  uint32_t value
1246)
1247{
1248  uint32_t   byte1, byte2, byte3, byte4, swapped;
1249
1250  byte4 = (value >> 24) & 0xff;
1251  byte3 = (value >> 16) & 0xff;
1252  byte2 = (value >> 8)  & 0xff;
1253  byte1 =  value        & 0xff;
1254
1255  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
1256  return( swapped );
1257}
1258
1259/**
1260 *  @ingroup CPUEndian
1261 *  This routine swaps a 16 bir quantity.
1262 *
1263 *  @param[in] value is the value to be swapped
1264 *  @return the value after being endian swapped
1265 */
1266#define CPU_swap_u16( value ) \
1267  (((value&0xff) << 8) | ((value >> 8)&0xff))
1268
1269#ifdef __cplusplus
1270}
1271#endif
1272
1273#endif
Note: See TracBrowser for help on using the repository browser.