source: rtems/cpukit/score/cpu/bfin/rtems/score/cpu.h @ 27bfcd8

5
Last change on this file since 27bfcd8 was 27bfcd8, checked in by Sebastian Huber <sebastian.huber@…>, on Jan 25, 2017 at 1:32:02 PM

score: Delete _CPU_Context_Fp_start()

Since the FP area pointer is passed by reference in
_CPU_Context_Initialize_fp() the optional FP area adjustment via
_CPU_Context_Fp_start() is superfluous. It is also wrong with respect
to memory management, e.g. pointer passed to _Workspace_Free() may be
not the one returned by _Workspace_Allocate().

Close #1400.

  • Property mode set to 100644
File size: 30.5 KB
Line 
1/**
2 * @file
3 *
4 * @brief Blackfin CPU Department Source
5 *
6 * This include file contains information pertaining to the Blackfin
7 * processor.
8 */
9
10/*
11 *  COPYRIGHT (c) 1989-2006.
12 *  On-Line Applications Research Corporation (OAR).
13 *  adapted to Blackfin by Alain Schaefer <alain.schaefer@easc.ch>
14 *                     and Antonio Giovanini <antonio@atos.com.br>
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.org/license/LICENSE.
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/types.h>
29#include <rtems/score/bfin.h>
30
31/* conditional compilation parameters */
32
33/**
34 * Does RTEMS manage a dedicated interrupt stack in software?
35 *
36 * If TRUE, then a stack is allocated in @ref _ISR_Handler_initialization.
37 * If FALSE, nothing is done.
38 *
39 * If the CPU supports a dedicated interrupt stack in hardware,
40 * then it is generally the responsibility of the BSP to allocate it
41 * and set it up.
42 *
43 * If the CPU does not support a dedicated interrupt stack, then
44 * the porter has two options: (1) execute interrupts on the
45 * stack of the interrupted task, and (2) have RTEMS manage a dedicated
46 * interrupt stack.
47 *
48 * If this is TRUE, @ref CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
49 *
50 * Only one of @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK and
51 * @ref CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE.  It is
52 * possible that both are FALSE for a particular CPU.  Although it
53 * is unclear what that would imply about the interrupt processing
54 * procedure on that CPU.
55 *
56 * Port Specific Information:
57 *
58 * XXX document implementation including references if appropriate
59 */
60#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE
61
62/*
63 *  Does the CPU follow the simple vectored interrupt model?
64 *
65 *  If TRUE, then RTEMS allocates the vector table it internally manages.
66 *  If FALSE, then the BSP is assumed to allocate and manage the vector
67 *  table
68 *
69 *  BFIN Specific Information:
70 *
71 *  XXX document implementation including references if appropriate
72 */
73#define CPU_SIMPLE_VECTORED_INTERRUPTS TRUE
74
75/**
76 * Does this CPU have hardware support for a dedicated interrupt stack?
77 *
78 * If TRUE, then it must be installed during initialization.
79 * If FALSE, then no installation is performed.
80 *
81 * If this is TRUE, @ref CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
82 *
83 * Only one of @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK and
84 * @ref CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE.  It is
85 * possible that both are FALSE for a particular CPU.  Although it
86 * is unclear what that would imply about the interrupt processing
87 * procedure on that CPU.
88 *
89 * Port Specific Information:
90 *
91 * XXX document implementation including references if appropriate
92 */
93#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
94
95/**
96 * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
97 *
98 * If TRUE, then the memory is allocated during initialization.
99 * If FALSE, then the memory is allocated during initialization.
100 *
101 * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE.
102 *
103 * Port Specific Information:
104 *
105 * XXX document implementation including references if appropriate
106 */
107#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
108
109/**
110 * Does the RTEMS invoke the user's ISR with the vector number and
111 * a pointer to the saved interrupt frame (1) or just the vector
112 * number (0)?
113 *
114 * Port Specific Information:
115 *
116 * XXX document implementation including references if appropriate
117 */
118#define CPU_ISR_PASSES_FRAME_POINTER TRUE
119
120/**
121 * @def CPU_HARDWARE_FP
122 *
123 * Does the CPU have hardware floating point?
124 *
125 * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
126 * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
127 *
128 * If there is a FP coprocessor such as the i387 or mc68881, then
129 * the answer is TRUE.
130 *
131 * The macro name "NO_CPU_HAS_FPU" should be made CPU specific.
132 * It indicates whether or not this CPU model has FP support.  For
133 * example, it would be possible to have an i386_nofp CPU model
134 * which set this to false to indicate that you have an i386 without
135 * an i387 and wish to leave floating point support out of RTEMS.
136 */
137
138/**
139 * @def CPU_SOFTWARE_FP
140 *
141 * Does the CPU have no hardware floating point and GCC provides a
142 * software floating point implementation which must be context
143 * switched?
144 *
145 * This feature conditional is used to indicate whether or not there
146 * is software implemented floating point that must be context
147 * switched.  The determination of whether or not this applies
148 * is very tool specific and the state saved/restored is also
149 * compiler specific.
150 *
151 * Port Specific Information:
152 *
153 * XXX document implementation including references if appropriate
154 */
155#if ( BLACKFIN_CPU_HAS_FPU == 1 )
156#define CPU_HARDWARE_FP     TRUE
157#else
158#define CPU_HARDWARE_FP     FALSE
159#endif
160#define CPU_SOFTWARE_FP     FALSE
161
162/**
163 * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
164 *
165 * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
166 * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
167 *
168 * So far, the only CPUs in which this option has been used are the
169 * HP PA-RISC and PowerPC.  On the PA-RISC, The HP C compiler and
170 * gcc both implicitly used the floating point registers to perform
171 * integer multiplies.  Similarly, the PowerPC port of gcc has been
172 * seen to allocate floating point local variables and touch the FPU
173 * even when the flow through a subroutine (like vfprintf()) might
174 * not use floating point formats.
175 *
176 * If a function which you would not think utilize the FP unit DOES,
177 * then one can not easily predict which tasks will use the FP hardware.
178 * In this case, this option should be TRUE.
179 *
180 * If @ref CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
181 *
182 * Port Specific Information:
183 *
184 * XXX document implementation including references if appropriate
185 */
186#define CPU_ALL_TASKS_ARE_FP     FALSE
187
188/**
189 * Should the IDLE task have a floating point context?
190 *
191 * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
192 * and it has a floating point context which is switched in and out.
193 * If FALSE, then the IDLE task does not have a floating point context.
194 *
195 * Setting this to TRUE negatively impacts the time required to preempt
196 * the IDLE task from an interrupt because the floating point context
197 * must be saved as part of the preemption.
198 *
199 * Port Specific Information:
200 *
201 * XXX document implementation including references if appropriate
202 */
203#define CPU_IDLE_TASK_IS_FP      FALSE
204
205/**
206 * Should the saving of the floating point registers be deferred
207 * until a context switch is made to another different floating point
208 * task?
209 *
210 * If TRUE, then the floating point context will not be stored until
211 * necessary.  It will remain in the floating point registers and not
212 * disturned until another floating point task is switched to.
213 *
214 * If FALSE, then the floating point context is saved when a floating
215 * point task is switched out and restored when the next floating point
216 * task is restored.  The state of the floating point registers between
217 * those two operations is not specified.
218 *
219 * If the floating point context does NOT have to be saved as part of
220 * interrupt dispatching, then it should be safe to set this to TRUE.
221 *
222 * Setting this flag to TRUE results in using a different algorithm
223 * for deciding when to save and restore the floating point context.
224 * The deferred FP switch algorithm minimizes the number of times
225 * the FP context is saved and restored.  The FP context is not saved
226 * until a context switch is made to another, different FP task.
227 * Thus in a system with only one FP task, the FP context will never
228 * be saved or restored.
229 *
230 * Port Specific Information:
231 *
232 * XXX document implementation including references if appropriate
233 */
234#define CPU_USE_DEFERRED_FP_SWITCH       TRUE
235
236#define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
237
238/**
239 * Does this port provide a CPU dependent IDLE task implementation?
240 *
241 * If TRUE, then the routine @ref _CPU_Thread_Idle_body
242 * must be provided and is the default IDLE thread body instead of
243 * @ref _CPU_Thread_Idle_body.
244 *
245 * If FALSE, then use the generic IDLE thread body if the BSP does
246 * not provide one.
247 *
248 * This is intended to allow for supporting processors which have
249 * a low power or idle mode.  When the IDLE thread is executed, then
250 * the CPU can be powered down.
251 *
252 * The order of precedence for selecting the IDLE thread body is:
253 *
254 *   -#  BSP provided
255 *   -#  CPU dependent (if provided)
256 *   -#  generic (if no BSP and no CPU dependent)
257 *
258 * Port Specific Information:
259 *
260 * XXX document implementation including references if appropriate
261 */
262#define CPU_PROVIDES_IDLE_THREAD_BODY    TRUE
263
264/**
265 * Does the stack grow up (toward higher addresses) or down
266 * (toward lower addresses)?
267 *
268 * If TRUE, then the grows upward.
269 * If FALSE, then the grows toward smaller addresses.
270 *
271 * Port Specific Information:
272 *
273 * XXX document implementation including references if appropriate
274 */
275#define CPU_STACK_GROWS_UP               FALSE
276
277/* FIXME: Is this the right value? */
278#define CPU_CACHE_LINE_BYTES 32
279
280#define CPU_STRUCTURE_ALIGNMENT
281
282/**
283 * @ingroup CPUInterrupt
284 * The following defines the number of bits actually used in the
285 * interrupt field of the task mode.  How those bits map to the
286 * CPU interrupt levels is defined by the routine @ref _CPU_ISR_Set_level.
287 *
288 * Port Specific Information:
289 *
290 * XXX document implementation including references if appropriate
291 */
292#define CPU_MODES_INTERRUPT_MASK   0x00000001
293
294#define CPU_MAXIMUM_PROCESSORS 32
295
296/*
297 *  Processor defined structures required for cpukit/score.
298 *
299 *  Port Specific Information:
300 *
301 *  XXX document implementation including references if appropriate
302 */
303
304/* may need to put some structures here.  */
305
306#ifndef ASM
307
308/**
309 * @defgroup CPUContext Processor Dependent Context Management
310 *
311 * From the highest level viewpoint, there are 2 types of context to save.
312 *
313 *    -# Interrupt registers to save
314 *    -# Task level registers to save
315 *
316 * Since RTEMS handles integer and floating point contexts separately, this
317 * means we have the following 3 context items:
318 *
319 *    -# task level context stuff::  Context_Control
320 *    -# floating point task stuff:: Context_Control_fp
321 *    -# special interrupt level context :: CPU_Interrupt_frame
322 *
323 * On some processors, it is cost-effective to save only the callee
324 * preserved registers during a task context switch.  This means
325 * that the ISR code needs to save those registers which do not
326 * persist across function calls.  It is not mandatory to make this
327 * distinctions between the caller/callee saves registers for the
328 * purpose of minimizing context saved during task switch and on interrupts.
329 * If the cost of saving extra registers is minimal, simplicity is the
330 * choice.  Save the same context on interrupt entry as for tasks in
331 * this case.
332 *
333 * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
334 * care should be used in designing the context area.
335 *
336 * On some CPUs with hardware floating point support, the Context_Control_fp
337 * structure will not be used or it simply consist of an array of a
338 * fixed number of bytes.   This is done when the floating point context
339 * is dumped by a "FP save context" type instruction and the format
340 * is not really defined by the CPU.  In this case, there is no need
341 * to figure out the exact format -- only the size.  Of course, although
342 * this is enough information for RTEMS, it is probably not enough for
343 * a debugger such as gdb.  But that is another problem.
344 *
345 * Port Specific Information:
346 *
347 * XXX document implementation including references if appropriate
348 */
349/**@{**/
350
351/**
352 * This defines the minimal set of integer and processor state registers
353 * that must be saved during a voluntary context switch from one thread
354 * to another.
355 */
356
357/* make sure this stays in sync with the assembly function
358   __CPU_Context_switch in cpu_asm.S  */
359typedef struct {
360    uint32_t   register_r4;
361    uint32_t   register_r5;
362    uint32_t   register_r6;
363    uint32_t   register_r7;
364
365    uint32_t   register_p3;
366    uint32_t   register_p4;
367    uint32_t   register_p5;
368    uint32_t   register_fp;
369    uint32_t   register_sp;
370
371    uint32_t   register_rets;
372
373    uint32_t   imask;
374} Context_Control;
375
376#define _CPU_Context_Get_SP( _context ) \
377  (_context)->register_sp
378
379/**
380 * This defines the complete set of floating point registers that must
381 * be saved during any context switch from one thread to another.
382 */
383typedef struct {
384    /* FPU registers are listed here */
385    /* Blackfin has no Floating Point */
386} Context_Control_fp;
387
388/**
389 * This defines the set of integer and processor state registers that must
390 * be saved during an interrupt.  This set does not include any which are
391 * in @ref Context_Control.
392 */
393typedef struct {
394    /** This field is a hint that a port will have a number of integer
395     * registers that need to be saved when an interrupt occurs or
396     * when a context switch occurs at the end of an ISR.
397     */
398    /*uint32_t   special_interrupt_register;*/
399} CPU_Interrupt_frame;
400
401/** @} */
402
403/**
404 * @defgroup CPUInterrupt Processor Dependent Interrupt Management
405 *
406 * On some CPUs, RTEMS supports a software managed interrupt stack.
407 * This stack is allocated by the Interrupt Manager and the switch
408 * is performed in @ref _ISR_Handler.  These variables contain pointers
409 * to the lowest and highest addresses in the chunk of memory allocated
410 * for the interrupt stack.  Since it is unknown whether the stack
411 * grows up or down (in general), this give the CPU dependent
412 * code the option of picking the version it wants to use.
413 *
414 * @note These two variables are required if the macro
415 *       @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
416 *
417 * Port Specific Information:
418 *
419 * XXX document implementation including references if appropriate
420 */
421/**@{**/
422
423/*
424 *  Nothing prevents the porter from declaring more CPU specific variables.
425 *
426 *  Port Specific Information:
427 *
428 *  XXX document implementation including references if appropriate
429 */
430
431/* XXX: if needed, put more variables here */
432
433/**
434 * @ingroup CPUContext
435 * The size of the floating point context area.  On some CPUs this
436 * will not be a "sizeof" because the format of the floating point
437 * area is not defined -- only the size is.  This is usually on
438 * CPUs with a "floating point save context" instruction.
439 *
440 * Port Specific Information:
441 *
442 * XXX document implementation including references if appropriate
443 */
444#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
445
446#endif /* ASM */
447
448/**
449 * Amount of extra stack (above minimum stack size) required by
450 * MPCI receive server thread.  Remember that in a multiprocessor
451 * system this thread must exist and be able to process all directives.
452 *
453 * Port Specific Information:
454 *
455 * XXX document implementation including references if appropriate
456 */
457#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
458
459/**
460 * @ingroup CPUInterrupt
461 * This defines the number of entries in the @ref _ISR_Vector_table managed
462 * by RTEMS.
463 *
464 * Port Specific Information:
465 *
466 * XXX document implementation including references if appropriate
467 */
468#define CPU_INTERRUPT_NUMBER_OF_VECTORS      16
469
470/**
471 * @ingroup CPUInterrupt
472 * This defines the highest interrupt vector number for this port.
473 */
474#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER  (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
475
476/**
477 * @ingroup CPUInterrupt
478 * This is defined if the port has a special way to report the ISR nesting
479 * level.  Most ports maintain the variable @a _ISR_Nest_level.
480 */
481#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
482
483/** @} */
484
485/**
486 * @ingroup CPUContext
487 * Should be large enough to run all RTEMS tests.  This ensures
488 * that a "reasonable" small application should not have any problems.
489 *
490 * Port Specific Information:
491 *
492 * XXX document implementation including references if appropriate
493 */
494#define CPU_STACK_MINIMUM_SIZE          (1024*8)
495
496#define CPU_SIZEOF_POINTER 4
497
498/**
499 * CPU's worst alignment requirement for data types on a byte boundary.  This
500 * alignment does not take into account the requirements for the stack.
501 *
502 * Port Specific Information:
503 *
504 * XXX document implementation including references if appropriate
505 */
506#define CPU_ALIGNMENT              8
507
508/**
509 * This number corresponds to the byte alignment requirement for the
510 * heap handler.  This alignment requirement may be stricter than that
511 * for the data types alignment specified by @ref CPU_ALIGNMENT.  It is
512 * common for the heap to follow the same alignment requirement as
513 * @ref CPU_ALIGNMENT.  If the @ref CPU_ALIGNMENT is strict enough for
514 * the heap, then this should be set to @ref CPU_ALIGNMENT.
515 *
516 * @note  This does not have to be a power of 2 although it should be
517 *        a multiple of 2 greater than or equal to 2.  The requirement
518 *        to be a multiple of 2 is because the heap uses the least
519 *        significant field of the front and back flags to indicate
520 *        that a block is in use or free.  So you do not want any odd
521 *        length blocks really putting length data in that bit.
522 *
523 *        On byte oriented architectures, @ref CPU_HEAP_ALIGNMENT normally will
524 *        have to be greater or equal to than @ref CPU_ALIGNMENT to ensure that
525 *        elements allocated from the heap meet all restrictions.
526 *
527 * Port Specific Information:
528 *
529 * XXX document implementation including references if appropriate
530 */
531#define CPU_HEAP_ALIGNMENT         CPU_ALIGNMENT
532
533/**
534 * This number corresponds to the byte alignment requirement for memory
535 * buffers allocated by the partition manager.  This alignment requirement
536 * may be stricter than that for the data types alignment specified by
537 * @ref CPU_ALIGNMENT.  It is common for the partition to follow the same
538 * alignment requirement as @ref CPU_ALIGNMENT.  If the @ref CPU_ALIGNMENT is
539 * strict enough for the partition, then this should be set to
540 * @ref CPU_ALIGNMENT.
541 *
542 * @note  This does not have to be a power of 2.  It does have to
543 *        be greater or equal to than @ref CPU_ALIGNMENT.
544 *
545 * Port Specific Information:
546 *
547 * XXX document implementation including references if appropriate
548 */
549#define CPU_PARTITION_ALIGNMENT    CPU_ALIGNMENT
550
551/**
552 * This number corresponds to the byte alignment requirement for the
553 * stack.  This alignment requirement may be stricter than that for the
554 * data types alignment specified by @ref CPU_ALIGNMENT.  If the
555 * @ref CPU_ALIGNMENT is strict enough for the stack, then this should be
556 * set to 0.
557 *
558 * @note This must be a power of 2 either 0 or greater than @ref CPU_ALIGNMENT.
559 *
560 * Port Specific Information:
561 *
562 * XXX document implementation including references if appropriate
563 */
564#define CPU_STACK_ALIGNMENT        8
565
566#ifndef ASM
567
568/*
569 *  ISR handler macros
570 */
571
572/**
573 * @addtogroup CPUInterrupt
574 */
575/**@{**/
576
577/**
578 * Support routine to initialize the RTEMS vector table after it is allocated.
579 *
580 * Port Specific Information:
581 *
582 * XXX document implementation including references if appropriate
583 */
584#define _CPU_Initialize_vectors()
585
586/**
587 * Disable all interrupts for an RTEMS critical section.  The previous
588 * level is returned in @a _isr_cookie.
589 *
590 * @param[out] _isr_cookie will contain the previous level cookie
591 *
592 * Port Specific Information:
593 *
594 * XXX document implementation including references if appropriate
595 */
596#define _CPU_ISR_Disable( _level ) \
597  {                                     \
598       __asm__ volatile ("cli %0; csync \n" : "=d" (_level) );     \
599  }
600
601
602/**
603 * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
604 * This indicates the end of an RTEMS critical section.  The parameter
605 * @a _isr_cookie is not modified.
606 *
607 * @param[in] _isr_cookie contain the previous level cookie
608 *
609 * Port Specific Information:
610 *
611 * XXX document implementation including references if appropriate
612 */
613#define _CPU_ISR_Enable( _level ) { \
614    __asm__ __volatile__ ("sti %0; csync \n" : : "d" (_level) );   \
615  }
616
617/**
618 * This temporarily restores the interrupt to @a _isr_cookie before immediately
619 * disabling them again.  This is used to divide long RTEMS critical
620 * sections into two or more parts.  The parameter @a _isr_cookie is not
621 * modified.
622 *
623 * @param[in] _isr_cookie contain the previous level cookie
624 *
625 * Port Specific Information:
626 *
627 * XXX document implementation including references if appropriate
628 */
629#define _CPU_ISR_Flash( _level ) { \
630    __asm__ __volatile__ ("sti %0; csync; cli r0; csync" \
631                          : : "d"(_level) : "R0" ); \
632  }
633
634RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint32_t level )
635{
636  return level != 0;
637}
638
639/**
640 * This routine and @ref _CPU_ISR_Get_level
641 * Map the interrupt level in task mode onto the hardware that the CPU
642 * actually provides.  Currently, interrupt levels which do not
643 * map onto the CPU in a generic fashion are undefined.  Someday,
644 * it would be nice if these were "mapped" by the application
645 * via a callout.  For example, m68k has 8 levels 0 - 7, levels
646 * 8 - 255 would be available for bsp/application specific meaning.
647 * This could be used to manage a programmable interrupt controller
648 * via the rtems_task_mode directive.
649 *
650 * Port Specific Information:
651 *
652 * XXX document implementation including references if appropriate
653 */
654#define _CPU_ISR_Set_level( _new_level ) \
655  { \
656    __asm__ __volatile__ ( "sti %0; csync" : : "d"(_new_level ? 0 : 0xffff) ); \
657  }
658
659/**
660 * Return the current interrupt disable level for this task in
661 * the format used by the interrupt level portion of the task mode.
662 *
663 * @note This routine usually must be implemented as a subroutine.
664 *
665 * Port Specific Information:
666 *
667 * XXX document implementation including references if appropriate
668 */
669uint32_t   _CPU_ISR_Get_level( void );
670
671/* end of ISR handler macros */
672
673/** @} */
674
675/* Context handler macros */
676
677/**
678 * @ingroup CPUContext
679 * Initialize the context to a state suitable for starting a
680 * task after a context restore operation.  Generally, this
681 * involves:
682 *
683 *    - setting a starting address
684 *    - preparing the stack
685 *    - preparing the stack and frame pointers
686 *    - setting the proper interrupt level in the context
687 *    - initializing the floating point context
688 *
689 * This routine generally does not set any unnecessary register
690 * in the context.  The state of the "general data" registers is
691 * undefined at task start time.
692 *
693 * @param[in] _the_context is the context structure to be initialized
694 * @param[in] _stack_base is the lowest physical address of this task's stack
695 * @param[in] _size is the size of this task's stack
696 * @param[in] _isr is the interrupt disable level
697 * @param[in] _entry_point is the thread's entry point.  This is
698 *        always @a _Thread_Handler
699 * @param[in] _is_fp is TRUE if the thread is to be a floating
700 *       point thread.  This is typically only used on CPUs where the
701 *       FPU may be easily disabled by software such as on the SPARC
702 *       where the PSR contains an enable FPU bit.
703 * @param[in] tls_area is the thread-local storage (TLS) area
704 *
705 * Port Specific Information:
706 *
707 * See implementation in cpu.c
708 */
709void _CPU_Context_Initialize(
710  Context_Control  *the_context,
711  uint32_t         *stack_base,
712  uint32_t          size,
713  uint32_t          new_level,
714  void             *entry_point,
715  bool              is_fp,
716  void             *tls_area
717);
718
719/**
720 * This routine is responsible for somehow restarting the currently
721 * executing task.  If you are lucky, then all that is necessary
722 * is restoring the context.  Otherwise, there will need to be
723 * a special assembly routine which does something special in this
724 * case.  For many ports, simply adding a label to the restore path
725 * of @ref _CPU_Context_switch will work.  On other ports, it may be
726 * possibly to load a few arguments and jump to the restore path. It will
727 * not work if restarting self conflicts with the stack frame
728 * assumptions of restoring a context.
729 *
730 * Port Specific Information:
731 *
732 * XXX document implementation including references if appropriate
733 */
734#define _CPU_Context_Restart_self( _the_context ) \
735   _CPU_Context_restore( (_the_context) );
736
737#define _CPU_Context_Initialize_fp( _destination ) \
738  memset( *( _destination ), 0, CPU_CONTEXT_FP_SIZE );
739
740/* end of Context handler macros */
741
742/* Fatal Error manager macros */
743
744/**
745 * This routine copies _error into a known place -- typically a stack
746 * location or a register, optionally disables interrupts, and
747 * halts/stops the CPU.
748 *
749 * Port Specific Information:
750 *
751 * XXX document implementation including references if appropriate
752 */
753#define _CPU_Fatal_halt( _source, _error ) \
754  { \
755    __asm__ volatile ( "cli R1; \
756                    R1 = %0; \
757                    _halt: \
758                    idle; \
759                    jump _halt;"\
760                    : : "r" (_error) ); \
761  }
762
763/* end of Fatal Error manager macros */
764
765#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
766
767/* functions */
768
769/**
770 * @brief CPU initialize.
771 * This routine performs CPU dependent initialization.
772 *
773 * Port Specific Information:
774 *
775 * XXX document implementation including references if appropriate
776 */
777void _CPU_Initialize(void);
778
779/**
780 * @ingroup CPUInterrupt
781 * This routine installs a "raw" interrupt handler directly into the
782 * processor's vector table.
783 *
784 * @param[in] vector is the vector number
785 * @param[in] new_handler is the raw ISR handler to install
786 * @param[in] old_handler is the previously installed ISR Handler
787 *
788 * Port Specific Information:
789 *
790 * XXX document implementation including references if appropriate
791 */
792void _CPU_ISR_install_raw_handler(
793  uint32_t    vector,
794  proc_ptr    new_handler,
795  proc_ptr   *old_handler
796);
797
798/**
799 * @ingroup CPUInterrupt
800 * This routine installs an interrupt vector.
801 *
802 * @param[in] vector is the vector number
803 * @param[in] new_handler is the RTEMS ISR handler to install
804 * @param[in] old_handler is the previously installed ISR Handler
805 *
806 * Port Specific Information:
807 *
808 * XXX document implementation including references if appropriate
809 */
810void _CPU_ISR_install_vector(
811  uint32_t    vector,
812  proc_ptr    new_handler,
813  proc_ptr   *old_handler
814);
815
816/**
817 * @ingroup CPUInterrupt
818 * This routine installs the hardware interrupt stack pointer.
819 *
820 * @note  It need only be provided if @ref CPU_HAS_HARDWARE_INTERRUPT_STACK
821 *        is TRUE.
822 *
823 * Port Specific Information:
824 *
825 * XXX document implementation including references if appropriate
826 */
827void _CPU_Install_interrupt_stack( void );
828
829/**
830 * This routine is the CPU dependent IDLE thread body.
831 *
832 * @note  It need only be provided if @ref CPU_PROVIDES_IDLE_THREAD_BODY
833 *        is TRUE.
834 *
835 * Port Specific Information:
836 *
837 * XXX document implementation including references if appropriate
838 */
839void *_CPU_Thread_Idle_body( uintptr_t ignored );
840
841/**
842 * @addtogroup CPUContext
843 */
844/**@{**/
845
846/**
847 * This routine switches from the run context to the heir context.
848 *
849 * @param[in] run points to the context of the currently executing task
850 * @param[in] heir points to the context of the heir task
851 *
852 * Port Specific Information:
853 *
854 * XXX document implementation including references if appropriate
855 */
856void _CPU_Context_switch(
857  Context_Control  *run,
858  Context_Control  *heir
859);
860
861/**
862 * This routine is generally used only to restart self in an
863 * efficient manner.  It may simply be a label in @ref _CPU_Context_switch.
864 *
865 * @param[in] new_context points to the context to be restored.
866 *
867 * @note May be unnecessary to reload some registers.
868 *
869 * Port Specific Information:
870 *
871 * XXX document implementation including references if appropriate
872 */
873void _CPU_Context_restore(
874  Context_Control *new_context
875) RTEMS_NO_RETURN;
876
877/**
878 * This routine saves the floating point context passed to it.
879 *
880 * @param[in] fp_context_ptr is a pointer to a pointer to a floating
881 * point context area
882 *
883 * @return on output @a *fp_context_ptr will contain the address that
884 * should be used with @ref _CPU_Context_restore_fp to restore this context.
885 *
886 * Port Specific Information:
887 *
888 * XXX document implementation including references if appropriate
889 */
890void _CPU_Context_save_fp(
891  Context_Control_fp **fp_context_ptr
892);
893
894/**
895 * This routine restores the floating point context passed to it.
896 *
897 * @param[in] fp_context_ptr is a pointer to a pointer to a floating
898 * point context area to restore
899 *
900 * @return on output @a *fp_context_ptr will contain the address that
901 * should be used with @ref _CPU_Context_save_fp to save this context.
902 *
903 * Port Specific Information:
904 *
905 * XXX document implementation including references if appropriate
906 */
907void _CPU_Context_restore_fp(
908  Context_Control_fp **fp_context_ptr
909);
910
911static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
912{
913  /* TODO */
914}
915
916static inline void _CPU_Context_validate( uintptr_t pattern )
917{
918  while (1) {
919    /* TODO */
920  }
921}
922
923/** @} */
924
925/* FIXME */
926typedef CPU_Interrupt_frame CPU_Exception_frame;
927
928void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
929
930/**
931 * @ingroup CPUEndian
932 * The following routine swaps the endian format of an unsigned int.
933 * It must be static because it is referenced indirectly.
934 *
935 * This version will work on any processor, but if there is a better
936 * way for your CPU PLEASE use it.  The most common way to do this is to:
937 *
938 *    swap least significant two bytes with 16-bit rotate
939 *    swap upper and lower 16-bits
940 *    swap most significant two bytes with 16-bit rotate
941 *
942 * Some CPUs have special instructions which swap a 32-bit quantity in
943 * a single instruction (e.g. i486).  It is probably best to avoid
944 * an "endian swapping control bit" in the CPU.  One good reason is
945 * that interrupts would probably have to be disabled to ensure that
946 * an interrupt does not try to access the same "chunk" with the wrong
947 * endian.  Another good reason is that on some CPUs, the endian bit
948 * endianness for ALL fetches -- both code and data -- so the code
949 * will be fetched incorrectly.
950 *
951 * @param[in] value is the value to be swapped
952 * @return the value after being endian swapped
953 *
954 * Port Specific Information:
955 *
956 * XXX document implementation including references if appropriate
957 */
958static inline uint32_t CPU_swap_u32(
959  uint32_t value
960)
961{
962  uint32_t   byte1, byte2, byte3, byte4, swapped;
963
964  byte4 = (value >> 24) & 0xff;
965  byte3 = (value >> 16) & 0xff;
966  byte2 = (value >> 8)  & 0xff;
967  byte1 =  value        & 0xff;
968
969  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
970  return( swapped );
971}
972
973/**
974 * @ingroup CPUEndian
975 * This routine swaps a 16 bir quantity.
976 *
977 * @param[in] value is the value to be swapped
978 * @return the value after being endian swapped
979 */
980#define CPU_swap_u16( value ) \
981  (((value&0xff) << 8) | ((value >> 8)&0xff))
982
983typedef uint32_t CPU_Counter_ticks;
984
985CPU_Counter_ticks _CPU_Counter_read( void );
986
987static inline CPU_Counter_ticks _CPU_Counter_difference(
988  CPU_Counter_ticks second,
989  CPU_Counter_ticks first
990)
991{
992  return second - first;
993}
994
995#endif /* ASM */
996
997#ifdef __cplusplus
998}
999#endif
1000
1001#endif
Note: See TracBrowser for help on using the repository browser.