source: rtems/cpukit/score/cpu/no_cpu/rtems/score/cpu.h @ e5120a5

4.115
Last change on this file since e5120a5 was e5120a5, checked in by Sebastian Huber <sebastian.huber@…>, on 04/22/14 at 08:10:39

score: Add _CPU_Get_current_per_CPU_control()

Add optional method _CPU_Get_current_per_CPU_control() to obtain the
per-CPU control of the current processor.

This is optional. Not every CPU port needs this. It is only an
optional optimization variant. In case this macro is undefined, the
default implementation using the current processor index will be used.

  • Property mode set to 100644
File size: 49.7 KB
RevLine 
[77d3533f]1/**
2 * @file rtems/score/cpu.h
[f8a39cdc]3 *
4 * @brief NO_CPU Department Source
5 *
6 * This include file contains information pertaining to the NO_CPU
7 * processor.
[77d3533f]8 */
9
10/*
[7908ba5b]11 *  This include file contains information pertaining to the XXX
12 *  processor.
13 *
[baff4da]14 *  @note This file is part of a porting template that is intended
15 *  to be used as the starting point when porting RTEMS to a new
16 *  CPU family.  The following needs to be done when using this as
17 *  the starting point for a new port:
18 *
19 *  + Anywhere there is an XXX, it should be replaced
20 *    with information about the CPU family being ported to.
[80f7732]21 *
[baff4da]22 *  + At the end of each comment section, there is a heading which
23 *    says "Port Specific Information:".  When porting to RTEMS,
24 *    add CPU family specific information in this section
25 */
26
[95e7637]27/*
28 *  COPYRIGHT (c) 1989-2008.
[7908ba5b]29 *  On-Line Applications Research Corporation (OAR).
30 *
31 *  The license and distribution terms for this file may be
32 *  found in the file LICENSE in this distribution or at
[c499856]33 *  http://www.rtems.org/license/LICENSE.
[7908ba5b]34 */
35
[7f70d1b7]36#ifndef _RTEMS_SCORE_CPU_H
37#define _RTEMS_SCORE_CPU_H
[7908ba5b]38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
[14c8ef9]43#include <rtems/score/types.h>
[89b85e51]44#include <rtems/score/no_cpu.h>
[7908ba5b]45
46/* conditional compilation parameters */
47
[baff4da]48/**
[d9e0006]49 * Should the calls to @ref _Thread_Enable_dispatch be inlined?
[7908ba5b]50 *
[d9e0006]51 * If TRUE, then they are inlined.
52 * If FALSE, then a subroutine call is made.
[7908ba5b]53 *
[d9e0006]54 * This conditional is an example of the classic trade-off of size
55 * versus speed.  Inlining the call (TRUE) typically increases the
56 * size of RTEMS while speeding up the enabling of dispatching.
[baff4da]57 *
[d9e0006]58 * NOTE: In general, the @ref _Thread_Dispatch_disable_level will
59 * only be 0 or 1 unless you are in an interrupt handler and that
60 * interrupt handler invokes the executive.]  When not inlined
61 * something calls @ref _Thread_Enable_dispatch which in turns calls
62 * @ref _Thread_Dispatch.  If the enable dispatch is inlined, then
63 * one subroutine call is avoided entirely.
[df49c60]64 *
[d9e0006]65 * Port Specific Information:
[df49c60]66 *
[d9e0006]67 * XXX document implementation including references if appropriate
[7908ba5b]68 */
69#define CPU_INLINE_ENABLE_DISPATCH       FALSE
70
[baff4da]71/**
[d9e0006]72 * Should the body of the search loops in _Thread_queue_Enqueue_priority
73 * be unrolled one time?  In unrolled each iteration of the loop examines
74 * two "nodes" on the chain being searched.  Otherwise, only one node
75 * is examined per iteration.
[7908ba5b]76 *
[d9e0006]77 * If TRUE, then the loops are unrolled.
78 * If FALSE, then the loops are not unrolled.
[7908ba5b]79 *
[d9e0006]80 * The primary factor in making this decision is the cost of disabling
81 * and enabling interrupts (_ISR_Flash) versus the cost of rest of the
82 * body of the loop.  On some CPUs, the flash is more expensive than
83 * one iteration of the loop body.  In this case, it might be desirable
84 * to unroll the loop.  It is important to note that on some CPUs, this
85 * code is the longest interrupt disable period in RTEMS.  So it is
86 * necessary to strike a balance when setting this parameter.
[df49c60]87 *
[d9e0006]88 * Port Specific Information:
[df49c60]89 *
[d9e0006]90 * XXX document implementation including references if appropriate
[7908ba5b]91 */
92#define CPU_UNROLL_ENQUEUE_PRIORITY      TRUE
93
[baff4da]94/**
[d9e0006]95 * Does RTEMS manage a dedicated interrupt stack in software?
[7908ba5b]96 *
[d9e0006]97 * If TRUE, then a stack is allocated in @ref _ISR_Handler_initialization.
98 * If FALSE, nothing is done.
[7908ba5b]99 *
[d9e0006]100 * If the CPU supports a dedicated interrupt stack in hardware,
101 * then it is generally the responsibility of the BSP to allocate it
102 * and set it up.
[7908ba5b]103 *
[d9e0006]104 * If the CPU does not support a dedicated interrupt stack, then
105 * the porter has two options: (1) execute interrupts on the
106 * stack of the interrupted task, and (2) have RTEMS manage a dedicated
107 * interrupt stack.
[7908ba5b]108 *
[d9e0006]109 * If this is TRUE, @ref CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
[7908ba5b]110 *
[d9e0006]111 * Only one of @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK and
112 * @ref CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE.  It is
113 * possible that both are FALSE for a particular CPU.  Although it
114 * is unclear what that would imply about the interrupt processing
115 * procedure on that CPU.
[df49c60]116 *
[d9e0006]117 * Port Specific Information:
[df49c60]118 *
[d9e0006]119 * XXX document implementation including references if appropriate
[7908ba5b]120 */
121#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
122
[2fd427c]123/**
[d9e0006]124 * Does the CPU follow the simple vectored interrupt model?
[2fd427c]125 *
[d9e0006]126 * If TRUE, then RTEMS allocates the vector table it internally manages.
127 * If FALSE, then the BSP is assumed to allocate and manage the vector
128 * table
[2fd427c]129 *
[d9e0006]130 * Port Specific Information:
[2fd427c]131 *
[d9e0006]132 * XXX document implementation including references if appropriate
[2fd427c]133 */
134#define CPU_SIMPLE_VECTORED_INTERRUPTS TRUE
135
[baff4da]136/**
[d9e0006]137 * Does this CPU have hardware support for a dedicated interrupt stack?
[7908ba5b]138 *
[d9e0006]139 * If TRUE, then it must be installed during initialization.
140 * If FALSE, then no installation is performed.
[7908ba5b]141 *
[d9e0006]142 * If this is TRUE, @ref CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
[7908ba5b]143 *
[d9e0006]144 * Only one of @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK and
145 * @ref CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE.  It is
146 * possible that both are FALSE for a particular CPU.  Although it
147 * is unclear what that would imply about the interrupt processing
148 * procedure on that CPU.
[df49c60]149 *
[d9e0006]150 * Port Specific Information:
[df49c60]151 *
[d9e0006]152 * XXX document implementation including references if appropriate
[7908ba5b]153 */
154#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE
155
[baff4da]156/**
[d9e0006]157 * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
[7908ba5b]158 *
[d9e0006]159 * If TRUE, then the memory is allocated during initialization.
160 * If FALSE, then the memory is allocated during initialization.
[7908ba5b]161 *
[d9e0006]162 * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE.
[df49c60]163 *
[d9e0006]164 * Port Specific Information:
[df49c60]165 *
[d9e0006]166 * XXX document implementation including references if appropriate
[7908ba5b]167 */
168#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
169
[baff4da]170/**
[d9e0006]171 * Does the RTEMS invoke the user's ISR with the vector number and
172 * a pointer to the saved interrupt frame (1) or just the vector
173 * number (0)?
[df49c60]174 *
[d9e0006]175 * Port Specific Information:
[df49c60]176 *
[d9e0006]177 * XXX document implementation including references if appropriate
[7908ba5b]178 */
179#define CPU_ISR_PASSES_FRAME_POINTER 0
180
[baff4da]181/**
[d9e0006]182 * @def CPU_HARDWARE_FP
[baff4da]183 *
[d9e0006]184 * Does the CPU have hardware floating point?
[7908ba5b]185 *
[d9e0006]186 * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
187 * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
[7908ba5b]188 *
[d9e0006]189 * If there is a FP coprocessor such as the i387 or mc68881, then
190 * the answer is TRUE.
[7908ba5b]191 *
[d9e0006]192 * The macro name "NO_CPU_HAS_FPU" should be made CPU specific.
193 * It indicates whether or not this CPU model has FP support.  For
194 * example, it would be possible to have an i386_nofp CPU model
195 * which set this to false to indicate that you have an i386 without
196 * an i387 and wish to leave floating point support out of RTEMS.
[baff4da]197 */
198
[80f7732]199/**
[d9e0006]200 * @def CPU_SOFTWARE_FP
[baff4da]201 *
[d9e0006]202 * Does the CPU have no hardware floating point and GCC provides a
203 * software floating point implementation which must be context
204 * switched?
[df49c60]205 *
[d9e0006]206 * This feature conditional is used to indicate whether or not there
207 * is software implemented floating point that must be context
208 * switched.  The determination of whether or not this applies
209 * is very tool specific and the state saved/restored is also
210 * compiler specific.
[df49c60]211 *
[d9e0006]212 * Port Specific Information:
[df49c60]213 *
[d9e0006]214 * XXX document implementation including references if appropriate
[7908ba5b]215 */
216#if ( NO_CPU_HAS_FPU == 1 )
217#define CPU_HARDWARE_FP     TRUE
218#else
219#define CPU_HARDWARE_FP     FALSE
220#endif
[df49c60]221#define CPU_SOFTWARE_FP     FALSE
[7908ba5b]222
[baff4da]223/**
[d9e0006]224 * Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
[7908ba5b]225 *
[d9e0006]226 * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
227 * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
[7908ba5b]228 *
[d9e0006]229 * So far, the only CPUs in which this option has been used are the
230 * HP PA-RISC and PowerPC.  On the PA-RISC, The HP C compiler and
231 * gcc both implicitly used the floating point registers to perform
232 * integer multiplies.  Similarly, the PowerPC port of gcc has been
233 * seen to allocate floating point local variables and touch the FPU
234 * even when the flow through a subroutine (like vfprintf()) might
235 * not use floating point formats.
[3b1c100]236 *
[d9e0006]237 * If a function which you would not think utilize the FP unit DOES,
238 * then one can not easily predict which tasks will use the FP hardware.
239 * In this case, this option should be TRUE.
[7908ba5b]240 *
[d9e0006]241 * If @ref CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
[df49c60]242 *
[d9e0006]243 * Port Specific Information:
[df49c60]244 *
[d9e0006]245 * XXX document implementation including references if appropriate
[7908ba5b]246 */
247#define CPU_ALL_TASKS_ARE_FP     TRUE
248
[baff4da]249/**
[d9e0006]250 * Should the IDLE task have a floating point context?
[7908ba5b]251 *
[d9e0006]252 * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
253 * and it has a floating point context which is switched in and out.
254 * If FALSE, then the IDLE task does not have a floating point context.
[7908ba5b]255 *
[d9e0006]256 * Setting this to TRUE negatively impacts the time required to preempt
257 * the IDLE task from an interrupt because the floating point context
258 * must be saved as part of the preemption.
[df49c60]259 *
[d9e0006]260 * Port Specific Information:
[df49c60]261 *
[d9e0006]262 * XXX document implementation including references if appropriate
[7908ba5b]263 */
264#define CPU_IDLE_TASK_IS_FP      FALSE
265
[baff4da]266/**
[d9e0006]267 * Should the saving of the floating point registers be deferred
268 * until a context switch is made to another different floating point
269 * task?
[7908ba5b]270 *
[d9e0006]271 * If TRUE, then the floating point context will not be stored until
272 * necessary.  It will remain in the floating point registers and not
273 * disturned until another floating point task is switched to.
[7908ba5b]274 *
[d9e0006]275 * If FALSE, then the floating point context is saved when a floating
276 * point task is switched out and restored when the next floating point
277 * task is restored.  The state of the floating point registers between
278 * those two operations is not specified.
[7908ba5b]279 *
[d9e0006]280 * If the floating point context does NOT have to be saved as part of
281 * interrupt dispatching, then it should be safe to set this to TRUE.
[7908ba5b]282 *
[d9e0006]283 * Setting this flag to TRUE results in using a different algorithm
284 * for deciding when to save and restore the floating point context.
285 * The deferred FP switch algorithm minimizes the number of times
286 * the FP context is saved and restored.  The FP context is not saved
287 * until a context switch is made to another, different FP task.
288 * Thus in a system with only one FP task, the FP context will never
289 * be saved or restored.
[df49c60]290 *
[d9e0006]291 * Port Specific Information:
[df49c60]292 *
[d9e0006]293 * XXX document implementation including references if appropriate
[7908ba5b]294 */
295#define CPU_USE_DEFERRED_FP_SWITCH       TRUE
296
[baff4da]297/**
[d9e0006]298 * Does this port provide a CPU dependent IDLE task implementation?
[7908ba5b]299 *
[d9e0006]300 * If TRUE, then the routine @ref _CPU_Thread_Idle_body
301 * must be provided and is the default IDLE thread body instead of
302 * @ref _CPU_Thread_Idle_body.
[7908ba5b]303 *
[d9e0006]304 * If FALSE, then use the generic IDLE thread body if the BSP does
305 * not provide one.
[7908ba5b]306 *
[d9e0006]307 * This is intended to allow for supporting processors which have
308 * a low power or idle mode.  When the IDLE thread is executed, then
309 * the CPU can be powered down.
[7908ba5b]310 *
[d9e0006]311 * The order of precedence for selecting the IDLE thread body is:
[7908ba5b]312 *
[d9e0006]313 *   -#  BSP provided
314 *   -#  CPU dependent (if provided)
315 *   -#  generic (if no BSP and no CPU dependent)
[df49c60]316 *
[d9e0006]317 * Port Specific Information:
[df49c60]318 *
[d9e0006]319 * XXX document implementation including references if appropriate
[7908ba5b]320 */
321#define CPU_PROVIDES_IDLE_THREAD_BODY    TRUE
322
[baff4da]323/**
[d9e0006]324 * Does the stack grow up (toward higher addresses) or down
325 * (toward lower addresses)?
[7908ba5b]326 *
[d9e0006]327 * If TRUE, then the grows upward.
328 * If FALSE, then the grows toward smaller addresses.
[df49c60]329 *
[d9e0006]330 * Port Specific Information:
[df49c60]331 *
[d9e0006]332 * XXX document implementation including references if appropriate
[7908ba5b]333 */
334#define CPU_STACK_GROWS_UP               TRUE
335
[baff4da]336/**
[d9e0006]337 * The following is the variable attribute used to force alignment
338 * of critical RTEMS structures.  On some processors it may make
339 * sense to have these aligned on tighter boundaries than
340 * the minimum requirements of the compiler in order to have as
341 * much of the critical data area as possible in a cache line.
[7908ba5b]342 *
[d9e0006]343 * The placement of this macro in the declaration of the variables
344 * is based on the syntactically requirements of the GNU C
345 * "__attribute__" extension.  For example with GNU C, use
346 * the following to force a structures to a 32 byte boundary.
[7908ba5b]347 *
[d9e0006]348 *     __attribute__ ((aligned (32)))
[7908ba5b]349 *
[d9e0006]350 * NOTE: Currently only the Priority Bit Map table uses this feature.
351 *       To benefit from using this, the data must be heavily
352 *       used so it will stay in the cache and used frequently enough
353 *       in the executive to justify turning this on.
[df49c60]354 *
[d9e0006]355 * Port Specific Information:
[df49c60]356 *
[d9e0006]357 * XXX document implementation including references if appropriate
[7908ba5b]358 */
359#define CPU_STRUCTURE_ALIGNMENT
360
[f40139b]361/**
[d9e0006]362 * @defgroup CPUTimestamp Processor Dependent Timestamp Support
[f40139b]363 *
[d9e0006]364 * This group assists in issues related to timestamp implementation.
[f40139b]365 *
[d9e0006]366 * The port must choose exactly one of the following defines:
367 * - #define CPU_TIMESTAMP_USE_STRUCT_TIMESPEC TRUE
368 * - #define CPU_TIMESTAMP_USE_INT64 TRUE
369 * - #define CPU_TIMESTAMP_USE_INT64_INLINE TRUE
[f40139b]370 *
[d9e0006]371 * Performance of int64_t versus struct timespec
372 * =============================================
[f40139b]373 *
[d9e0006]374 * On PowerPC/psim, inlined int64_t saves ~50 instructions on each
375 *   _Thread_Dispatch operation which results in a context switch.
376 *   This works out to be about 10% faster dispatches and 7.5% faster
377 *   blocking semaphore obtains.  The following numbers are in instructions
378 *   and from tm02 and tm26.
[f40139b]379 *
[d9e0006]380 *                        timespec  int64  inlined int64
381 *   dispatch:              446      446      400
382 *   blocking sem obtain:   627      626      581
[f40139b]383 *
[d9e0006]384 * On SPARC/sis, inlined int64_t shows the same percentage gains.
385 *   The following numbers are in microseconds and from tm02 and tm26.
[f40139b]386 *
[d9e0006]387 *                        timespec  int64  inlined int64
388 *   dispatch:               59       61       53
389 *   blocking sem obtain:    98      100       92
[f40139b]390 *
[d9e0006]391 * Inlining appears to have a tendency to increase the size of
392 *   some executables.
393 * Not inlining reduces the execution improvement but does not seem to
394 *   be an improvement on the PowerPC and SPARC. The struct timespec
395 *   and the executables with int64 not inlined are about the same size.
396 *
[f40139b]397 */
[b697bc6]398/**@{**/
[f40139b]399
400/**
[d9e0006]401 * Selects the timestamp implementation using struct timespec.
[f40139b]402 *
[d9e0006]403 * Port Specific Information:
[f40139b]404 *
[d9e0006]405 * XXX document implementation including references if appropriate
[f40139b]406 */
407#define CPU_TIMESTAMP_USE_STRUCT_TIMESPEC TRUE
408
409/**
[d9e0006]410 * Selects the timestamp implementation using int64_t and no inlined methods.
[f40139b]411 *
[d9e0006]412 * Port Specific Information:
[f40139b]413 *
[d9e0006]414 * XXX document implementation including references if appropriate
[f40139b]415 */
416#define CPU_TIMESTAMP_USE_INT64 TRUE
417
418/**
[d9e0006]419 * Selects the timestamp implementation using int64_t and inlined methods.
[f40139b]420 *
[d9e0006]421 * Port Specific Information:
[f40139b]422 *
[d9e0006]423 * XXX document implementation including references if appropriate
[f40139b]424 */
425#define CPU_TIMESTAMP_USE_INT64_INLINE TRUE
426
[d9e0006]427/** @} */
428
[baff4da]429/**
[d9e0006]430 * @defgroup CPUEndian Processor Dependent Endianness Support
[baff4da]431 *
[d9e0006]432 * This group assists in issues related to processor endianness.
433 *
[baff4da]434 */
[b697bc6]435/**@{**/
[baff4da]436
437/**
[d9e0006]438 * Define what is required to specify how the network to host conversion
439 * routines are handled.
[df49c60]440 *
[d9e0006]441 * NOTE: @a CPU_BIG_ENDIAN and @a CPU_LITTLE_ENDIAN should NOT have the
442 * same values.
[baff4da]443 *
[d9e0006]444 * @see CPU_LITTLE_ENDIAN
[baff4da]445 *
[d9e0006]446 * Port Specific Information:
[df49c60]447 *
[d9e0006]448 * XXX document implementation including references if appropriate
[7908ba5b]449 */
450#define CPU_BIG_ENDIAN                           TRUE
[baff4da]451
452/**
[d9e0006]453 * Define what is required to specify how the network to host conversion
454 * routines are handled.
[baff4da]455 *
[d9e0006]456 * NOTE: @ref CPU_BIG_ENDIAN and @ref CPU_LITTLE_ENDIAN should NOT have the
457 * same values.
[baff4da]458 *
[d9e0006]459 * @see CPU_BIG_ENDIAN
[baff4da]460 *
[d9e0006]461 * Port Specific Information:
[baff4da]462 *
[d9e0006]463 * XXX document implementation including references if appropriate
[baff4da]464 */
[7908ba5b]465#define CPU_LITTLE_ENDIAN                        FALSE
466
[d9e0006]467/** @} */
468
[baff4da]469/**
[d9e0006]470 * @ingroup CPUInterrupt
471 *
472 * The following defines the number of bits actually used in the
473 * interrupt field of the task mode.  How those bits map to the
474 * CPU interrupt levels is defined by the routine @ref _CPU_ISR_Set_level.
[df49c60]475 *
[d9e0006]476 * Port Specific Information:
[df49c60]477 *
[d9e0006]478 * XXX document implementation including references if appropriate
[7908ba5b]479 */
480#define CPU_MODES_INTERRUPT_MASK   0x00000001
481
[10fd4aac]482/**
483 * @brief The size of the CPU specific per-CPU control.
484 *
485 * This define must be visible to assember files since it is used to derive
486 * structure offsets.
487 */
488#define CPU_PER_CPU_CONTROL_SIZE 0
489
[7908ba5b]490/*
[90550fe]491 *  Processor defined structures required for cpukit/score.
[df49c60]492 *
[baff4da]493 *  Port Specific Information:
[df49c60]494 *
495 *  XXX document implementation including references if appropriate
[7908ba5b]496 */
497
498/* may need to put some structures here.  */
499
[10fd4aac]500/**
501 * @brief The CPU specific per-CPU control.
502 *
503 * The CPU port can place here all state information that must be available and
504 * maintained for each CPU in the system.
505 */
506typedef struct {
507  /* CPU specific per-CPU state */
508} CPU_Per_CPU_control;
509
[baff4da]510/**
511 * @defgroup CPUContext Processor Dependent Context Management
[7908ba5b]512 *
[d9e0006]513 * From the highest level viewpoint, there are 2 types of context to save.
[7908ba5b]514 *
[d9e0006]515 *    -# Interrupt registers to save
516 *    -# Task level registers to save
[baff4da]517 *
[d9e0006]518 * Since RTEMS handles integer and floating point contexts separately, this
519 * means we have the following 3 context items:
[baff4da]520 *
[d9e0006]521 *    -# task level context stuff::  Context_Control
522 *    -# floating point task stuff:: Context_Control_fp
523 *    -# special interrupt level context :: CPU_Interrupt_frame
[7908ba5b]524 *
[d9e0006]525 * On some processors, it is cost-effective to save only the callee
526 * preserved registers during a task context switch.  This means
527 * that the ISR code needs to save those registers which do not
528 * persist across function calls.  It is not mandatory to make this
529 * distinctions between the caller/callee saves registers for the
530 * purpose of minimizing context saved during task switch and on interrupts.
531 * If the cost of saving extra registers is minimal, simplicity is the
532 * choice.  Save the same context on interrupt entry as for tasks in
533 * this case.
[7908ba5b]534 *
[d9e0006]535 * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
536 * care should be used in designing the context area.
[7908ba5b]537 *
[d9e0006]538 * On some CPUs with hardware floating point support, the Context_Control_fp
539 * structure will not be used or it simply consist of an array of a
540 * fixed number of bytes.   This is done when the floating point context
541 * is dumped by a "FP save context" type instruction and the format
542 * is not really defined by the CPU.  In this case, there is no need
543 * to figure out the exact format -- only the size.  Of course, although
544 * this is enough information for RTEMS, it is probably not enough for
545 * a debugger such as gdb.  But that is another problem.
[df49c60]546 *
[d9e0006]547 * Port Specific Information:
[df49c60]548 *
[d9e0006]549 * XXX document implementation including references if appropriate
550 *
[7908ba5b]551 */
[b697bc6]552/**@{**/
[7908ba5b]553
[baff4da]554/**
[d9e0006]555 * @ingroup Management
556 * This defines the minimal set of integer and processor state registers
557 * that must be saved during a voluntary context switch from one thread
558 * to another.
[baff4da]559 */
[7908ba5b]560typedef struct {
[d9e0006]561    /**
562     * This field is a hint that a port will have a number of integer
563     * registers that need to be saved at a context switch.
[baff4da]564     */
[c346f33d]565    uint32_t   some_integer_register;
[d9e0006]566    /**
567     * This field is a hint that a port will have a number of system
568     * registers that need to be saved at a context switch.
[baff4da]569     */
[c346f33d]570    uint32_t   some_system_register;
[0ca6d0d9]571
[d9e0006]572    /**
573     * This field is a hint that a port will have a register that
574     * is the stack pointer.
[0ca6d0d9]575     */
576    uint32_t   stack_pointer;
[7908ba5b]577} Context_Control;
578
[95e7637]579/**
[d9e0006]580 * @ingroup Management
[95e7637]581 *
[d9e0006]582 * This macro returns the stack pointer associated with @a _context.
[95e7637]583 *
[d9e0006]584 * @param[in] _context is the thread context area to access
[80f7732]585 *
[d9e0006]586 * @return This method returns the stack pointer.
[95e7637]587 */
[0ca6d0d9]588#define _CPU_Context_Get_SP( _context ) \
589  (_context)->stack_pointer
590
[baff4da]591/**
[d9e0006]592 * @ingroup Management
593 *
594 * This defines the complete set of floating point registers that must
595 * be saved during any context switch from one thread to another.
[baff4da]596 */
[7908ba5b]597typedef struct {
[22b3bed]598    /** FPU registers are listed here */
[7908ba5b]599    double      some_float_register;
600} Context_Control_fp;
601
[baff4da]602/**
[d9e0006]603 * @ingroup Management
604 *
605 * This defines the set of integer and processor state registers that must
606 * be saved during an interrupt.  This set does not include any which are
607 * in @ref Context_Control.
[baff4da]608 */
[7908ba5b]609typedef struct {
[d9e0006]610    /**
611     * This field is a hint that a port will have a number of integer
612     * registers that need to be saved when an interrupt occurs or
613     * when a context switch occurs at the end of an ISR.
[baff4da]614     */
[c346f33d]615    uint32_t   special_interrupt_register;
[7908ba5b]616} CPU_Interrupt_frame;
617
[baff4da]618/**
[d9e0006]619 * This variable is optional.  It is used on CPUs on which it is difficult
620 * to generate an "uninitialized" FP context.  It is filled in by
621 * @ref _CPU_Initialize and copied into the task's FP context area during
622 * @ref _CPU_Context_Initialize.
[df49c60]623 *
[d9e0006]624 * Port Specific Information:
[df49c60]625 *
[d9e0006]626 * XXX document implementation including references if appropriate
[7908ba5b]627 */
628SCORE_EXTERN Context_Control_fp  _CPU_Null_fp_context;
629
[d9e0006]630/** @} */
631
[baff4da]632/**
[d9e0006]633 * @defgroup CPUInterrupt Processor Dependent Interrupt Management
[baff4da]634 *
[d9e0006]635 * On some CPUs, RTEMS supports a software managed interrupt stack.
636 * This stack is allocated by the Interrupt Manager and the switch
637 * is performed in @ref _ISR_Handler.  These variables contain pointers
638 * to the lowest and highest addresses in the chunk of memory allocated
639 * for the interrupt stack.  Since it is unknown whether the stack
640 * grows up or down (in general), this give the CPU dependent
641 * code the option of picking the version it wants to use.
[7908ba5b]642 *
[d9e0006]643 * NOTE: These two variables are required if the macro
644 *       @ref CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
[df49c60]645 *
[d9e0006]646 * Port Specific Information:
[df49c60]647 *
[d9e0006]648 * XXX document implementation including references if appropriate
[7908ba5b]649 */
650
651/*
652 *  Nothing prevents the porter from declaring more CPU specific variables.
[df49c60]653 *
[baff4da]654 *  Port Specific Information:
[df49c60]655 *
656 *  XXX document implementation including references if appropriate
[7908ba5b]657 */
658
659/* XXX: if needed, put more variables here */
660
[baff4da]661/**
[d9e0006]662 * @ingroup CPUContext
663 *
664 * The size of the floating point context area.  On some CPUs this
665 * will not be a "sizeof" because the format of the floating point
666 * area is not defined -- only the size is.  This is usually on
667 * CPUs with a "floating point save context" instruction.
[df49c60]668 *
[d9e0006]669 * Port Specific Information:
[df49c60]670 *
[d9e0006]671 * XXX document implementation including references if appropriate
[7908ba5b]672 */
673#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
674
[baff4da]675/**
[d9e0006]676 * Amount of extra stack (above minimum stack size) required by
677 * MPCI receive server thread.  Remember that in a multiprocessor
678 * system this thread must exist and be able to process all directives.
[df49c60]679 *
[d9e0006]680 * Port Specific Information:
[df49c60]681 *
[d9e0006]682 * XXX document implementation including references if appropriate
[7908ba5b]683 */
684#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
685
[baff4da]686/**
[d9e0006]687 * @ingroup CPUInterrupt
688 *
689 * This defines the number of entries in the @ref _ISR_Vector_table managed
690 * by RTEMS.
[df49c60]691 *
[d9e0006]692 * Port Specific Information:
[df49c60]693 *
[d9e0006]694 * XXX document implementation including references if appropriate
[7908ba5b]695 */
696#define CPU_INTERRUPT_NUMBER_OF_VECTORS      32
[baff4da]697
698/**
[d9e0006]699 * @ingroup CPUInterrupt
700 *
701 * This defines the highest interrupt vector number for this port.
[baff4da]702 */
[7908ba5b]703#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER  (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
704
[baff4da]705/**
[d9e0006]706 * @ingroup CPUInterrupt
707 *
708 * This is defined if the port has a special way to report the ISR nesting
709 * level.  Most ports maintain the variable @a _ISR_Nest_level.
[4db30283]710 */
711#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
712
[baff4da]713/**
[d9e0006]714 * @ingroup CPUContext
715 *
716 * Should be large enough to run all RTEMS tests.  This ensures
717 * that a "reasonable" small application should not have any problems.
[df49c60]718 *
[d9e0006]719 * Port Specific Information:
[df49c60]720 *
[d9e0006]721 * XXX document implementation including references if appropriate
[7908ba5b]722 */
723#define CPU_STACK_MINIMUM_SIZE          (1024*4)
724
[f1738ed]725/**
[d9e0006]726 * Size of a pointer.
[f1738ed]727 *
[d9e0006]728 * This must be an integer literal that can be used by the assembler.  This
729 * value will be used to calculate offsets of structure members.  These
730 * offsets will be used in assembler code.
[f1738ed]731 */
732#define CPU_SIZEOF_POINTER         4
733
[baff4da]734/**
[d9e0006]735 * CPU's worst alignment requirement for data types on a byte boundary.  This
[57740ce8]736 * alignment does not take into account the requirements for the stack.  It
737 * must be a power of two greater than or equal to two.  The power of two
738 * requirement makes it possible to align values easily using simple bit
739 * operations.
[df49c60]740 *
[d9e0006]741 * Port Specific Information:
[df49c60]742 *
[d9e0006]743 * XXX document implementation including references if appropriate
[7908ba5b]744 */
745#define CPU_ALIGNMENT              8
746
[baff4da]747/**
[d9e0006]748 * This number corresponds to the byte alignment requirement for the
749 * heap handler.  This alignment requirement may be stricter than that
750 * for the data types alignment specified by @ref CPU_ALIGNMENT.  It is
751 * common for the heap to follow the same alignment requirement as
752 * @ref CPU_ALIGNMENT.  If the @ref CPU_ALIGNMENT is strict enough for
753 * the heap, then this should be set to @ref CPU_ALIGNMENT.
[7908ba5b]754 *
[57740ce8]755 * NOTE:  It must be a power of two greater than or equal to two.  The
756 *        requirement to be a multiple of two is because the heap uses the
757 *        least significant field of the front and back flags to indicate that
758 *        a block is in use or free.  So you do not want any odd length blocks
759 *        really putting length data in that bit.
[df49c60]760 *
[d9e0006]761 *        On byte oriented architectures, @ref CPU_HEAP_ALIGNMENT normally will
762 *        have to be greater or equal to than @ref CPU_ALIGNMENT to ensure that
763 *        elements allocated from the heap meet all restrictions.
[df49c60]764 *
[d9e0006]765 * Port Specific Information:
[df49c60]766 *
[d9e0006]767 * XXX document implementation including references if appropriate
[7908ba5b]768 */
769#define CPU_HEAP_ALIGNMENT         CPU_ALIGNMENT
770
[baff4da]771/**
[d9e0006]772 * This number corresponds to the byte alignment requirement for memory
773 * buffers allocated by the partition manager.  This alignment requirement
774 * may be stricter than that for the data types alignment specified by
775 * @ref CPU_ALIGNMENT.  It is common for the partition to follow the same
776 * alignment requirement as @ref CPU_ALIGNMENT.  If the @ref CPU_ALIGNMENT is
777 * strict enough for the partition, then this should be set to
778 * @ref CPU_ALIGNMENT.
[7908ba5b]779 *
[d9e0006]780 * NOTE:  This does not have to be a power of 2.  It does have to
781 *        be greater or equal to than @ref CPU_ALIGNMENT.
[df49c60]782 *
[d9e0006]783 * Port Specific Information:
[df49c60]784 *
[d9e0006]785 * XXX document implementation including references if appropriate
[7908ba5b]786 */
787#define CPU_PARTITION_ALIGNMENT    CPU_ALIGNMENT
788
[baff4da]789/**
[d9e0006]790 * This number corresponds to the byte alignment requirement for the
791 * stack.  This alignment requirement may be stricter than that for the
792 * data types alignment specified by @ref CPU_ALIGNMENT.  If the
793 * @ref CPU_ALIGNMENT is strict enough for the stack, then this should be
794 * set to 0.
[7908ba5b]795 *
[d9e0006]796 * NOTE: This must be a power of 2 either 0 or greater than @ref CPU_ALIGNMENT.
[df49c60]797 *
[d9e0006]798 * Port Specific Information:
[df49c60]799 *
[d9e0006]800 * XXX document implementation including references if appropriate
[7908ba5b]801 */
802#define CPU_STACK_ALIGNMENT        0
803
[d6ea098]804/*
805 *  ISR handler macros
806 */
807
[baff4da]808/**
[d9e0006]809 * @ingroup CPUInterrupt
810 *
811 * Support routine to initialize the RTEMS vector table after it is allocated.
[d6ea098]812 *
[d9e0006]813 * Port Specific Information:
[d6ea098]814 *
[d9e0006]815 * XXX document implementation including references if appropriate
[d6ea098]816 */
817#define _CPU_Initialize_vectors()
[7908ba5b]818
[baff4da]819/**
[d9e0006]820 * @ingroup CPUInterrupt
821 *
822 * Disable all interrupts for an RTEMS critical section.  The previous
823 * level is returned in @a _isr_cookie.
[baff4da]824 *
[d9e0006]825 * @param[out] _isr_cookie will contain the previous level cookie
[df49c60]826 *
[d9e0006]827 * Port Specific Information:
[df49c60]828 *
[d9e0006]829 * XXX document implementation including references if appropriate
[7908ba5b]830 */
831#define _CPU_ISR_Disable( _isr_cookie ) \
832  { \
833    (_isr_cookie) = 0;   /* do something to prevent warnings */ \
834  }
835
[baff4da]836/**
[d9e0006]837 * @ingroup CPUInterrupt
838 *
839 * Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
840 * This indicates the end of an RTEMS critical section.  The parameter
841 * @a _isr_cookie is not modified.
[baff4da]842 *
[d9e0006]843 * @param[in] _isr_cookie contain the previous level cookie
[df49c60]844 *
[d9e0006]845 * Port Specific Information:
[df49c60]846 *
[d9e0006]847 * XXX document implementation including references if appropriate
[7908ba5b]848 */
849#define _CPU_ISR_Enable( _isr_cookie )  \
850  { \
851  }
852
[baff4da]853/**
[d9e0006]854 * @ingroup CPUInterrupt
855 *
856 * This temporarily restores the interrupt to @a _isr_cookie before immediately
857 * disabling them again.  This is used to divide long RTEMS critical
858 * sections into two or more parts.  The parameter @a _isr_cookie is not
859 * modified.
[baff4da]860 *
[d9e0006]861 * @param[in] _isr_cookie contain the previous level cookie
[df49c60]862 *
[d9e0006]863 * Port Specific Information:
[df49c60]864 *
[d9e0006]865 * XXX document implementation including references if appropriate
[7908ba5b]866 */
867#define _CPU_ISR_Flash( _isr_cookie ) \
868  { \
869  }
870
[baff4da]871/**
[d9e0006]872 * @ingroup CPUInterrupt
[baff4da]873 *
[d9e0006]874 * This routine and @ref _CPU_ISR_Get_level
875 * Map the interrupt level in task mode onto the hardware that the CPU
876 * actually provides.  Currently, interrupt levels which do not
877 * map onto the CPU in a generic fashion are undefined.  Someday,
878 * it would be nice if these were "mapped" by the application
879 * via a callout.  For example, m68k has 8 levels 0 - 7, levels
880 * 8 - 255 would be available for bsp/application specific meaning.
881 * This could be used to manage a programmable interrupt controller
882 * via the rtems_task_mode directive.
[7908ba5b]883 *
[d9e0006]884 * Port Specific Information:
[df49c60]885 *
[d9e0006]886 * XXX document implementation including references if appropriate
[7908ba5b]887 */
888#define _CPU_ISR_Set_level( new_level ) \
889  { \
890  }
891
[baff4da]892/**
[d9e0006]893 * @ingroup CPUInterrupt
894 *
895 * Return the current interrupt disable level for this task in
896 * the format used by the interrupt level portion of the task mode.
[baff4da]897 *
[d9e0006]898 * NOTE: This routine usually must be implemented as a subroutine.
[baff4da]899 *
[d9e0006]900 * Port Specific Information:
[baff4da]901 *
[d9e0006]902 * XXX document implementation including references if appropriate
[baff4da]903 */
[c346f33d]904uint32_t   _CPU_ISR_Get_level( void );
[7908ba5b]905
906/* end of ISR handler macros */
907
908/* Context handler macros */
909
[baff4da]910/**
911 *  @ingroup CPUContext
[d9e0006]912 *
913 * Initialize the context to a state suitable for starting a
914 * task after a context restore operation.  Generally, this
915 * involves:
916 *
917 *    - setting a starting address
918 *    - preparing the stack
919 *    - preparing the stack and frame pointers
920 *    - setting the proper interrupt level in the context
921 *    - initializing the floating point context
922 *
923 * This routine generally does not set any unnecessary register
924 * in the context.  The state of the "general data" registers is
925 * undefined at task start time.
926 *
927 * @param[in] _the_context is the context structure to be initialized
928 * @param[in] _stack_base is the lowest physical address of this task's stack
929 * @param[in] _size is the size of this task's stack
930 * @param[in] _isr is the interrupt disable level
931 * @param[in] _entry_point is the thread's entry point.  This is
932 *        always @a _Thread_Handler
933 * @param[in] _is_fp is TRUE if the thread is to be a floating
934 *       point thread.  This is typically only used on CPUs where the
935 *       FPU may be easily disabled by software such as on the SPARC
936 *       where the PSR contains an enable FPU bit.
[022851a]937 * @param[in] _tls_area The thread-local storage (TLS) area.
[d9e0006]938 *
939 * Port Specific Information:
940 *
941 * XXX document implementation including references if appropriate
[7908ba5b]942 */
943#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
[022851a]944                                 _isr, _entry_point, _is_fp, _tls_area ) \
[7908ba5b]945  { \
946  }
947
[22b3bed]948/**
[d9e0006]949 * This routine is responsible for somehow restarting the currently
950 * executing task.  If you are lucky, then all that is necessary
951 * is restoring the context.  Otherwise, there will need to be
952 * a special assembly routine which does something special in this
953 * case.  For many ports, simply adding a label to the restore path
954 * of @ref _CPU_Context_switch will work.  On other ports, it may be
955 * possibly to load a few arguments and jump to the restore path. It will
956 * not work if restarting self conflicts with the stack frame
957 * assumptions of restoring a context.
[df49c60]958 *
[d9e0006]959 * Port Specific Information:
[df49c60]960 *
[d9e0006]961 * XXX document implementation including references if appropriate
[7908ba5b]962 */
963#define _CPU_Context_Restart_self( _the_context ) \
964   _CPU_Context_restore( (_the_context) );
965
[baff4da]966/**
[d9e0006]967 * @ingroup CPUContext
968 *
969 * The purpose of this macro is to allow the initial pointer into
970 * a floating point context area (used to save the floating point
971 * context) to be at an arbitrary place in the floating point
972 *context area.
[baff4da]973 *
[d9e0006]974 * This is necessary because some FP units are designed to have
975 * their context saved as a stack which grows into lower addresses.
976 * Other FP units can be saved by simply moving registers into offsets
977 * from the base of the context area.  Finally some FP units provide
978 * a "dump context" instruction which could fill in from high to low
979 * or low to high based on the whim of the CPU designers.
[df49c60]980 *
[d9e0006]981 * @param[in] _base is the lowest physical address of the floating point
982 *        context area
983 * @param[in] _offset is the offset into the floating point area
984 *
985 * Port Specific Information:
986 *
987 * XXX document implementation including references if appropriate
[7908ba5b]988 */
989#define _CPU_Context_Fp_start( _base, _offset ) \
990   ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
991
[baff4da]992/**
[d9e0006]993 * This routine initializes the FP context area passed to it to.
994 * There are a few standard ways in which to initialize the
995 * floating point context.  The code included for this macro assumes
996 * that this is a CPU in which a "initial" FP context was saved into
997 * @a _CPU_Null_fp_context and it simply copies it to the destination
998 * context passed to it.
[7908ba5b]999 *
[d9e0006]1000 * Other floating point context save/restore models include:
1001 *   -# not doing anything, and
1002 *   -# putting a "null FP status word" in the correct place in the FP context.
[df49c60]1003 *
[d9e0006]1004 * @param[in] _destination is the floating point context area
[baff4da]1005 *
[d9e0006]1006 * Port Specific Information:
[df49c60]1007 *
[d9e0006]1008 * XXX document implementation including references if appropriate
[7908ba5b]1009 */
1010#define _CPU_Context_Initialize_fp( _destination ) \
1011  { \
[b60dc893]1012   *(*(_destination)) = _CPU_Null_fp_context; \
[7908ba5b]1013  }
1014
1015/* end of Context handler macros */
1016
1017/* Fatal Error manager macros */
1018
[baff4da]1019/**
[d9e0006]1020 * This routine copies _error into a known place -- typically a stack
1021 * location or a register, optionally disables interrupts, and
1022 * halts/stops the CPU.
[df49c60]1023 *
[d9e0006]1024 * Port Specific Information:
[df49c60]1025 *
[d9e0006]1026 * XXX document implementation including references if appropriate
[7908ba5b]1027 */
1028#define _CPU_Fatal_halt( _error ) \
1029  { \
1030  }
1031
1032/* end of Fatal Error manager macros */
1033
1034/* Bitfield handler macros */
1035
[baff4da]1036/**
[d9e0006]1037 * @defgroup CPUBitfield Processor Dependent Bitfield Manipulation
[baff4da]1038 *
[d9e0006]1039 * This set of routines are used to implement fast searches for
1040 * the most important ready task.
1041 *
[baff4da]1042 */
[b697bc6]1043/**@{**/
[baff4da]1044
1045/**
[d9e0006]1046 * This definition is set to TRUE if the port uses the generic bitfield
1047 * manipulation implementation.
[baff4da]1048 */
1049#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
1050
1051/**
[d9e0006]1052 * This definition is set to TRUE if the port uses the data tables provided
1053 * by the generic bitfield manipulation implementation.
1054 * This can occur when actually using the generic bitfield manipulation
1055 * implementation or when implementing the same algorithm in assembly
1056 * language for improved performance.  It is unlikely that a port will use
1057 * the data if it has a bitfield scan instruction.
[baff4da]1058 */
1059#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
1060
1061/**
[d9e0006]1062 * This routine sets @a _output to the bit number of the first bit
1063 * set in @a _value.  @a _value is of CPU dependent type
[f570b071]1064 * @a Priority_bit_map_Word.  This type may be either 16 or 32 bits
[d9e0006]1065 * wide although only the 16 least significant bits will be used.
1066 *
1067 * There are a number of variables in using a "find first bit" type
1068 * instruction.
1069 *
1070 *   -# What happens when run on a value of zero?
1071 *   -# Bits may be numbered from MSB to LSB or vice-versa.
1072 *   -# The numbering may be zero or one based.
1073 *   -# The "find first bit" instruction may search from MSB or LSB.
1074 *
1075 * RTEMS guarantees that (1) will never happen so it is not a concern.
1076 * (2),(3), (4) are handled by the macros @ref _CPU_Priority_Mask and
1077 * @ref _CPU_Priority_bits_index.  These three form a set of routines
1078 * which must logically operate together.  Bits in the _value are
1079 * set and cleared based on masks built by @ref _CPU_Priority_Mask.
1080 * The basic major and minor values calculated by @ref _Priority_Major
1081 * and @ref _Priority_Minor are "massaged" by @ref _CPU_Priority_bits_index
1082 * to properly range between the values returned by the "find first bit"
1083 * instruction.  This makes it possible for @ref _Priority_Get_highest to
1084 * calculate the major and directly index into the minor table.
1085 * This mapping is necessary to ensure that 0 (a high priority major/minor)
1086 * is the first bit found.
1087 *
1088 * This entire "find first bit" and mapping process depends heavily
1089 * on the manner in which a priority is broken into a major and minor
1090 * components with the major being the 4 MSB of a priority and minor
1091 * the 4 LSB.  Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
1092 * priority.  And (15 << 4) + 14 corresponds to priority 254 -- the next
1093 * to the lowest priority.
1094 *
1095 * If your CPU does not have a "find first bit" instruction, then
1096 * there are ways to make do without it.  Here are a handful of ways
1097 * to implement this in software:
[7908ba5b]1098 *
[baff4da]1099@verbatim
1100      - a series of 16 bit test instructions
1101      - a "binary search using if's"
1102      - _number = 0
1103        if _value > 0x00ff
1104          _value >>=8
1105          _number = 8;
[80f7732]1106
[baff4da]1107        if _value > 0x0000f
1108          _value >=8
1109          _number += 4
[80f7732]1110
[baff4da]1111        _number += bit_set_table[ _value ]
1112@endverbatim
[80f7732]1113
[d9e0006]1114 *   where bit_set_table[ 16 ] has values which indicate the first
1115 *     bit set
[df49c60]1116 *
[d9e0006]1117 * @param[in] _value is the value to be scanned
1118 * @param[in] _output is the first bit set
[baff4da]1119 *
[d9e0006]1120 * Port Specific Information:
[df49c60]1121 *
[d9e0006]1122 * XXX document implementation including references if appropriate
[7908ba5b]1123 */
1124
1125#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
1126#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
1127  { \
1128    (_output) = 0;   /* do something to prevent warnings */ \
1129  }
1130#endif
1131
[d9e0006]1132/** @} */
1133
[7908ba5b]1134/* end of Bitfield handler macros */
1135
[baff4da]1136/**
[d9e0006]1137 * This routine builds the mask which corresponds to the bit fields
1138 * as searched by @ref _CPU_Bitfield_Find_first_bit.  See the discussion
1139 * for that routine.
[df49c60]1140 *
[d9e0006]1141 * Port Specific Information:
[df49c60]1142 *
[d9e0006]1143 * XXX document implementation including references if appropriate
[7908ba5b]1144 */
1145#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
1146
1147#define _CPU_Priority_Mask( _bit_number ) \
1148  ( 1 << (_bit_number) )
1149
1150#endif
1151
[baff4da]1152/**
[d9e0006]1153 * @ingroup CPUBitfield
1154 *
1155 * This routine translates the bit numbers returned by
1156 * @ref _CPU_Bitfield_Find_first_bit into something suitable for use as
1157 * a major or minor component of a priority.  See the discussion
1158 * for that routine.
[df49c60]1159 *
[d9e0006]1160 * @param[in] _priority is the major or minor number to translate
[baff4da]1161 *
[d9e0006]1162 * Port Specific Information:
[df49c60]1163 *
[d9e0006]1164 * XXX document implementation including references if appropriate
[7908ba5b]1165 */
1166#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
1167
1168#define _CPU_Priority_bits_index( _priority ) \
1169  (_priority)
1170
1171#endif
1172
1173/* end of Priority handler macros */
1174
1175/* functions */
1176
[baff4da]1177/**
[d9e0006]1178 * This routine performs CPU dependent initialization.
[df49c60]1179 *
[d9e0006]1180 * Port Specific Information:
[df49c60]1181 *
[d9e0006]1182 * XXX document implementation including references if appropriate
[7908ba5b]1183 */
[c03e2bc]1184void _CPU_Initialize(void);
[7908ba5b]1185
[baff4da]1186/**
[d9e0006]1187 * @ingroup CPUInterrupt
1188 *
1189 * This routine installs a "raw" interrupt handler directly into the
1190 * processor's vector table.
[df49c60]1191 *
[d9e0006]1192 * @param[in] vector is the vector number
1193 * @param[in] new_handler is the raw ISR handler to install
1194 * @param[in] old_handler is the previously installed ISR Handler
[baff4da]1195 *
[d9e0006]1196 * Port Specific Information:
[df49c60]1197 *
[d9e0006]1198 * XXX document implementation including references if appropriate
[7908ba5b]1199 */
1200void _CPU_ISR_install_raw_handler(
[c346f33d]1201  uint32_t    vector,
[7908ba5b]1202  proc_ptr    new_handler,
1203  proc_ptr   *old_handler
1204);
1205
[baff4da]1206/**
[d9e0006]1207 * @ingroup CPUInterrupt
1208 *
1209 * This routine installs an interrupt vector.
[df49c60]1210 *
[d9e0006]1211 * @param[in] vector is the vector number
1212 * @param[in] new_handler is the RTEMS ISR handler to install
1213 * @param[in] old_handler is the previously installed ISR Handler
[baff4da]1214 *
[d9e0006]1215 * Port Specific Information:
[df49c60]1216 *
[d9e0006]1217 * XXX document implementation including references if appropriate
[7908ba5b]1218 */
1219void _CPU_ISR_install_vector(
[c346f33d]1220  uint32_t    vector,
[7908ba5b]1221  proc_ptr    new_handler,
1222  proc_ptr   *old_handler
1223);
1224
[baff4da]1225/**
[d9e0006]1226 * @ingroup CPUInterrupt
1227 * This routine installs the hardware interrupt stack pointer.
[7908ba5b]1228 *
[d9e0006]1229 * NOTE:  It need only be provided if @ref CPU_HAS_HARDWARE_INTERRUPT_STACK
1230 *        is TRUE.
[df49c60]1231 *
[d9e0006]1232 * Port Specific Information:
[df49c60]1233 *
[d9e0006]1234 * XXX document implementation including references if appropriate
[7908ba5b]1235 */
1236void _CPU_Install_interrupt_stack( void );
1237
[baff4da]1238/**
[d9e0006]1239 * This routine is the CPU dependent IDLE thread body.
[7908ba5b]1240 *
[d9e0006]1241 * NOTE:  It need only be provided if @ref CPU_PROVIDES_IDLE_THREAD_BODY
[7908ba5b]1242 *         is TRUE.
[df49c60]1243 *
[d9e0006]1244 * Port Specific Information:
[df49c60]1245 *
[d9e0006]1246 * XXX document implementation including references if appropriate
[7908ba5b]1247 */
[cca8379]1248void *_CPU_Thread_Idle_body( uintptr_t ignored );
[7908ba5b]1249
[baff4da]1250/**
[d9e0006]1251 * @ingroup CPUContext
1252 *
1253 * This routine switches from the run context to the heir context.
[df49c60]1254 *
[d9e0006]1255 * @param[in] run points to the context of the currently executing task
1256 * @param[in] heir points to the context of the heir task
[baff4da]1257 *
[d9e0006]1258 * Port Specific Information:
[df49c60]1259 *
[d9e0006]1260 * XXX document implementation including references if appropriate
[7908ba5b]1261 */
1262void _CPU_Context_switch(
1263  Context_Control  *run,
1264  Context_Control  *heir
1265);
1266
[baff4da]1267/**
[d9e0006]1268 * @ingroup CPUContext
1269 *
1270 * This routine is generally used only to restart self in an
1271 * efficient manner.  It may simply be a label in @ref _CPU_Context_switch.
[7908ba5b]1272 *
[d9e0006]1273 * @param[in] new_context points to the context to be restored.
[df49c60]1274 *
[d9e0006]1275 * NOTE: May be unnecessary to reload some registers.
[baff4da]1276 *
[d9e0006]1277 * Port Specific Information:
[df49c60]1278 *
[d9e0006]1279 * XXX document implementation including references if appropriate
[7908ba5b]1280 */
1281void _CPU_Context_restore(
1282  Context_Control *new_context
[479cbaf8]1283) RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
[7908ba5b]1284
[baff4da]1285/**
[d9e0006]1286 * @ingroup CPUContext
1287 *
1288 * This routine saves the floating point context passed to it.
[df49c60]1289 *
[d9e0006]1290 * @param[in] fp_context_ptr is a pointer to a pointer to a floating
1291 * point context area
[baff4da]1292 *
[d9e0006]1293 * @return on output @a *fp_context_ptr will contain the address that
1294 * should be used with @ref _CPU_Context_restore_fp to restore this context.
[baff4da]1295 *
[d9e0006]1296 * Port Specific Information:
[df49c60]1297 *
[d9e0006]1298 * XXX document implementation including references if appropriate
[7908ba5b]1299 */
1300void _CPU_Context_save_fp(
[b60dc893]1301  Context_Control_fp **fp_context_ptr
[7908ba5b]1302);
1303
[baff4da]1304/**
[d9e0006]1305 * @ingroup CPUContext
1306 *
1307 * This routine restores the floating point context passed to it.
[df49c60]1308 *
[d9e0006]1309 * @param[in] fp_context_ptr is a pointer to a pointer to a floating
1310 * point context area to restore
[baff4da]1311 *
[d9e0006]1312 * @return on output @a *fp_context_ptr will contain the address that
1313 * should be used with @ref _CPU_Context_save_fp to save this context.
[baff4da]1314 *
[d9e0006]1315 * Port Specific Information:
[df49c60]1316 *
[d9e0006]1317 * XXX document implementation including references if appropriate
[7908ba5b]1318 */
1319void _CPU_Context_restore_fp(
[b60dc893]1320  Context_Control_fp **fp_context_ptr
[7908ba5b]1321);
1322
[39993d6]1323/**
1324 * @ingroup CPUContext
1325 *
1326 * @brief Clobbers all volatile registers with values derived from the pattern
1327 * parameter.
1328 *
1329 * This function is used only in test sptests/spcontext01.
1330 *
1331 * @param[in] pattern Pattern used to generate distinct register values.
1332 *
1333 * @see _CPU_Context_validate().
1334 */
1335void _CPU_Context_volatile_clobber( uintptr_t pattern );
1336
1337/**
1338 * @ingroup CPUContext
1339 *
1340 * @brief Initializes and validates the CPU context with values derived from
1341 * the pattern parameter.
1342 *
1343 * This function will not return if the CPU context remains consistent.  In
1344 * case this function returns the CPU port is broken.
1345 *
1346 * This function is used only in test sptests/spcontext01.
1347 *
1348 * @param[in] pattern Pattern used to generate distinct register values.
1349 *
1350 * @see _CPU_Context_volatile_clobber().
1351 */
1352void _CPU_Context_validate( uintptr_t pattern );
1353
[815994f]1354/**
[d9e0006]1355 * @brief The set of registers that specifies the complete processor state.
[815994f]1356 *
[d9e0006]1357 * The CPU exception frame may be available in fatal error conditions like for
1358 * example illegal opcodes, instruction fetch errors, or data access errors.
[815994f]1359 *
[d9e0006]1360 * @see rtems_fatal(), RTEMS_FATAL_SOURCE_EXCEPTION, and
1361 * rtems_exception_frame_print().
[815994f]1362 */
1363typedef struct {
1364  uint32_t processor_state_register;
1365  uint32_t integer_registers [1];
1366  double float_registers [1];
1367} CPU_Exception_frame;
1368
1369/**
[d9e0006]1370 * @brief Prints the exception frame via printk().
[815994f]1371 *
[d9e0006]1372 * @see rtems_fatal() and RTEMS_FATAL_SOURCE_EXCEPTION.
[815994f]1373 */
1374void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
1375
[baff4da]1376/**
[d9e0006]1377 * @ingroup CPUEndian
1378 *
1379 * The following routine swaps the endian format of an unsigned int.
1380 * It must be static because it is referenced indirectly.
[7908ba5b]1381 *
[d9e0006]1382 * This version will work on any processor, but if there is a better
1383 * way for your CPU PLEASE use it.  The most common way to do this is to:
[7908ba5b]1384 *
[d9e0006]1385 *    swap least significant two bytes with 16-bit rotate
1386 *    swap upper and lower 16-bits
1387 *    swap most significant two bytes with 16-bit rotate
[7908ba5b]1388 *
[d9e0006]1389 * Some CPUs have special instructions which swap a 32-bit quantity in
1390 * a single instruction (e.g. i486).  It is probably best to avoid
1391 * an "endian swapping control bit" in the CPU.  One good reason is
1392 * that interrupts would probably have to be disabled to ensure that
1393 * an interrupt does not try to access the same "chunk" with the wrong
1394 * endian.  Another good reason is that on some CPUs, the endian bit
1395 * endianness for ALL fetches -- both code and data -- so the code
1396 * will be fetched incorrectly.
[df49c60]1397 *
[d9e0006]1398 * @param[in] value is the value to be swapped
1399 * @return the value after being endian swapped
[baff4da]1400 *
[d9e0006]1401 * Port Specific Information:
[df49c60]1402 *
[d9e0006]1403 * XXX document implementation including references if appropriate
[7908ba5b]1404 */
[ec8973ed]1405static inline uint32_t CPU_swap_u32(
1406  uint32_t value
[7908ba5b]1407)
1408{
[5c5d438]1409  uint32_t byte1, byte2, byte3, byte4, swapped;
[80f7732]1410
[7908ba5b]1411  byte4 = (value >> 24) & 0xff;
1412  byte3 = (value >> 16) & 0xff;
1413  byte2 = (value >> 8)  & 0xff;
1414  byte1 =  value        & 0xff;
[80f7732]1415
[7908ba5b]1416  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
[5c5d438]1417  return swapped;
[7908ba5b]1418}
1419
[baff4da]1420/**
[d9e0006]1421 * @ingroup CPUEndian
1422 *
1423 * This routine swaps a 16 bir quantity.
[baff4da]1424 *
[d9e0006]1425 * @param[in] value is the value to be swapped
1426 * @return the value after being endian swapped
[baff4da]1427 */
[7908ba5b]1428#define CPU_swap_u16( value ) \
1429  (((value&0xff) << 8) | ((value >> 8)&0xff))
1430
[24bf11e]1431/**
1432 * @brief Unsigned integer type for CPU counter values.
1433 */
1434typedef uint32_t CPU_Counter_ticks;
1435
1436/**
1437 * @brief Returns the current CPU counter value.
1438 *
1439 * A CPU counter is some free-running counter.  It ticks usually with a
1440 * frequency close to the CPU or system bus clock.  The board support package
1441 * must ensure that this function works before the RTEMS initialization.
1442 * Otherwise invalid profiling statistics will be gathered.
1443 *
1444 * @return The current CPU counter value.
1445 */
1446CPU_Counter_ticks _CPU_Counter_read( void );
1447
1448/**
1449 * @brief Returns the difference between the second and first CPU counter
1450 * value.
1451 *
1452 * This operation may be carried out as a modulo operation depending on the
1453 * range of the CPU counter device.
1454 *
1455 * @param[in] second The second CPU counter value.
1456 * @param[in] first The first CPU counter value.
1457 *
1458 * @return Returns second minus first modulo counter period.
1459 */
1460CPU_Counter_ticks _CPU_Counter_difference(
1461  CPU_Counter_ticks second,
1462  CPU_Counter_ticks first
1463);
1464
[e5120a5]1465/**
1466 * @brief Special register pointing to the per-CPU control of the current
1467 * processor.
1468 *
1469 * This is optional.  Not every CPU port needs this.  It is only an optional
1470 * optimization variant.
1471 */
1472register struct Per_CPU_Control *_CPU_Per_CPU_current asm( "rX" );
1473
1474/**
1475 * @brief Optional method to obtain the per-CPU control of the current processor.
1476 *
1477 * This is optional.  Not every CPU port needs this.  It is only an optional
1478 * optimization variant.  In case this macro is undefined, the default
1479 * implementation using the current processor index will be used.
1480 */
1481#define _CPU_Get_current_per_CPU_control() ( _CPU_Per_CPU_current )
1482
[2f6108f9]1483#ifdef RTEMS_SMP
[4627fcd]1484  /**
[7336be9d]1485   * @brief Performs CPU specific SMP initialization in the context of the boot
[4627fcd]1486   * processor.
1487   *
[53e008b]1488   * This function is invoked on the boot processor during system
[4627fcd]1489   * initialization.  All interrupt stacks are allocated at this point in case
[53e008b]1490   * the CPU port allocates the interrupt stacks.  This function is called
1491   * before _CPU_SMP_Start_processor() or _CPU_SMP_Finalize_initialization() is
1492   * used.
[4627fcd]1493   *
[53e008b]1494   * @return The count of physically or virtually available processors.
1495   * Depending on the configuration the application may use not all processors.
1496   */
1497  uint32_t _CPU_SMP_Initialize( void );
1498
1499  /**
1500   * @brief Starts a processor specified by its index.
1501   *
1502   * This function is invoked on the boot processor during system
1503   * initialization.
1504   *
1505   * This function will be called after _CPU_SMP_Initialize().
1506   *
1507   * @param[in] cpu_index The processor index.
1508   *
1509   * @retval true Successful operation.
1510   * @retval false Unable to start this processor.
1511   */
1512  bool _CPU_SMP_Start_processor( uint32_t cpu_index );
1513
1514  /**
1515   * @brief Performs final steps of CPU specific SMP initialization in the
1516   * context of the boot processor.
1517   *
1518   * This function is invoked on the boot processor during system
1519   * initialization.
[4627fcd]1520   *
[53e008b]1521   * This function will be called after all processors requested by the
1522   * application have been started.
[4627fcd]1523   *
[53e008b]1524   * @param[in] cpu_count The minimum value of the count of processors
1525   * requested by the application configuration and the count of physically or
1526   * virtually available processors.
[4627fcd]1527   */
[53e008b]1528  void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
[4627fcd]1529
[39e51758]1530  /**
1531   * @brief Returns the index of the current processor.
1532   *
1533   * An architecture specific method must be used to obtain the index of the
1534   * current processor in the system.  The set of processor indices is the
1535   * range of integers starting with zero up to the processor count minus one.
1536   */
[47d60134]1537  static inline uint32_t _CPU_SMP_Get_current_processor( void )
[39e51758]1538  {
1539    return 123;
1540  }
1541
[ca63ae2]1542  /**
1543   * @brief Sends an inter-processor interrupt to the specified target
1544   * processor.
1545   *
1546   * This operation is undefined for target processor indices out of range.
1547   *
1548   * @param[in] target_processor_index The target processor index.
1549   */
1550  void _CPU_SMP_Send_interrupt( uint32_t target_processor_index );
1551
[2f6108f9]1552  /**
1553   * @brief Broadcasts a processor event.
1554   *
1555   * Some architectures provide a low-level synchronization primitive for
1556   * processors in a multi-processor environment.  Processors waiting for this
1557   * event may go into a low-power state and stop generating system bus
1558   * transactions.  This function must ensure that preceding store operations
1559   * can be observed by other processors.
1560   *
[f7740e97]1561   * @see _CPU_SMP_Processor_event_receive().
[2f6108f9]1562   */
[07f6e419]1563  static inline void _CPU_SMP_Processor_event_broadcast( void )
[2f6108f9]1564  {
1565    __asm__ volatile ( "" : : : "memory" );
1566  }
1567
1568  /**
1569   * @brief Receives a processor event.
1570   *
1571   * This function will wait for the processor event and may wait forever if no
1572   * such event arrives.
1573   *
[07f6e419]1574   * @see _CPU_SMP_Processor_event_broadcast().
[2f6108f9]1575   */
[f7740e97]1576  static inline void _CPU_SMP_Processor_event_receive( void )
[2f6108f9]1577  {
1578    __asm__ volatile ( "" : : : "memory" );
1579  }
1580#endif
1581
[7908ba5b]1582#ifdef __cplusplus
1583}
1584#endif
1585
1586#endif
Note: See TracBrowser for help on using the repository browser.