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 01/25/17 at 13:32:02

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
RevLine 
[d9a6ab3]1/**
[4f5740f]2 * @file
3 *
4 * @brief Blackfin CPU Department Source
5 *
6 * This include file contains information pertaining to the Blackfin
7 * processor.
[d9a6ab3]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
[c499856]18 *  http://www.rtems.org/license/LICENSE.
[d9a6ab3]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>
[89b85e51]29#include <rtems/score/bfin.h>
[d9a6ab3]30
31/* conditional compilation parameters */
32
33/**
[4f5740f]34 * Does RTEMS manage a dedicated interrupt stack in software?
[d9a6ab3]35 *
[4f5740f]36 * If TRUE, then a stack is allocated in @ref _ISR_Handler_initialization.
37 * If FALSE, nothing is done.
[d9a6ab3]38 *
[4f5740f]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.
[d9a6ab3]42 *
[4f5740f]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.
[d9a6ab3]47 *
[4f5740f]48 * If this is TRUE, @ref CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
[d9a6ab3]49 *
[4f5740f]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.
[d9a6ab3]55 *
[4f5740f]56 * Port Specific Information:
[d9a6ab3]57 *
[4f5740f]58 * XXX document implementation including references if appropriate
[d9a6ab3]59 */
[4daebbd]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
[d9a6ab3]74
75/**
[4f5740f]76 * Does this CPU have hardware support for a dedicated interrupt stack?
[d9a6ab3]77 *
[4f5740f]78 * If TRUE, then it must be installed during initialization.
79 * If FALSE, then no installation is performed.
[d9a6ab3]80 *
[4f5740f]81 * If this is TRUE, @ref CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
[d9a6ab3]82 *
[4f5740f]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.
[d9a6ab3]88 *
[4f5740f]89 * Port Specific Information:
[d9a6ab3]90 *
[4f5740f]91 * XXX document implementation including references if appropriate
[d9a6ab3]92 */
93#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
94
95/**
[4f5740f]96 * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
[d9a6ab3]97 *
[4f5740f]98 * If TRUE, then the memory is allocated during initialization.
99 * If FALSE, then the memory is allocated during initialization.
[d9a6ab3]100 *
[4f5740f]101 * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE.
[d9a6ab3]102 *
[4f5740f]103 * Port Specific Information:
[d9a6ab3]104 *
[4f5740f]105 * XXX document implementation including references if appropriate
[d9a6ab3]106 */
[4daebbd]107#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
[d9a6ab3]108
109/**
[4f5740f]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)?
[d9a6ab3]113 *
[4f5740f]114 * Port Specific Information:
[d9a6ab3]115 *
[4f5740f]116 * XXX document implementation including references if appropriate
[d9a6ab3]117 */
[141e16d]118#define CPU_ISR_PASSES_FRAME_POINTER TRUE
[d9a6ab3]119
120/**
[4f5740f]121 * @def CPU_HARDWARE_FP
[d9a6ab3]122 *
[4f5740f]123 * Does the CPU have hardware floating point?
[d9a6ab3]124 *
[4f5740f]125 * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
126 * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
[d9a6ab3]127 *
[4f5740f]128 * If there is a FP coprocessor such as the i387 or mc68881, then
129 * the answer is TRUE.
[d9a6ab3]130 *
[4f5740f]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.
[d9a6ab3]136 */
137
[42e243e]138/**
[4f5740f]139 * @def CPU_SOFTWARE_FP
[d9a6ab3]140 *
[4f5740f]141 * Does the CPU have no hardware floating point and GCC provides a
142 * software floating point implementation which must be context
143 * switched?
[d9a6ab3]144 *
[4f5740f]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.
[d9a6ab3]150 *
[4f5740f]151 * Port Specific Information:
[d9a6ab3]152 *
[4f5740f]153 * XXX document implementation including references if appropriate
[d9a6ab3]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/**
[4f5740f]163 * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
[d9a6ab3]164 *
[4f5740f]165 * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
166 * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
[d9a6ab3]167 *
[4f5740f]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.
[d9a6ab3]175 *
[4f5740f]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.
[d9a6ab3]179 *
[4f5740f]180 * If @ref CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
[d9a6ab3]181 *
[4f5740f]182 * Port Specific Information:
[d9a6ab3]183 *
[4f5740f]184 * XXX document implementation including references if appropriate
[d9a6ab3]185 */
186#define CPU_ALL_TASKS_ARE_FP     FALSE
187
188/**
[4f5740f]189 * Should the IDLE task have a floating point context?
[d9a6ab3]190 *
[4f5740f]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.
[d9a6ab3]194 *
[4f5740f]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.
[d9a6ab3]198 *
[4f5740f]199 * Port Specific Information:
[d9a6ab3]200 *
[4f5740f]201 * XXX document implementation including references if appropriate
[d9a6ab3]202 */
203#define CPU_IDLE_TASK_IS_FP      FALSE
204
205/**
[4f5740f]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?
[d9a6ab3]209 *
[4f5740f]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.
[d9a6ab3]213 *
[4f5740f]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.
[d9a6ab3]218 *
[4f5740f]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.
[d9a6ab3]221 *
[4f5740f]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.
[d9a6ab3]229 *
[4f5740f]230 * Port Specific Information:
[d9a6ab3]231 *
[4f5740f]232 * XXX document implementation including references if appropriate
[d9a6ab3]233 */
234#define CPU_USE_DEFERRED_FP_SWITCH       TRUE
235
[84e6f15]236#define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
237
[d9a6ab3]238/**
[4f5740f]239 * Does this port provide a CPU dependent IDLE task implementation?
[d9a6ab3]240 *
[4f5740f]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.
[d9a6ab3]244 *
[4f5740f]245 * If FALSE, then use the generic IDLE thread body if the BSP does
246 * not provide one.
[d9a6ab3]247 *
[4f5740f]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.
[d9a6ab3]251 *
[4f5740f]252 * The order of precedence for selecting the IDLE thread body is:
[d9a6ab3]253 *
[4f5740f]254 *   -#  BSP provided
255 *   -#  CPU dependent (if provided)
256 *   -#  generic (if no BSP and no CPU dependent)
[d9a6ab3]257 *
[4f5740f]258 * Port Specific Information:
[d9a6ab3]259 *
[4f5740f]260 * XXX document implementation including references if appropriate
[d9a6ab3]261 */
[4daebbd]262#define CPU_PROVIDES_IDLE_THREAD_BODY    TRUE
[d9a6ab3]263
264/**
[4f5740f]265 * Does the stack grow up (toward higher addresses) or down
266 * (toward lower addresses)?
[d9a6ab3]267 *
[4f5740f]268 * If TRUE, then the grows upward.
269 * If FALSE, then the grows toward smaller addresses.
[d9a6ab3]270 *
[4f5740f]271 * Port Specific Information:
[d9a6ab3]272 *
[4f5740f]273 * XXX document implementation including references if appropriate
[d9a6ab3]274 */
275#define CPU_STACK_GROWS_UP               FALSE
276
[a8865f8]277/* FIXME: Is this the right value? */
278#define CPU_CACHE_LINE_BYTES 32
279
[42e243e]280#define CPU_STRUCTURE_ALIGNMENT
[d9a6ab3]281
282/**
[4f5740f]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.
[d9a6ab3]287 *
[4f5740f]288 * Port Specific Information:
[d9a6ab3]289 *
[4f5740f]290 * XXX document implementation including references if appropriate
[d9a6ab3]291 */
[d902069]292#define CPU_MODES_INTERRUPT_MASK   0x00000001
[d9a6ab3]293
[decff899]294#define CPU_MAXIMUM_PROCESSORS 32
295
[d9a6ab3]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
[10fd4aac]306#ifndef ASM
307
[d9a6ab3]308/**
309 * @defgroup CPUContext Processor Dependent Context Management
310 *
[4f5740f]311 * From the highest level viewpoint, there are 2 types of context to save.
[d9a6ab3]312 *
[4f5740f]313 *    -# Interrupt registers to save
314 *    -# Task level registers to save
[d9a6ab3]315 *
[4f5740f]316 * Since RTEMS handles integer and floating point contexts separately, this
317 * means we have the following 3 context items:
[d9a6ab3]318 *
[4f5740f]319 *    -# task level context stuff::  Context_Control
320 *    -# floating point task stuff:: Context_Control_fp
321 *    -# special interrupt level context :: CPU_Interrupt_frame
[d9a6ab3]322 *
[4f5740f]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.
[d9a6ab3]332 *
[4f5740f]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.
[d9a6ab3]335 *
[4f5740f]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.
[d9a6ab3]344 *
[4f5740f]345 * Port Specific Information:
[d9a6ab3]346 *
[4f5740f]347 * XXX document implementation including references if appropriate
[d9a6ab3]348 */
[b697bc6]349/**@{**/
[d9a6ab3]350
351/**
[4f5740f]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.
[d9a6ab3]355 */
[4daebbd]356
357/* make sure this stays in sync with the assembly function
358   __CPU_Context_switch in cpu_asm.S  */
[d9a6ab3]359typedef struct {
360    uint32_t   register_r4;
361    uint32_t   register_r5;
362    uint32_t   register_r6;
363    uint32_t   register_r7;
[4daebbd]364
[d9a6ab3]365    uint32_t   register_p3;
366    uint32_t   register_p4;
[42e243e]367    uint32_t   register_p5;
[d9a6ab3]368    uint32_t   register_fp;
369    uint32_t   register_sp;
[42e243e]370
[d9a6ab3]371    uint32_t   register_rets;
[4daebbd]372
[42e243e]373    uint32_t   imask;
[d9a6ab3]374} Context_Control;
375
[0ca6d0d9]376#define _CPU_Context_Get_SP( _context ) \
[47751810]377  (_context)->register_sp
[0ca6d0d9]378
[d9a6ab3]379/**
[4f5740f]380 * This defines the complete set of floating point registers that must
381 * be saved during any context switch from one thread to another.
[d9a6ab3]382 */
383typedef struct {
384    /* FPU registers are listed here */
385    /* Blackfin has no Floating Point */
386} Context_Control_fp;
387
388/**
[4f5740f]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.
[d9a6ab3]392 */
393typedef struct {
[42e243e]394    /** This field is a hint that a port will have a number of integer
[4f5740f]395     * registers that need to be saved when an interrupt occurs or
396     * when a context switch occurs at the end of an ISR.
[d9a6ab3]397     */
398    /*uint32_t   special_interrupt_register;*/
399} CPU_Interrupt_frame;
400
[4f5740f]401/** @} */
402
[d9a6ab3]403/**
[4f5740f]404 * @defgroup CPUInterrupt Processor Dependent Interrupt Management
[d9a6ab3]405 *
[4f5740f]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.
[d9a6ab3]413 *
[4f5740f]414 * @note These two variables are required if the macro
415 *       @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
[d9a6ab3]416 *
[4f5740f]417 * Port Specific Information:
[d9a6ab3]418 *
[4f5740f]419 * XXX document implementation including references if appropriate
[d9a6ab3]420 */
[b697bc6]421/**@{**/
[d9a6ab3]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/**
[4f5740f]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.
[d9a6ab3]439 *
[4f5740f]440 * Port Specific Information:
[d9a6ab3]441 *
[4f5740f]442 * XXX document implementation including references if appropriate
[d9a6ab3]443 */
444#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
445
[6ff19253]446#endif /* ASM */
447
[d9a6ab3]448/**
[4f5740f]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.
[d9a6ab3]452 *
[4f5740f]453 * Port Specific Information:
[d9a6ab3]454 *
[4f5740f]455 * XXX document implementation including references if appropriate
[d9a6ab3]456 */
457#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
458
459/**
[4f5740f]460 * @ingroup CPUInterrupt
461 * This defines the number of entries in the @ref _ISR_Vector_table managed
462 * by RTEMS.
[d9a6ab3]463 *
[4f5740f]464 * Port Specific Information:
[d9a6ab3]465 *
[4f5740f]466 * XXX document implementation including references if appropriate
[d9a6ab3]467 */
468#define CPU_INTERRUPT_NUMBER_OF_VECTORS      16
469
470/**
[4f5740f]471 * @ingroup CPUInterrupt
472 * This defines the highest interrupt vector number for this port.
[d9a6ab3]473 */
474#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER  (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
475
476/**
[4f5740f]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.
[d9a6ab3]480 */
481#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
482
[4f5740f]483/** @} */
484
[d9a6ab3]485/**
[4f5740f]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.
[d9a6ab3]489 *
[4f5740f]490 * Port Specific Information:
[d9a6ab3]491 *
[4f5740f]492 * XXX document implementation including references if appropriate
[d9a6ab3]493 */
[ca11004d]494#define CPU_STACK_MINIMUM_SIZE          (1024*8)
[d9a6ab3]495
[f1738ed]496#define CPU_SIZEOF_POINTER 4
497
[d9a6ab3]498/**
[4f5740f]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.
[d9a6ab3]501 *
[4f5740f]502 * Port Specific Information:
[d9a6ab3]503 *
[4f5740f]504 * XXX document implementation including references if appropriate
[d9a6ab3]505 */
506#define CPU_ALIGNMENT              8
507
508/**
[4f5740f]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.
[d9a6ab3]515 *
[4f5740f]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.
[d9a6ab3]522 *
[4f5740f]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.
[d9a6ab3]526 *
[4f5740f]527 * Port Specific Information:
[d9a6ab3]528 *
[4f5740f]529 * XXX document implementation including references if appropriate
[d9a6ab3]530 */
531#define CPU_HEAP_ALIGNMENT         CPU_ALIGNMENT
532
533/**
[4f5740f]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.
[d9a6ab3]541 *
[4f5740f]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.
[d9a6ab3]544 *
[4f5740f]545 * Port Specific Information:
[d9a6ab3]546 *
[4f5740f]547 * XXX document implementation including references if appropriate
[d9a6ab3]548 */
549#define CPU_PARTITION_ALIGNMENT    CPU_ALIGNMENT
550
551/**
[4f5740f]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.
[d9a6ab3]557 *
[4f5740f]558 * @note This must be a power of 2 either 0 or greater than @ref CPU_ALIGNMENT.
[d9a6ab3]559 *
[4f5740f]560 * Port Specific Information:
[d9a6ab3]561 *
[4f5740f]562 * XXX document implementation including references if appropriate
[d9a6ab3]563 */
[ca11004d]564#define CPU_STACK_ALIGNMENT        8
[d9a6ab3]565
[c6f446b]566#ifndef ASM
567
[d9a6ab3]568/*
569 *  ISR handler macros
570 */
571
572/**
[4f5740f]573 * @addtogroup CPUInterrupt
574 */
[b697bc6]575/**@{**/
[4f5740f]576
577/**
578 * Support routine to initialize the RTEMS vector table after it is allocated.
[d9a6ab3]579 *
[4f5740f]580 * Port Specific Information:
581 *
582 * XXX document implementation including references if appropriate
[d9a6ab3]583 */
584#define _CPU_Initialize_vectors()
585
586/**
[4f5740f]587 * Disable all interrupts for an RTEMS critical section.  The previous
588 * level is returned in @a _isr_cookie.
[d9a6ab3]589 *
[4f5740f]590 * @param[out] _isr_cookie will contain the previous level cookie
[d9a6ab3]591 *
[4f5740f]592 * Port Specific Information:
[d9a6ab3]593 *
[4f5740f]594 * XXX document implementation including references if appropriate
[d9a6ab3]595 */
596#define _CPU_ISR_Disable( _level ) \
597  {                                     \
[566fa34]598       __asm__ volatile ("cli %0; csync \n" : "=d" (_level) );     \
[d9a6ab3]599  }
[42e243e]600
[d9a6ab3]601
602/**
[4f5740f]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.
[d9a6ab3]606 *
[4f5740f]607 * @param[in] _isr_cookie contain the previous level cookie
[d9a6ab3]608 *
[4f5740f]609 * Port Specific Information:
[d9a6ab3]610 *
[4f5740f]611 * XXX document implementation including references if appropriate
[d9a6ab3]612 */
[4daebbd]613#define _CPU_ISR_Enable( _level ) { \
[c7935a4a]614    __asm__ __volatile__ ("sti %0; csync \n" : : "d" (_level) );   \
[d9a6ab3]615  }
616
617/**
[4f5740f]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.
[d9a6ab3]622 *
[4f5740f]623 * @param[in] _isr_cookie contain the previous level cookie
[d9a6ab3]624 *
[4f5740f]625 * Port Specific Information:
[d9a6ab3]626 *
[4f5740f]627 * XXX document implementation including references if appropriate
[d9a6ab3]628 */
[4daebbd]629#define _CPU_ISR_Flash( _level ) { \
[c7935a4a]630    __asm__ __volatile__ ("sti %0; csync; cli r0; csync" \
631                          : : "d"(_level) : "R0" ); \
[4daebbd]632  }
[d9a6ab3]633
[408609f6]634RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint32_t level )
635{
636  return level != 0;
637}
638
[d9a6ab3]639/**
[4f5740f]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.
[d9a6ab3]649 *
[4f5740f]650 * Port Specific Information:
[d9a6ab3]651 *
[4f5740f]652 * XXX document implementation including references if appropriate
[d9a6ab3]653 */
654#define _CPU_ISR_Set_level( _new_level ) \
655  { \
[c7935a4a]656    __asm__ __volatile__ ( "sti %0; csync" : : "d"(_new_level ? 0 : 0xffff) ); \
[d9a6ab3]657  }
658
659/**
[4f5740f]660 * Return the current interrupt disable level for this task in
661 * the format used by the interrupt level portion of the task mode.
[d9a6ab3]662 *
[4f5740f]663 * @note This routine usually must be implemented as a subroutine.
[d9a6ab3]664 *
[4f5740f]665 * Port Specific Information:
[d9a6ab3]666 *
[4f5740f]667 * XXX document implementation including references if appropriate
[d9a6ab3]668 */
669uint32_t   _CPU_ISR_Get_level( void );
670
671/* end of ISR handler macros */
672
[4f5740f]673/** @} */
674
[d9a6ab3]675/* Context handler macros */
676
677/**
[4f5740f]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.
[022851a]703 * @param[in] tls_area is the thread-local storage (TLS) area
[4f5740f]704 *
705 * Port Specific Information:
706 *
707 * See implementation in cpu.c
[d9a6ab3]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,
[022851a]715  bool              is_fp,
716  void             *tls_area
[d9a6ab3]717);
718
719/**
[4f5740f]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.
[d9a6ab3]729 *
[4f5740f]730 * Port Specific Information:
[d9a6ab3]731 *
[4f5740f]732 * XXX document implementation including references if appropriate
[d9a6ab3]733 */
734#define _CPU_Context_Restart_self( _the_context ) \
735   _CPU_Context_restore( (_the_context) );
736
737#define _CPU_Context_Initialize_fp( _destination ) \
[142868b2]738  memset( *( _destination ), 0, CPU_CONTEXT_FP_SIZE );
[d9a6ab3]739
740/* end of Context handler macros */
741
742/* Fatal Error manager macros */
743
744/**
[4f5740f]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.
[d9a6ab3]748 *
[4f5740f]749 * Port Specific Information:
[d9a6ab3]750 *
[4f5740f]751 * XXX document implementation including references if appropriate
[d9a6ab3]752 */
[f82752a4]753#define _CPU_Fatal_halt( _source, _error ) \
[d9a6ab3]754  { \
[566fa34]755    __asm__ volatile ( "cli R1; \
[d9a6ab3]756                    R1 = %0; \
757                    _halt: \
[4daebbd]758                    idle; \
[d9a6ab3]759                    jump _halt;"\
[4daebbd]760                    : : "r" (_error) ); \
[d9a6ab3]761  }
762
763/* end of Fatal Error manager macros */
764
765#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
766
767/* functions */
768
769/**
[4f5740f]770 * @brief CPU initialize.
771 * This routine performs CPU dependent initialization.
[d9a6ab3]772 *
[4f5740f]773 * Port Specific Information:
[d9a6ab3]774 *
[4f5740f]775 * XXX document implementation including references if appropriate
[d9a6ab3]776 */
[c03e2bc]777void _CPU_Initialize(void);
[d9a6ab3]778
779/**
[4f5740f]780 * @ingroup CPUInterrupt
781 * This routine installs a "raw" interrupt handler directly into the
782 * processor's vector table.
[d9a6ab3]783 *
[4f5740f]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
[d9a6ab3]787 *
[4f5740f]788 * Port Specific Information:
[d9a6ab3]789 *
[4f5740f]790 * XXX document implementation including references if appropriate
[d9a6ab3]791 */
792void _CPU_ISR_install_raw_handler(
793  uint32_t    vector,
794  proc_ptr    new_handler,
795  proc_ptr   *old_handler
796);
797
798/**
[4f5740f]799 * @ingroup CPUInterrupt
800 * This routine installs an interrupt vector.
[d9a6ab3]801 *
[4f5740f]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
[d9a6ab3]805 *
[4f5740f]806 * Port Specific Information:
[d9a6ab3]807 *
[4f5740f]808 * XXX document implementation including references if appropriate
[d9a6ab3]809 */
810void _CPU_ISR_install_vector(
811  uint32_t    vector,
812  proc_ptr    new_handler,
813  proc_ptr   *old_handler
814);
815
816/**
[4f5740f]817 * @ingroup CPUInterrupt
818 * This routine installs the hardware interrupt stack pointer.
[d9a6ab3]819 *
[4f5740f]820 * @note  It need only be provided if @ref CPU_HAS_HARDWARE_INTERRUPT_STACK
821 *        is TRUE.
[d9a6ab3]822 *
[4f5740f]823 * Port Specific Information:
[d9a6ab3]824 *
[4f5740f]825 * XXX document implementation including references if appropriate
[d9a6ab3]826 */
827void _CPU_Install_interrupt_stack( void );
828
829/**
[4f5740f]830 * This routine is the CPU dependent IDLE thread body.
[d9a6ab3]831 *
[4f5740f]832 * @note  It need only be provided if @ref CPU_PROVIDES_IDLE_THREAD_BODY
833 *        is TRUE.
[d9a6ab3]834 *
[4f5740f]835 * Port Specific Information:
[d9a6ab3]836 *
[4f5740f]837 * XXX document implementation including references if appropriate
[d9a6ab3]838 */
[cca8379]839void *_CPU_Thread_Idle_body( uintptr_t ignored );
[d9a6ab3]840
841/**
[4f5740f]842 * @addtogroup CPUContext
843 */
[b697bc6]844/**@{**/
[4f5740f]845
846/**
847 * This routine switches from the run context to the heir context.
[d9a6ab3]848 *
[4f5740f]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
[d9a6ab3]851 *
[4f5740f]852 * Port Specific Information:
853 *
854 * XXX document implementation including references if appropriate
[d9a6ab3]855 */
856void _CPU_Context_switch(
857  Context_Control  *run,
858  Context_Control  *heir
859);
860
861/**
[4f5740f]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.
[d9a6ab3]864 *
[4f5740f]865 * @param[in] new_context points to the context to be restored.
[d9a6ab3]866 *
[4f5740f]867 * @note May be unnecessary to reload some registers.
[d9a6ab3]868 *
[4f5740f]869 * Port Specific Information:
[d9a6ab3]870 *
[4f5740f]871 * XXX document implementation including references if appropriate
[d9a6ab3]872 */
873void _CPU_Context_restore(
874  Context_Control *new_context
[143696a]875) RTEMS_NO_RETURN;
[d9a6ab3]876
877/**
[4f5740f]878 * This routine saves the floating point context passed to it.
[d9a6ab3]879 *
[4f5740f]880 * @param[in] fp_context_ptr is a pointer to a pointer to a floating
881 * point context area
[d9a6ab3]882 *
[4f5740f]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.
[d9a6ab3]885 *
[4f5740f]886 * Port Specific Information:
[d9a6ab3]887 *
[4f5740f]888 * XXX document implementation including references if appropriate
[d9a6ab3]889 */
890void _CPU_Context_save_fp(
[231aac4]891  Context_Control_fp **fp_context_ptr
[d9a6ab3]892);
893
894/**
[4f5740f]895 * This routine restores the floating point context passed to it.
[d9a6ab3]896 *
[4f5740f]897 * @param[in] fp_context_ptr is a pointer to a pointer to a floating
898 * point context area to restore
[d9a6ab3]899 *
[4f5740f]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.
[d9a6ab3]902 *
[4f5740f]903 * Port Specific Information:
[d9a6ab3]904 *
[4f5740f]905 * XXX document implementation including references if appropriate
[d9a6ab3]906 */
907void _CPU_Context_restore_fp(
[231aac4]908  Context_Control_fp **fp_context_ptr
[d9a6ab3]909);
910
[39993d6]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
[4f5740f]923/** @} */
924
[815994f]925/* FIXME */
926typedef CPU_Interrupt_frame CPU_Exception_frame;
927
928void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
929
[d9a6ab3]930/**
[4f5740f]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.
[d9a6ab3]934 *
[4f5740f]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:
[d9a6ab3]937 *
[4f5740f]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
[d9a6ab3]941 *
[4f5740f]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.
[d9a6ab3]950 *
[4f5740f]951 * @param[in] value is the value to be swapped
952 * @return the value after being endian swapped
[d9a6ab3]953 *
[4f5740f]954 * Port Specific Information:
[d9a6ab3]955 *
[4f5740f]956 * XXX document implementation including references if appropriate
[d9a6ab3]957 */
958static inline uint32_t CPU_swap_u32(
959  uint32_t value
960)
961{
962  uint32_t   byte1, byte2, byte3, byte4, swapped;
[42e243e]963
[d9a6ab3]964  byte4 = (value >> 24) & 0xff;
965  byte3 = (value >> 16) & 0xff;
966  byte2 = (value >> 8)  & 0xff;
967  byte1 =  value        & 0xff;
[42e243e]968
[d9a6ab3]969  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
970  return( swapped );
971}
972
973/**
[4f5740f]974 * @ingroup CPUEndian
975 * This routine swaps a 16 bir quantity.
[d9a6ab3]976 *
[4f5740f]977 * @param[in] value is the value to be swapped
978 * @return the value after being endian swapped
[d9a6ab3]979 */
980#define CPU_swap_u16( value ) \
981  (((value&0xff) << 8) | ((value >> 8)&0xff))
982
[24bf11e]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
[6ff19253]995#endif /* ASM */
996
[d9a6ab3]997#ifdef __cplusplus
998}
999#endif
1000
1001#endif
Note: See TracBrowser for help on using the repository browser.