source: rtems/c/src/exec/score/cpu/a29k/rtems/score/cpu.h @ 458bd34

4.104.114.84.95
Last change on this file since 458bd34 was 458bd34, checked in by Joel Sherrill <joel.sherrill@…>, on 11/05/99 at 16:44:02

This is another pass at making sure that nothing outside the BSP
unnecessarily uses any variables defined by the BSP. On this
sweep, use of BSP_Configuration and Cpu_table was eliminated.

A significant part of this modification was the addition of
macros to access fields in the RTEMS configuration structures.

This is necessary to strengthen the division between the BSP independent
parts of RTEMS and the BSPs themselves. This started after
comments and analysis by Ralf Corsepius <corsepiu@…>.

  • Property mode set to 100644
File size: 32.3 KB
Line 
1/*  cpu.h
2 *
3 *  This include file contains information pertaining to the AMD 29K
4 *  processor.
5 *
6 *  Author:     Craig Lebakken <craigl@transition.com>
7 *
8 *  COPYRIGHT (c) 1996 by Transition Networks Inc.
9 *
10 *  To anyone who acknowledges that this file is provided "AS IS"
11 *  without any express or implied warranty:
12 *      permission to use, copy, modify, and distribute this file
13 *      for any purpose is hereby granted without fee, provided that
14 *      the above copyright notice and this notice appears in all
15 *      copies, and that the name of Transition Networks not be used in
16 *      advertising or publicity pertaining to distribution of the
17 *      software without specific, written prior permission.
18 *      Transition Networks makes no representations about the suitability
19 *      of this software for any purpose.
20 *
21 *  Derived from c/src/exec/score/cpu/no_cpu/cpu_asm.c:
22 *
23 *  COPYRIGHT (c) 1989-1998.
24 *  On-Line Applications Research Corporation (OAR).
25 *  Copyright assigned to U.S. Government, 1994.
26 *
27 *  The license and distribution terms for this file may be
28 *  found in the file LICENSE in this distribution or at
29 *  http://www.OARcorp.com/rtems/license.html.
30 *
31 *  $Id$
32 */
33/* @(#)cpu.h    10/21/96        1.11 */
34
35#ifndef __CPU_h
36#define __CPU_h
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42#include <rtems/score/a29k.h>                /* pick up machine definitions */
43#ifndef ASM
44#include <rtems/score/a29ktypes.h>
45#endif
46
47extern unsigned int a29k_disable( void );
48extern void a29k_enable( unsigned int cookie );
49extern unsigned int a29k_getops( void );
50extern void a29k_getops_sup( void );
51extern void a29k_disable_sup( void );
52extern void a29k_enable_sup( void );
53extern void a29k_disable_all( void );
54extern void a29k_disable_all_sup( void );
55extern void a29k_enable_all( void );
56extern void a29k_enable_all_sup( void );
57extern void a29k_halt( void );
58extern void a29k_fatal_error( unsigned32 error );
59extern void a29k_as70( void );
60extern void a29k_super_mode( void );
61extern void a29k_context_switch_sup(void);
62extern void a29k_context_restore_sup(void);
63extern void a29k_context_save_sup(void);
64extern void a29k_sigdfl_sup(void);
65
66/* conditional compilation parameters */
67
68/*
69 *  Should the calls to _Thread_Enable_dispatch be inlined?
70 *
71 *  If TRUE, then they are inlined.
72 *  If FALSE, then a subroutine call is made.
73 *
74 *  Basically this is an example of the classic trade-off of size
75 *  versus speed.  Inlining the call (TRUE) typically increases the
76 *  size of RTEMS while speeding up the enabling of dispatching.
77 *  [NOTE: In general, the _Thread_Dispatch_disable_level will
78 *  only be 0 or 1 unless you are in an interrupt handler and that
79 *  interrupt handler invokes the executive.]  When not inlined
80 *  something calls _Thread_Enable_dispatch which in turns calls
81 *  _Thread_Dispatch.  If the enable dispatch is inlined, then
82 *  one subroutine call is avoided entirely.]
83 */
84
85#define CPU_INLINE_ENABLE_DISPATCH       TRUE
86
87/*
88 *  Should the body of the search loops in _Thread_queue_Enqueue_priority
89 *  be unrolled one time?  In unrolled each iteration of the loop examines
90 *  two "nodes" on the chain being searched.  Otherwise, only one node
91 *  is examined per iteration.
92 *
93 *  If TRUE, then the loops are unrolled.
94 *  If FALSE, then the loops are not unrolled.
95 *
96 *  The primary factor in making this decision is the cost of disabling
97 *  and enabling interrupts (_ISR_Flash) versus the cost of rest of the
98 *  body of the loop.  On some CPUs, the flash is more expensive than
99 *  one iteration of the loop body.  In this case, it might be desirable
100 *  to unroll the loop.  It is important to note that on some CPUs, this
101 *  code is the longest interrupt disable period in RTEMS.  So it is
102 *  necessary to strike a balance when setting this parameter.
103 */
104
105#define CPU_UNROLL_ENQUEUE_PRIORITY      TRUE
106
107/*
108 *  Does RTEMS manage a dedicated interrupt stack in software?
109 *
110 *  If TRUE, then a stack is allocated in _Interrupt_Manager_initialization.
111 *  If FALSE, nothing is done.
112 *
113 *  If the CPU supports a dedicated interrupt stack in hardware,
114 *  then it is generally the responsibility of the BSP to allocate it
115 *  and set it up.
116 *
117 *  If the CPU does not support a dedicated interrupt stack, then
118 *  the porter has two options: (1) execute interrupts on the
119 *  stack of the interrupted task, and (2) have RTEMS manage a dedicated
120 *  interrupt stack.
121 *
122 *  If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
123 *
124 *  Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
125 *  CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE.  It is
126 *  possible that both are FALSE for a particular CPU.  Although it
127 *  is unclear what that would imply about the interrupt processing
128 *  procedure on that CPU.
129 */
130
131#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
132
133/*
134 *  Does this CPU have hardware support for a dedicated interrupt stack?
135 *
136 *  If TRUE, then it must be installed during initialization.
137 *  If FALSE, then no installation is performed.
138 *
139 *  If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
140 *
141 *  Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
142 *  CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE.  It is
143 *  possible that both are FALSE for a particular CPU.  Although it
144 *  is unclear what that would imply about the interrupt processing
145 *  procedure on that CPU.
146 */
147
148#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
149
150/*
151 *  Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
152 *
153 *  If TRUE, then the memory is allocated during initialization.
154 *  If FALSE, then the memory is allocated during initialization.
155 *
156 *  This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE
157 *  or CPU_INSTALL_HARDWARE_INTERRUPT_STACK is TRUE.
158 */
159
160#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
161
162/*
163 *  Does the RTEMS invoke the user's ISR with the vector number and
164 *  a pointer to the saved interrupt frame (1) or just the vector
165 *  number (0)?
166 */
167
168#define CPU_ISR_PASSES_FRAME_POINTER 0
169
170/*
171 *  Does the CPU have hardware floating point?
172 *
173 *  If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
174 *  If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
175 *
176 *  If there is a FP coprocessor such as the i387 or mc68881, then
177 *  the answer is TRUE.
178 *
179 *  The macro name "NO_CPU_HAS_FPU" should be made CPU specific.
180 *  It indicates whether or not this CPU model has FP support.  For
181 *  example, it would be possible to have an i386_nofp CPU model
182 *  which set this to false to indicate that you have an i386 without
183 *  an i387 and wish to leave floating point support out of RTEMS.
184 */
185
186#if ( A29K_HAS_FPU == 1 )
187#define CPU_HARDWARE_FP     TRUE
188#else
189#define CPU_HARDWARE_FP     FALSE
190#endif
191
192/*
193 *  Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
194 *
195 *  If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
196 *  If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
197 *
198 *  So far, the only CPU in which this option has been used is the
199 *  HP PA-RISC.  The HP C compiler and gcc both implicitly use the
200 *  floating point registers to perform integer multiplies.  If
201 *  a function which you would not think utilize the FP unit DOES,
202 *  then one can not easily predict which tasks will use the FP hardware.
203 *  In this case, this option should be TRUE.
204 *
205 *  If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
206 */
207
208#define CPU_ALL_TASKS_ARE_FP     FALSE
209
210/*
211 *  Should the IDLE task have a floating point context?
212 *
213 *  If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
214 *  and it has a floating point context which is switched in and out.
215 *  If FALSE, then the IDLE task does not have a floating point context.
216 *
217 *  Setting this to TRUE negatively impacts the time required to preempt
218 *  the IDLE task from an interrupt because the floating point context
219 *  must be saved as part of the preemption.
220 */
221
222#define CPU_IDLE_TASK_IS_FP      FALSE
223
224/*
225 *  Should the saving of the floating point registers be deferred
226 *  until a context switch is made to another different floating point
227 *  task?
228 *
229 *  If TRUE, then the floating point context will not be stored until
230 *  necessary.  It will remain in the floating point registers and not
231 *  disturned until another floating point task is switched to.
232 *
233 *  If FALSE, then the floating point context is saved when a floating
234 *  point task is switched out and restored when the next floating point
235 *  task is restored.  The state of the floating point registers between
236 *  those two operations is not specified.
237 *
238 *  If the floating point context does NOT have to be saved as part of
239 *  interrupt dispatching, then it should be safe to set this to TRUE.
240 *
241 *  Setting this flag to TRUE results in using a different algorithm
242 *  for deciding when to save and restore the floating point context.
243 *  The deferred FP switch algorithm minimizes the number of times
244 *  the FP context is saved and restored.  The FP context is not saved
245 *  until a context switch is made to another, different FP task.
246 *  Thus in a system with only one FP task, the FP context will never
247 *  be saved or restored.
248 */
249
250#define CPU_USE_DEFERRED_FP_SWITCH       TRUE
251
252/*
253 *  Does this port provide a CPU dependent IDLE task implementation?
254 *
255 *  If TRUE, then the routine _CPU_Internal_threads_Idle_thread_body
256 *  must be provided and is the default IDLE thread body instead of
257 *  _Internal_threads_Idle_thread_body.
258 *
259 *  If FALSE, then use the generic IDLE thread body if the BSP does
260 *  not provide one.
261 *
262 *  This is intended to allow for supporting processors which have
263 *  a low power or idle mode.  When the IDLE thread is executed, then
264 *  the CPU can be powered down.
265 *
266 *  The order of precedence for selecting the IDLE thread body is:
267 *
268 *    1.  BSP provided
269 *    2.  CPU dependent (if provided)
270 *    3.  generic (if no BSP and no CPU dependent)
271 */
272
273#define CPU_PROVIDES_IDLE_THREAD_BODY    TRUE
274
275/*
276 *  Does the stack grow up (toward higher addresses) or down
277 *  (toward lower addresses)?
278 *
279 *  If TRUE, then the grows upward.
280 *  If FALSE, then the grows toward smaller addresses.
281 */
282
283#define CPU_STACK_GROWS_UP               FALSE
284
285/*
286 *  The following is the variable attribute used to force alignment
287 *  of critical RTEMS structures.  On some processors it may make
288 *  sense to have these aligned on tighter boundaries than
289 *  the minimum requirements of the compiler in order to have as
290 *  much of the critical data area as possible in a cache line.
291 *
292 *  The placement of this macro in the declaration of the variables
293 *  is based on the syntactically requirements of the GNU C
294 *  "__attribute__" extension.  For example with GNU C, use
295 *  the following to force a structures to a 32 byte boundary.
296 *
297 *      __attribute__ ((aligned (32)))
298 *
299 *  NOTE:  Currently only the Priority Bit Map table uses this feature.
300 *         To benefit from using this, the data must be heavily
301 *         used so it will stay in the cache and used frequently enough
302 *         in the executive to justify turning this on.
303 */
304
305#define CPU_STRUCTURE_ALIGNMENT
306
307/*
308 *  Define what is required to specify how the network to host conversion
309 *  routines are handled.
310 *
311 */
312
313#error "Check these definitions!!!"
314
315#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES     FALSE
316#define CPU_BIG_ENDIAN                           TRUE
317#define CPU_LITTLE_ENDIAN                        FALSE
318
319/*
320 *  The following defines the number of bits actually used in the
321 *  interrupt field of the task mode.  How those bits map to the
322 *  CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
323 */
324
325#define CPU_MODES_INTERRUPT_MASK   0x00000001
326
327/*
328 *  Processor defined structures
329 *
330 *  Examples structures include the descriptor tables from the i386
331 *  and the processor control structure on the i960ca.
332 */
333
334/* may need to put some structures here.  */
335
336/*
337 * Contexts
338 *
339 *  Generally there are 2 types of context to save.
340 *     1. Interrupt registers to save
341 *     2. Task level registers to save
342 *
343 *  This means we have the following 3 context items:
344 *     1. task level context stuff::  Context_Control
345 *     2. floating point task stuff:: Context_Control_fp
346 *     3. special interrupt level context :: Context_Control_interrupt
347 *
348 *  On some processors, it is cost-effective to save only the callee
349 *  preserved registers during a task context switch.  This means
350 *  that the ISR code needs to save those registers which do not
351 *  persist across function calls.  It is not mandatory to make this
352 *  distinctions between the caller/callee saves registers for the
353 *  purpose of minimizing context saved during task switch and on interrupts.
354 *  If the cost of saving extra registers is minimal, simplicity is the
355 *  choice.  Save the same context on interrupt entry as for tasks in
356 *  this case.
357 *
358 *  Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
359 *  care should be used in designing the context area.
360 *
361 *  On some CPUs with hardware floating point support, the Context_Control_fp
362 *  structure will not be used or it simply consist of an array of a
363 *  fixed number of bytes.   This is done when the floating point context
364 *  is dumped by a "FP save context" type instruction and the format
365 *  is not really defined by the CPU.  In this case, there is no need
366 *  to figure out the exact format -- only the size.  Of course, although
367 *  this is enough information for RTEMS, it is probably not enough for
368 *  a debugger such as gdb.  But that is another problem.
369 */
370
371typedef struct {
372    unsigned32 signal;
373    unsigned32 gr1;
374    unsigned32 rab;
375    unsigned32 PC0;
376    unsigned32 PC1;
377    unsigned32 PC2;
378    unsigned32 CHA;
379    unsigned32 CHD;
380    unsigned32 CHC;
381    unsigned32 ALU;
382    unsigned32 OPS;
383    unsigned32 tav;
384    unsigned32 lr1;
385    unsigned32 rfb;
386    unsigned32 msp;
387
388    unsigned32 FPStat0;
389    unsigned32 FPStat1;
390    unsigned32 FPStat2;
391    unsigned32 IPA;
392    unsigned32 IPB;
393    unsigned32 IPC;
394    unsigned32 Q;
395
396    unsigned32 gr96;
397    unsigned32 gr97;
398    unsigned32 gr98;
399    unsigned32 gr99;
400    unsigned32 gr100;
401    unsigned32 gr101;
402    unsigned32 gr102;
403    unsigned32 gr103;
404    unsigned32 gr104;
405    unsigned32 gr105;
406    unsigned32 gr106;
407    unsigned32 gr107;
408    unsigned32 gr108;
409    unsigned32 gr109;
410    unsigned32 gr110;
411    unsigned32 gr111;
412
413    unsigned32 gr112;
414    unsigned32 gr113;
415    unsigned32 gr114;
416    unsigned32 gr115;
417
418    unsigned32 gr116;
419    unsigned32 gr117;
420    unsigned32 gr118;
421    unsigned32 gr119;
422    unsigned32 gr120;
423    unsigned32 gr121;
424    unsigned32 gr122;
425    unsigned32 gr123;
426    unsigned32 gr124;
427
428    unsigned32 local_count;
429
430    unsigned32 locals[128];
431} Context_Control;
432
433typedef struct {
434    double      some_float_register;
435} Context_Control_fp;
436
437typedef struct {
438    unsigned32 special_interrupt_register;
439} CPU_Interrupt_frame;
440
441
442/*
443 *  The following table contains the information required to configure
444 *  the XXX processor specific parameters.
445 *
446 *  NOTE: The interrupt_stack_size field is required if
447 *        CPU_ALLOCATE_INTERRUPT_STACK is defined as TRUE.
448 *
449 *        The pretasking_hook, predriver_hook, and postdriver_hook,
450 *        and the do_zero_of_workspace fields are required on ALL CPUs.
451 */
452
453typedef struct {
454  void       (*pretasking_hook)( void );
455  void       (*predriver_hook)( void );
456  void       (*postdriver_hook)( void );
457  void       (*idle_task)( void );
458  boolean      do_zero_of_workspace;
459  unsigned32   idle_task_stack_size;
460  unsigned32   interrupt_stack_size;
461  unsigned32   extra_system_initialization_stack;
462}   rtems_cpu_table;
463
464/*
465 *  Macros to access required entires in the CPU Table are in
466 *  the file rtems/system.h.
467 */
468
469/*
470 *  Macros to access AMD A29K specific additions to the CPU Table
471 */
472
473/* There are no CPU specific additions to the CPU Table for this port. */
474
475/*
476 *  This variable is optional.  It is used on CPUs on which it is difficult
477 *  to generate an "uninitialized" FP context.  It is filled in by
478 *  _CPU_Initialize and copied into the task's FP context area during
479 *  _CPU_Context_Initialize.
480 */
481
482EXTERN Context_Control_fp  _CPU_Null_fp_context;
483
484/*
485 *  On some CPUs, RTEMS supports a software managed interrupt stack.
486 *  This stack is allocated by the Interrupt Manager and the switch
487 *  is performed in _ISR_Handler.  These variables contain pointers
488 *  to the lowest and highest addresses in the chunk of memory allocated
489 *  for the interrupt stack.  Since it is unknown whether the stack
490 *  grows up or down (in general), this give the CPU dependent
491 *  code the option of picking the version it wants to use.
492 *
493 *  NOTE: These two variables are required if the macro
494 *        CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
495 */
496
497EXTERN void               *_CPU_Interrupt_stack_low;
498EXTERN void               *_CPU_Interrupt_stack_high;
499
500/*
501 *  With some compilation systems, it is difficult if not impossible to
502 *  call a high-level language routine from assembly language.  This
503 *  is especially true of commercial Ada compilers and name mangling
504 *  C++ ones.  This variable can be optionally defined by the CPU porter
505 *  and contains the address of the routine _Thread_Dispatch.  This
506 *  can make it easier to invoke that routine at the end of the interrupt
507 *  sequence (if a dispatch is necessary).
508 */
509
510EXTERN void           (*_CPU_Thread_dispatch_pointer)();
511
512/*
513 *  Nothing prevents the porter from declaring more CPU specific variables.
514 */
515
516/* XXX: if needed, put more variables here */
517
518/*
519 *  The size of the floating point context area.  On some CPUs this
520 *  will not be a "sizeof" because the format of the floating point
521 *  area is not defined -- only the size is.  This is usually on
522 *  CPUs with a "floating point save context" instruction.
523 */
524
525#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
526
527/*
528 *  Amount of extra stack (above minimum stack size) required by
529 *  system initialization thread.  Remember that in a multiprocessor
530 *  system the system intialization thread becomes the MP server thread.
531 */
532
533#define CPU_SYSTEM_INITIALIZATION_THREAD_EXTRA_STACK 0
534
535/*
536 *  This defines the number of entries in the ISR_Vector_table managed
537 *  by RTEMS.
538 */
539
540#define CPU_INTERRUPT_NUMBER_OF_VECTORS      256
541#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER  (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
542
543/*
544 *  Should be large enough to run all RTEMS tests.  This insures
545 *  that a "reasonable" small application should not have any problems.
546 */
547
548#define CPU_STACK_MINIMUM_SIZE          (8192)
549
550/*
551 *  CPU's worst alignment requirement for data types on a byte boundary.  This
552 *  alignment does not take into account the requirements for the stack.
553 */
554
555#define CPU_ALIGNMENT              4
556
557/*
558 *  This number corresponds to the byte alignment requirement for the
559 *  heap handler.  This alignment requirement may be stricter than that
560 *  for the data types alignment specified by CPU_ALIGNMENT.  It is
561 *  common for the heap to follow the same alignment requirement as
562 *  CPU_ALIGNMENT.  If the CPU_ALIGNMENT is strict enough for the heap,
563 *  then this should be set to CPU_ALIGNMENT.
564 *
565 *  NOTE:  This does not have to be a power of 2.  It does have to
566 *         be greater or equal to than CPU_ALIGNMENT.
567 */
568
569#define CPU_HEAP_ALIGNMENT         CPU_ALIGNMENT
570
571/*
572 *  This number corresponds to the byte alignment requirement for memory
573 *  buffers allocated by the partition manager.  This alignment requirement
574 *  may be stricter than that for the data types alignment specified by
575 *  CPU_ALIGNMENT.  It is common for the partition to follow the same
576 *  alignment requirement as CPU_ALIGNMENT.  If the CPU_ALIGNMENT is strict
577 *  enough for the partition, then this should be set to CPU_ALIGNMENT.
578 *
579 *  NOTE:  This does not have to be a power of 2.  It does have to
580 *         be greater or equal to than CPU_ALIGNMENT.
581 */
582
583#define CPU_PARTITION_ALIGNMENT    CPU_ALIGNMENT
584
585/*
586 *  This number corresponds to the byte alignment requirement for the
587 *  stack.  This alignment requirement may be stricter than that for the
588 *  data types alignment specified by CPU_ALIGNMENT.  If the CPU_ALIGNMENT
589 *  is strict enough for the stack, then this should be set to 0.
590 *
591 *  NOTE:  This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
592 */
593
594#define CPU_STACK_ALIGNMENT        0
595
596/* ISR handler macros */
597
598/*
599 *  Disable all interrupts for an RTEMS critical section.  The previous
600 *  level is returned in _level.
601 */
602
603#define _CPU_ISR_Disable( _isr_cookie ) \
604    do{ _isr_cookie = a29k_disable(); }while(0)
605
606/*
607 *  Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
608 *  This indicates the end of an RTEMS critical section.  The parameter
609 *  _level is not modified.
610 */
611
612#define _CPU_ISR_Enable( _isr_cookie )  \
613      do{ a29k_enable(_isr_cookie) ; }while(0)
614
615/*
616 *  This temporarily restores the interrupt to _level before immediately
617 *  disabling them again.  This is used to divide long RTEMS critical
618 *  sections into two or more parts.  The parameter _level is not
619 * modified.
620 */
621
622#define _CPU_ISR_Flash( _isr_cookie ) \
623  do{ \
624     _CPU_ISR_Enable( _isr_cookie ); \
625     _CPU_ISR_Disable( _isr_cookie ); \
626  }while(0)
627
628/*
629 *  Map interrupt level in task mode onto the hardware that the CPU
630 *  actually provides.  Currently, interrupt levels which do not
631 *  map onto the CPU in a generic fashion are undefined.  Someday,
632 *  it would be nice if these were "mapped" by the application
633 *  via a callout.  For example, m68k has 8 levels 0 - 7, levels
634 *  8 - 255 would be available for bsp/application specific meaning.
635 *  This could be used to manage a programmable interrupt controller
636 *  via the rtems_task_mode directive.
637 */
638
639#define _CPU_ISR_Set_level( new_level ) \
640  do{ \
641    if ( new_level ) a29k_disable_all(); \
642    else a29k_enable_all(); \
643  }while(0);
644
645/* end of ISR handler macros */
646
647/* Context handler macros */
648
649extern void _CPU_Context_save(
650  Context_Control *new_context
651);
652
653/*
654 *  Initialize the context to a state suitable for starting a
655 *  task after a context restore operation.  Generally, this
656 *  involves:
657 *
658 *     - setting a starting address
659 *     - preparing the stack
660 *     - preparing the stack and frame pointers
661 *     - setting the proper interrupt level in the context
662 *     - initializing the floating point context
663 *
664 *  This routine generally does not set any unnecessary register
665 *  in the context.  The state of the "general data" registers is
666 *  undefined at task start time.
667 *
668 *  NOTE: This is_fp parameter is TRUE if the thread is to be a floating
669 *        point thread.  This is typically only used on CPUs where the
670 *        FPU may be easily disabled by software such as on the SPARC
671 *        where the PSR contains an enable FPU bit.
672 */
673
674#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
675                                 _isr, _entry_point, _is_fp ) \
676  do{ /* allocate 1/4 of stack for memory stack, 3/4 of stack for register stack */           \
677      unsigned32 _mem_stack_tmp = (unsigned32)(_stack_base) + (_size);  \
678      unsigned32 _reg_stack_tmp = (unsigned32)(_stack_base) + (((_size)*3)/4); \
679      _mem_stack_tmp &= ~(CPU_ALIGNMENT-1);                         \
680      _reg_stack_tmp &= ~(CPU_ALIGNMENT-1);                         \
681      _CPU_Context_save(_the_context);                              \
682      (_the_context)->msp = _mem_stack_tmp;           /* gr125 */   \
683      (_the_context)->lr1 =                                         \
684      (_the_context)->locals[1] =                                   \
685      (_the_context)->rfb = _reg_stack_tmp;           /* gr127 */   \
686      (_the_context)->gr1 = _reg_stack_tmp - 4 * 4;                 \
687      (_the_context)->rab = _reg_stack_tmp - 128 * 4; /* gr126 */   \
688      (_the_context)->local_count = 1-1;                            \
689      (_the_context)->PC1 = _entry_point;                           \
690      (_the_context)->PC0 = (unsigned32)((char *)_entry_point + 4); \
691      if (_isr) { (_the_context)->OPS |= (TD | DI); }               \
692      else                                                          \
693                { (_the_context)->OPS &= ~(TD | DI); }              \
694  }while(0)
695
696/*
697 *  This routine is responsible for somehow restarting the currently
698 *  executing task.  If you are lucky, then all that is necessary
699 *  is restoring the context.  Otherwise, there will need to be
700 *  a special assembly routine which does something special in this
701 *  case.  Context_Restore should work most of the time.  It will
702 *  not work if restarting self conflicts with the stack frame
703 *  assumptions of restoring a context.
704 */
705
706#define _CPU_Context_Restart_self( _the_context ) \
707   _CPU_Context_restore( (_the_context) )
708
709/*
710 *  The purpose of this macro is to allow the initial pointer into
711 *  a floating point context area (used to save the floating point
712 *  context) to be at an arbitrary place in the floating point
713 *  context area.
714 *
715 *  This is necessary because some FP units are designed to have
716 *  their context saved as a stack which grows into lower addresses.
717 *  Other FP units can be saved by simply moving registers into offsets
718 *  from the base of the context area.  Finally some FP units provide
719 *  a "dump context" instruction which could fill in from high to low
720 *  or low to high based on the whim of the CPU designers.
721 */
722
723#define _CPU_Context_Fp_start( _base, _offset ) \
724   ( (char *) (_base) + (_offset) )
725
726/*
727 *  This routine initializes the FP context area passed to it to.
728 *  There are a few standard ways in which to initialize the
729 *  floating point context.  The code included for this macro assumes
730 *  that this is a CPU in which a "initial" FP context was saved into
731 *  _CPU_Null_fp_context and it simply copies it to the destination
732 *  context passed to it.
733 *
734 *  Other models include (1) not doing anything, and (2) putting
735 *  a "null FP status word" in the correct place in the FP context.
736 */
737
738#define _CPU_Context_Initialize_fp( _destination ) \
739  do { \
740   *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \
741  } while(0)
742
743/* end of Context handler macros */
744
745/* Fatal Error manager macros */
746
747/*
748 *  This routine copies _error into a known place -- typically a stack
749 *  location or a register, optionally disables interrupts, and
750 *  halts/stops the CPU.
751 */
752
753#define _CPU_Fatal_halt( _error ) \
754        a29k_fatal_error(_error)
755
756/* end of Fatal Error manager macros */
757
758/* Bitfield handler macros */
759
760/*
761 *  This routine sets _output to the bit number of the first bit
762 *  set in _value.  _value is of CPU dependent type Priority_Bit_map_control.
763 *  This type may be either 16 or 32 bits wide although only the 16
764 *  least significant bits will be used.
765 *
766 *  There are a number of variables in using a "find first bit" type
767 *  instruction.
768 *
769 *    (1) What happens when run on a value of zero?
770 *    (2) Bits may be numbered from MSB to LSB or vice-versa.
771 *    (3) The numbering may be zero or one based.
772 *    (4) The "find first bit" instruction may search from MSB or LSB.
773 *
774 *  RTEMS guarantees that (1) will never happen so it is not a concern.
775 *  (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
776 *  _CPU_Priority_bits_index().  These three form a set of routines
777 *  which must logically operate together.  Bits in the _value are
778 *  set and cleared based on masks built by _CPU_Priority_mask().
779 *  The basic major and minor values calculated by _Priority_Major()
780 *  and _Priority_Minor() are "massaged" by _CPU_Priority_bits_index()
781 *  to properly range between the values returned by the "find first bit"
782 *  instruction.  This makes it possible for _Priority_Get_highest() to
783 *  calculate the major and directly index into the minor table.
784 *  This mapping is necessary to ensure that 0 (a high priority major/minor)
785 *  is the first bit found.
786 *
787 *  This entire "find first bit" and mapping process depends heavily
788 *  on the manner in which a priority is broken into a major and minor
789 *  components with the major being the 4 MSB of a priority and minor
790 *  the 4 LSB.  Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
791 *  priority.  And (15 << 4) + 14 corresponds to priority 254 -- the next
792 *  to the lowest priority.
793 *
794 *  If your CPU does not have a "find first bit" instruction, then
795 *  there are ways to make do without it.  Here are a handful of ways
796 *  to implement this in software:
797 *
798 *    - a series of 16 bit test instructions
799 *    - a "binary search using if's"
800 *    - _number = 0
801 *      if _value > 0x00ff
802 *        _value >>=8
803 *        _number = 8;
804 *
805 *      if _value > 0x0000f
806 *        _value >=8
807 *        _number += 4
808 *
809 *      _number += bit_set_table[ _value ]
810 *
811 *    where bit_set_table[ 16 ] has values which indicate the first
812 *      bit set
813 */
814
815#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
816#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
817
818#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
819
820#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
821  { \
822    (_output) = 0;   /* do something to prevent warnings */ \
823  }
824
825#endif
826
827/* end of Bitfield handler macros */
828
829/*
830 *  This routine builds the mask which corresponds to the bit fields
831 *  as searched by _CPU_Bitfield_Find_first_bit().  See the discussion
832 *  for that routine.
833 */
834
835#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
836
837#define _CPU_Priority_Mask( _bit_number ) \
838  ( 1 << (_bit_number) )
839
840#endif
841
842/*
843 *  This routine translates the bit numbers returned by
844 *  _CPU_Bitfield_Find_first_bit() into something suitable for use as
845 *  a major or minor component of a priority.  See the discussion
846 *  for that routine.
847 */
848
849#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
850
851#define _CPU_Priority_bits_index( _priority ) \
852  (_priority)
853
854#endif
855
856/* end of Priority handler macros */
857
858/* functions */
859
860/*
861 *  _CPU_Initialize
862 *
863 *  This routine performs CPU dependent initialization.
864 */
865
866void _CPU_Initialize(
867  rtems_cpu_table  *cpu_table,
868  void      (*thread_dispatch)()
869);
870
871/*
872 *  _CPU_ISR_install_raw_handler
873 *
874 *  This routine installs a "raw" interrupt handler directly into the
875 *  processor's vector table.
876 */
877 
878void _CPU_ISR_install_raw_handler(
879  unsigned32  vector,
880  proc_ptr    new_handler,
881  proc_ptr   *old_handler
882);
883
884/*
885 *  _CPU_ISR_install_vector
886 *
887 *  This routine installs an interrupt vector.
888 */
889
890void _CPU_ISR_install_vector(
891  unsigned32  vector,
892  proc_ptr    new_handler,
893  proc_ptr   *old_handler
894);
895
896/*
897 *  _CPU_Install_interrupt_stack
898 *
899 *  This routine installs the hardware interrupt stack pointer.
900 *
901 *  NOTE:  It need only be provided if CPU_HAS_HARDWARE_INTERRUPT_STACK
902 *         is TRUE.
903 */
904
905void _CPU_Install_interrupt_stack( void );
906
907/*
908 *  _CPU_Internal_threads_Idle_thread_body
909 *
910 *  This routine is the CPU dependent IDLE thread body.
911 *
912 *  NOTE:  It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY
913 *         is TRUE.
914 */
915
916void _CPU_Internal_threads_Idle_thread_body( void );
917
918/*
919 *  _CPU_Context_switch
920 *
921 *  This routine switches from the run context to the heir context.
922 */
923
924void _CPU_Context_switch(
925  Context_Control  *run,
926  Context_Control  *heir
927);
928
929/*
930 *  _CPU_Context_restore
931 *
932 *  This routine is generally used only to restart self in an
933 *  efficient manner.  It may simply be a label in _CPU_Context_switch.
934 *
935 *  NOTE: May be unnecessary to reload some registers.
936 */
937
938void _CPU_Context_restore(
939  Context_Control *new_context
940);
941
942/*
943 *  _CPU_Context_save_fp
944 *
945 *  This routine saves the floating point context passed to it.
946 */
947
948void _CPU_Context_save_fp(
949  void **fp_context_ptr
950);
951
952/*
953 *  _CPU_Context_restore_fp
954 *
955 *  This routine restores the floating point context passed to it.
956 */
957
958void _CPU_Context_restore_fp(
959  void **fp_context_ptr
960);
961
962/*  The following routine swaps the endian format of an unsigned int.
963 *  It must be static because it is referenced indirectly.
964 *
965 *  This version will work on any processor, but if there is a better
966 *  way for your CPU PLEASE use it.  The most common way to do this is to:
967 *
968 *     swap least significant two bytes with 16-bit rotate
969 *     swap upper and lower 16-bits
970 *     swap most significant two bytes with 16-bit rotate
971 *
972 *  Some CPUs have special instructions which swap a 32-bit quantity in
973 *  a single instruction (e.g. i486).  It is probably best to avoid
974 *  an "endian swapping control bit" in the CPU.  One good reason is
975 *  that interrupts would probably have to be disabled to insure that
976 *  an interrupt does not try to access the same "chunk" with the wrong
977 *  endian.  Another good reason is that on some CPUs, the endian bit
978 *  endianness for ALL fetches -- both code and data -- so the code
979 *  will be fetched incorrectly.
980 */
981 
982#define CPU_swap_u32( value ) \
983  ((value&0xff) << 24) | (((value >> 8)&0xff) << 16) | \
984    (((value >> 16)&0xff) << 8) | ((value>>24)&0xff)
985
986#define CPU_swap_u16( value ) \
987  (((value&0xff) << 8) | ((value >> 8)&0xff))
988
989#ifdef __cplusplus
990}
991#endif
992
993#endif
Note: See TracBrowser for help on using the repository browser.