source: rtems/cpukit/score/cpu/v850/include/rtems/score/cpu.h @ e88abc0

5
Last change on this file since e88abc0 was 2afb22b, checked in by Chris Johns <chrisj@…>, on 12/23/17 at 07:18:56

Remove make preinstall

A speciality of the RTEMS build system was the make preinstall step. It
copied header files from arbitrary locations into the build tree. The
header files were included via the -Bsome/build/tree/path GCC command
line option.

This has at least seven problems:

  • The make preinstall step itself needs time and disk space.
  • Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error.
  • There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult.
  • The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit.
  • An introduction of a new build system is difficult.
  • Include paths specified by the -B option are system headers. This may suppress warnings.
  • The parallel build had sporadic failures on some hosts.

This patch removes the make preinstall step. All installed header
files are moved to dedicated include directories in the source tree.
Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc,
etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g.
erc32, imx, qoriq, etc.

The new cpukit include directories are:

  • cpukit/include
  • cpukit/score/cpu/@RTEMS_CPU@/include
  • cpukit/libnetworking

The new BSP include directories are:

  • bsps/include
  • bsps/@RTEMS_CPU@/include
  • bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include

There are build tree include directories for generated files.

The include directory order favours the most general header file, e.g.
it is not possible to override general header files via the include path
order.

The "bootstrap -p" option was removed. The new "bootstrap -H" option
should be used to regenerate the "headers.am" files.

Update #3254.

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