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

4.115
Last change on this file since f1738ed was f1738ed, checked in by Sebastian Huber <sebastian.huber@…>, on 11/04/12 at 20:04:39

score: PR1607: Add and use CPU_SIZEOF_POINTER

Add and use new CPU port define CPU_SIZEOF_POINTER. It must be an
integer literal that can be used by the assembler. This value will be
used to calculate offsets of structure members. These offsets will be
used in assembler code.

The size of a pointer is part of the application binary interface (ABI)
and thus independent of the actual programming language. The compiler
will provide defines to determine the current ABI. We use these defines
to select the appropriate CPU_SIZEOF_POINTER value.

Static assertions in the new file "cpukit/score/src/percpuasm.c" will
ensure that the value of CPU_SIZEOF_POINTER is consistent with the
current compiler settings. Also the offset values used by assembler
code are verfied.

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