source: rtems/c/src/exec/score/cpu/hppa1.1/rtems/score/cpu.h @ 17508d02

4.104.114.84.95
Last change on this file since 17508d02 was 17508d02, checked in by Joel Sherrill <joel.sherrill@…>, on 07/26/00 at 19:26:28

Port of RTEMS to the Texas Instruments C3x/C4x DSP families including
a BSP (c4xsim) supporting the simulator included with gdb. This port
was done by Joel Sherrill and Jennifer Averett of OAR Corporation.
Also included with this port is a space/time optimization to eliminate
FP context switch management on CPUs without hardware or software FP.

An issue with this port was that sizeof(unsigned32) = sizeof(unsigned8)
on this CPU. This required addressing alignment checks and assumptions
as well as fixing code that assumed sizeof(unsigned32) == 4.

  • Property mode set to 100644
File size: 18.3 KB
Line 
1/*  cpu.h
2 *
3 *  This include file contains information pertaining to the HP
4 *  PA-RISC processor (Level 1.1).
5 *
6 *  COPYRIGHT (c) 1994 by Division Incorporated
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.OARcorp.com/rtems/license.html.
11 *
12 * Note:
13 *      This file is included by both C and assembler code ( -DASM )
14 *
15 *  $Id$
16 */
17
18#ifndef __CPU_h
19#define __CPU_h
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24
25#include <rtems/score/hppa.h>              /* pick up machine definitions */
26#ifndef ASM
27#include <rtems/score/hppatypes.h>
28#endif
29
30/* conditional compilation parameters */
31
32#define CPU_INLINE_ENABLE_DISPATCH       FALSE
33#define CPU_UNROLL_ENQUEUE_PRIORITY      TRUE
34
35/*
36 *  RTEMS manages an interrupt stack in software for the HPPA.
37 */
38
39#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE
40#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
41#define CPU_ALLOCATE_INTERRUPT_STACK     TRUE
42
43/*
44 *  Does the RTEMS invoke the user's ISR with the vector number and
45 *  a pointer to the saved interrupt frame (1) or just the vector
46 *  number (0)?
47 */
48
49#define CPU_ISR_PASSES_FRAME_POINTER 0
50
51/*
52 *  HPPA has hardware FP, it is assumed to exist by GCC so all tasks
53 *  may implicitly use it (especially for integer multiplies).  Because
54 *  the FP context is technically part of the basic integer context
55 *  on this CPU, we cannot use the deferred FP context switch algorithm.
56 */
57
58#define CPU_HARDWARE_FP                  TRUE
59#define CPU_SOFTWARE_FP                  FALSE
60#define CPU_ALL_TASKS_ARE_FP             TRUE
61#define CPU_IDLE_TASK_IS_FP              FALSE
62#define CPU_USE_DEFERRED_FP_SWITCH       FALSE
63
64#define CPU_PROVIDES_IDLE_THREAD_BODY    FALSE
65#define CPU_STACK_GROWS_UP               TRUE
66#define CPU_STRUCTURE_ALIGNMENT          __attribute__ ((__aligned__ (32)))
67
68/*
69 *  Define what is required to specify how the network to host conversion
70 *  routines are handled.
71 */
72
73#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES     FALSE
74#define CPU_BIG_ENDIAN                           TRUE
75#define CPU_LITTLE_ENDIAN                        FALSE
76
77/* constants */
78
79#define CPU_MODES_INTERRUPT_LEVEL  0x00000001 /* interrupt level in mode */
80#define CPU_MODES_INTERRUPT_MASK   0x00000001 /* interrupt level in mode */
81
82/*
83 * PSW contstants
84 */
85
86#define CPU_PSW_BASE (HPPA_PSW_C | HPPA_PSW_Q | HPPA_PSW_P | HPPA_PSW_D)
87#define CPU_PSW_INTERRUPTS_ON    (CPU_PSW_BASE | HPPA_PSW_I)
88#define CPU_PSW_INTERRUPTS_OFF   (CPU_PSW_BASE)
89
90#define CPU_PSW_DEFAULT     CPU_PSW_BASE
91
92
93#ifndef ASM
94
95/*
96 * Contexts
97 *
98 *  This means we have the following context items:
99 *    1. task level context stuff::  Context_Control
100 *    2. floating point task stuff:: Context_Control_fp
101 *
102 *  The PA-RISC is very fast so the expense of saving an extra register
103 *  or two is not of great concern at the present.  So we are not making
104 *  a distinction between what is saved during a task switch and what is
105 *  saved at each interrupt.  Plus saving the entire context should make
106 *  it easier to make gdb aware of RTEMS tasks.
107 */
108
109typedef struct {
110    unsigned32 flags;      /* whatever */
111    unsigned32 gr1;        /* scratch -- caller saves */
112    unsigned32 gr2;        /* RP -- return pointer */
113    unsigned32 gr3;        /* scratch -- callee saves */
114    unsigned32 gr4;        /* scratch -- callee saves */
115    unsigned32 gr5;        /* scratch -- callee saves */
116    unsigned32 gr6;        /* scratch -- callee saves */
117    unsigned32 gr7;        /* scratch -- callee saves */
118    unsigned32 gr8;        /* scratch -- callee saves */
119    unsigned32 gr9;        /* scratch -- callee saves */
120    unsigned32 gr10;       /* scratch -- callee saves */
121    unsigned32 gr11;       /* scratch -- callee saves */
122    unsigned32 gr12;       /* scratch -- callee saves */
123    unsigned32 gr13;       /* scratch -- callee saves */
124    unsigned32 gr14;       /* scratch -- callee saves */
125    unsigned32 gr15;       /* scratch -- callee saves */
126    unsigned32 gr16;       /* scratch -- callee saves */
127    unsigned32 gr17;       /* scratch -- callee saves */
128    unsigned32 gr18;       /* scratch -- callee saves */
129    unsigned32 gr19;       /* scratch -- caller saves */
130    unsigned32 gr20;       /* scratch -- caller saves */
131    unsigned32 gr21;       /* scratch -- caller saves */
132    unsigned32 gr22;       /* scratch -- caller saves */
133    unsigned32 gr23;       /* argument 3 */
134    unsigned32 gr24;       /* argument 2 */
135    unsigned32 gr25;       /* argument 1 */
136    unsigned32 gr26;       /* argument 0 */
137    unsigned32 gr27;       /* DP -- global data pointer */
138    unsigned32 gr28;       /* return values -- caller saves */
139    unsigned32 gr29;       /* return values -- caller saves */
140    unsigned32 sp;         /* gr30 */
141    unsigned32 gr31;
142
143    /* Various control registers */
144
145    unsigned32 sar;         /* cr11 */
146    unsigned32 ipsw;        /* cr22; full 32 bits of psw */
147    unsigned32 iir;         /* cr19; interrupt instruction register */
148    unsigned32 ior;         /* cr21; interrupt offset register */
149    unsigned32 isr;         /* cr20; interrupt space register (not used) */
150    unsigned32 pcoqfront;   /* cr18; front que offset */
151    unsigned32 pcoqback;    /* cr18; back que offset */
152    unsigned32 pcsqfront;   /* cr17; front que space (not used) */
153    unsigned32 pcsqback;    /* cr17; back que space (not used) */
154    unsigned32 itimer;      /* cr16; itimer value */
155
156} Context_Control;
157
158
159/* Must be double word aligned.
160 * This will be ok since our allocator returns 8 byte aligned chunks
161 */
162
163typedef struct {
164    double      fr0;        /* status */
165    double      fr1;        /* exception information */
166    double      fr2;        /* exception information */
167    double      fr3;        /* exception information */
168    double      fr4;        /* argument */
169    double      fr5;        /* argument */
170    double      fr6;        /* argument */
171    double      fr7;        /* argument */
172    double      fr8;        /* scratch -- caller saves */
173    double      fr9;        /* scratch -- caller saves */
174    double      fr10;       /* scratch -- caller saves */
175    double      fr11;       /* scratch -- caller saves */
176    double      fr12;       /* callee saves -- (PA-RISC 1.1 CPUs) */
177    double      fr13;       /* callee saves -- (PA-RISC 1.1 CPUs) */
178    double      fr14;       /* callee saves -- (PA-RISC 1.1 CPUs) */
179    double      fr15;       /* callee saves -- (PA-RISC 1.1 CPUs) */
180    double      fr16;       /* callee saves -- (PA-RISC 1.1 CPUs) */
181    double      fr17;       /* callee saves -- (PA-RISC 1.1 CPUs) */
182    double      fr18;       /* callee saves -- (PA-RISC 1.1 CPUs) */
183    double      fr19;       /* callee saves -- (PA-RISC 1.1 CPUs) */
184    double      fr20;       /* callee saves -- (PA-RISC 1.1 CPUs) */
185    double      fr21;       /* callee saves -- (PA-RISC 1.1 CPUs) */
186    double      fr22;       /* caller saves -- (PA-RISC 1.1 CPUs) */
187    double      fr23;       /* caller saves -- (PA-RISC 1.1 CPUs) */
188    double      fr24;       /* caller saves -- (PA-RISC 1.1 CPUs) */
189    double      fr25;       /* caller saves -- (PA-RISC 1.1 CPUs) */
190    double      fr26;       /* caller saves -- (PA-RISC 1.1 CPUs) */
191    double      fr27;       /* caller saves -- (PA-RISC 1.1 CPUs) */
192    double      fr28;       /* caller saves -- (PA-RISC 1.1 CPUs) */
193    double      fr29;       /* caller saves -- (PA-RISC 1.1 CPUs) */
194    double      fr30;       /* caller saves -- (PA-RISC 1.1 CPUs) */
195    double      fr31;       /* caller saves -- (PA-RISC 1.1 CPUs) */
196} Context_Control_fp;
197
198/*
199 *  The following structure defines the set of information saved
200 *  on the current stack by RTEMS upon receipt of each interrupt.
201 */
202
203typedef struct {
204  Context_Control             Integer;
205  Context_Control_fp          Floating_Point;
206} CPU_Interrupt_frame;
207
208/*
209 * Our interrupt handlers take a 2nd argument:
210 *   a pointer to a CPU_Interrupt_frame
211 * So we use our own prototype instead of rtems_isr_entry
212 */
213
214typedef void ( *hppa_rtems_isr_entry )(
215    unsigned32,
216    CPU_Interrupt_frame *
217 );
218
219/*
220 * The following table contains the information required to configure
221 * the HPPA specific parameters.
222 */
223
224typedef struct {
225  void       (*pretasking_hook)( void );
226  void       (*predriver_hook)( void );
227  void       (*postdriver_hook)( void );
228  void       (*idle_task)( void );
229  boolean      do_zero_of_workspace;
230  unsigned32   idle_task_stack_size;
231  unsigned32   interrupt_stack_size;
232  unsigned32   extra_mpci_receive_server_stack;
233  void *     (*stack_allocate_hook)( unsigned32 );
234  void       (*stack_free_hook)( void * );
235  /* end of fields required on all CPUs */
236
237  hppa_rtems_isr_entry spurious_handler;
238
239  unsigned32   itimer_clicks_per_microsecond; /* for use by Clock driver */
240}   rtems_cpu_table;
241
242/*
243 *  Macros to access required entires in the CPU Table are in
244 *  the file rtems/system.h.
245 */
246
247/*
248 *  Macros to access HPPA specific additions to the CPU Table
249 */
250
251#define rtems_cpu_configuration_get_spurious_handler() \
252   (_CPU_Table.spurious_handler)
253
254#define rtems_cpu_configuration_get_itimer_clicks_per_microsecond() \
255   (_CPU_Table.itimer_clicks_per_microsecond)
256
257/* variables */
258
259SCORE_EXTERN Context_Control_fp  _CPU_Null_fp_context;
260SCORE_EXTERN unsigned32          _CPU_Default_gr27;
261SCORE_EXTERN void               *_CPU_Interrupt_stack_low;
262SCORE_EXTERN void               *_CPU_Interrupt_stack_high;
263
264#endif          /* ! ASM */
265
266/*
267 *  context sizes
268 */
269
270#ifndef ASM
271#define CPU_CONTEXT_SIZE     sizeof( Context_Control )
272#define CPU_CONTEXT_FP_SIZE  sizeof( Context_Control_fp )
273#endif
274
275/*
276 *  size of a frame on the stack
277 */
278
279#define CPU_FRAME_SIZE (16 * 4)
280
281/*
282 * (Optional) # of bytes for libmisc/stackchk to check
283 * If not specifed, then it defaults to something reasonable
284 * for most architectures.
285 */
286
287#define CPU_STACK_CHECK_SIZE    (CPU_FRAME_SIZE * 2)
288
289/*
290 *  extra stack required by the MPCI receive server thread
291 */
292
293#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
294
295/*
296 * HPPA has 32 traps, then 32 external interrupts
297 * Rtems (_ISR_Vector_Table) is aware ONLY of the first 32
298 * The BSP is aware of the external interrupts and possibly more.
299 *
300 */
301
302#define CPU_INTERRUPT_NUMBER_OF_VECTORS      (HPPA_INTERNAL_TRAPS)
303#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER  (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
304
305/*
306 * Don't be chintzy here; we don't want to debug these problems
307 * Some of the tests eat almost 4k.
308 * Plus, the HPPA always allocates chunks of 64 bytes for stack
309 *       growth.
310 */
311
312#define CPU_STACK_MINIMUM_SIZE          (8 * 1024)
313
314/*
315 * HPPA double's must be on 8 byte boundary
316 */
317
318#define CPU_ALIGNMENT              8
319
320/*
321 * just follow the basic HPPA alignment for the heap and partition
322 */
323
324#define CPU_HEAP_ALIGNMENT         CPU_ALIGNMENT
325#define CPU_PARTITION_ALIGNMENT    CPU_ALIGNMENT
326
327/*
328 * HPPA stack is best when 64 byte aligned.
329 */
330
331#define CPU_STACK_ALIGNMENT        64
332
333#ifndef ASM
334
335/* macros */
336
337/*
338 *  ISR handler macros
339 *
340 *  These macros perform the following functions:
341 *     + disable all maskable CPU interrupts
342 *     + restore previous interrupt level (enable)
343 *     + temporarily restore interrupts (flash)
344 *     + set a particular level
345 */
346
347/* Disable interrupts; returning previous psw bits in _isr_level */
348#define _CPU_ISR_Disable( _isr_level ) \
349  do { \
350         HPPA_ASM_RSM(HPPA_PSW_I, _isr_level);         \
351         if (_isr_level & HPPA_PSW_I) _isr_level = 0;  \
352         else                          _isr_level = 1; \
353  } while(0)
354
355/* Enable interrupts to previous level from _CPU_ISR_Disable
356 * does not change 'level' */
357#define _CPU_ISR_Enable( _isr_level )  \
358  { \
359        register int _ignore; \
360        if (_isr_level == 0) HPPA_ASM_SSM(HPPA_PSW_I, _ignore); \
361        else                 HPPA_ASM_RSM(HPPA_PSW_I, _ignore); \
362  }
363
364/* restore, then disable interrupts; does not change level */
365#define _CPU_ISR_Flash( _isr_level ) \
366  { \
367        if (_isr_level == 0) \
368        { \
369              register int _ignore;  \
370              HPPA_ASM_SSM(HPPA_PSW_I, _ignore); \
371              HPPA_ASM_RSM(HPPA_PSW_I, _ignore); \
372        } \
373  }
374
375/*
376 * Interrupt task levels
377 *
378 * Future scheme proposal
379 *      level will be an index into a array.
380 *      Each entry of array will be the interrupt bits
381 *        enabled for that level.  There will be 32 bits of external
382 *        interrupts (to be placed in EIEM) and some (optional) bsp
383 *        specific bits
384 *
385 * For pixel flow this *may* mean something like:
386 *      level 0:   all interrupts enabled (external + rhino)
387 *      level 1:   rhino disabled
388 *      level 2:   all io interrupts disabled (timer still enabled)
389 *      level 7:   *ALL* disabled (timer disabled)
390 */
391
392/* set interrupts on or off; does not return new level */
393#define _CPU_ISR_Set_level( new_level ) \
394  { \
395        volatile int ignore; \
396        if ( new_level )  HPPA_ASM_RSM(HPPA_PSW_I, ignore); \
397        else              HPPA_ASM_SSM(HPPA_PSW_I, ignore); \
398  }
399
400/* return current level */
401unsigned32 _CPU_ISR_Get_level( void );
402
403/* end of ISR handler macros */
404
405/*
406 *  Context handler macros
407 *
408 *  These macros perform the following functions:
409 *     + initialize a context area
410 *     + restart the current thread
411 *     + calculate the initial pointer into a FP context area
412 *     + initialize an FP context area
413 *
414 *  HPPA port adds two macros which hide the "indirectness" of the
415 *  pointer passed the save/restore FP context assembly routines.
416 */
417
418#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
419                                  _new_level, _entry_point, _is_fp ) \
420  do { \
421    unsigned32 _stack; \
422    \
423    (_the_context)->flags = 0xfeedf00d; \
424    (_the_context)->pcoqfront = (unsigned32)(_entry_point); \
425    (_the_context)->pcoqback  = (unsigned32)(_entry_point) + 4; \
426    (_the_context)->pcsqfront = 0; \
427    (_the_context)->pcsqback  = 0; \
428    if ( (_new_level) ) \
429        (_the_context)->ipsw = CPU_PSW_INTERRUPTS_OFF; \
430    else \
431        (_the_context)->ipsw = CPU_PSW_INTERRUPTS_ON; \
432    \
433    _stack = ((unsigned32)(_stack_base) + (CPU_STACK_ALIGNMENT - 1)); \
434    _stack &= ~(CPU_STACK_ALIGNMENT - 1); \
435    if ((_stack - (unsigned32) (_stack_base)) < CPU_FRAME_SIZE) \
436       _stack += CPU_FRAME_SIZE; \
437    \
438    (_the_context)->sp = (_stack); \
439    (_the_context)->gr27 = _CPU_Default_gr27; \
440  } while (0)
441
442#define _CPU_Context_Restart_self( _the_context ) \
443    do { \
444         _CPU_Context_restore( (_the_context) ); \
445    } while (0)
446
447#define _CPU_Context_Fp_start( _base, _offset ) \
448   ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
449
450#define _CPU_Context_Initialize_fp( _destination ) \
451  do { \
452    *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context;\
453  } while(0)
454
455#define _CPU_Context_save_fp( _fp_context ) \
456   _CPU_Save_float_context( *(Context_Control_fp **)(_fp_context) )
457
458#define _CPU_Context_restore_fp( _fp_context ) \
459   _CPU_Restore_float_context( *(Context_Control_fp **)(_fp_context) )
460
461/* end of Context handler macros */
462
463/*
464 *  Fatal Error manager macros
465 *
466 *  These macros perform the following functions:
467 *    + disable interrupts and halt the CPU
468 */
469
470void    hppa_cpu_halt(unsigned32 the_error);
471#define _CPU_Fatal_halt( _error ) \
472    hppa_cpu_halt(_error)
473
474/* end of Fatal Error manager macros */
475
476/*
477 *  Bitfield handler macros
478 *
479 *  These macros perform the following functions:
480 *     + scan for the highest numbered (MSB) set in a 16 bit bitfield
481 *
482 *  NOTE:
483 *
484 *  The HPPA does not have a scan instruction.  This functionality
485 *  is implemented in software.
486 */
487
488#define CPU_USE_GENERIC_BITFIELD_CODE FALSE
489#define CPU_USE_GENERIC_BITFIELD_DATA FALSE
490
491int hppa_rtems_ffs(unsigned int value);
492#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
493    _output = hppa_rtems_ffs(_value)
494
495/* end of Bitfield handler macros */
496
497/*
498 *  Priority handler macros
499 *
500 *  These macros perform the following functions:
501 *    + return a mask with the bit for this major/minor portion of
502 *      of thread priority set.
503 *    + translate the bit number returned by "Bitfield_find_first_bit"
504 *      into an index into the thread ready chain bit maps
505 *
506 *  Note: 255 is the lowest priority
507 */
508
509#define _CPU_Priority_Mask( _bit_number ) \
510  ( 1 << (_bit_number) )
511
512#define _CPU_Priority_bits_index( _priority ) \
513  (_priority)
514
515/* end of Priority handler macros */
516
517/* functions */
518
519/*
520 *  _CPU_Initialize
521 *
522 *  This routine performs CPU dependent initialization.
523 */
524
525void _CPU_Initialize(
526  rtems_cpu_table  *cpu_table,
527  void      (*thread_dispatch)
528);
529
530/*
531 *  _CPU_ISR_install_raw_handler
532 *
533 *  This routine installs a "raw" interrupt handler directly into the
534 *  processor's vector table.
535 */
536 
537void _CPU_ISR_install_raw_handler(
538  unsigned32  vector,
539  proc_ptr    new_handler,
540  proc_ptr   *old_handler
541);
542
543/*
544 *  _CPU_ISR_install_vector
545 *
546 *  This routine installs an interrupt vector.
547 */
548
549void _CPU_ISR_install_vector(
550  unsigned32  vector,
551  proc_ptr    new_handler,
552  proc_ptr   *old_handler
553);
554
555/*
556 *  _CPU_Context_switch
557 *
558 *  This routine switches from the run context to the heir context.
559 */
560
561void _CPU_Context_switch(
562  Context_Control  *run,
563  Context_Control  *heir
564);
565
566/*
567 *  _CPU_Context_restore
568 *
569 *  This routine is generally used only to restart self in an
570 *  efficient manner and avoid stack conflicts.
571 */
572
573void _CPU_Context_restore(
574  Context_Control *new_context
575);
576
577/*
578 *  _CPU_Save_float_context
579 *
580 *  This routine saves the floating point context passed to it.
581 *
582 *  NOTE:  _CPU_Context_save_fp is implemented as a macro on the HPPA
583 *         which dereferences the pointer before calling this.
584 */
585
586void _CPU_Save_float_context(
587  Context_Control_fp *fp_context
588);
589
590/*
591 *  _CPU_Restore_float_context
592 *
593 *  This routine restores the floating point context passed to it.
594 *
595 *  NOTE:  _CPU_Context_save_fp is implemented as a macro on the HPPA
596 *         which dereferences the pointer before calling this.
597 */
598
599void _CPU_Restore_float_context(
600  Context_Control_fp *fp_context
601);
602
603
604/*
605 * The raw interrupt handler for external interrupts
606 */
607
608extern void _Generic_ISR_Handler(
609    void
610);
611
612
613/*  The following routine swaps the endian format of an unsigned int.
614 *  It must be static so it can be referenced indirectly.
615 */
616
617static inline unsigned int
618CPU_swap_u32(unsigned32 value)
619{
620  unsigned32 swapped;
621
622  HPPA_ASM_SWAPBYTES(value, swapped);
623
624  return( swapped );
625}
626
627#define CPU_swap_u16( value ) \
628  (((value&0xff) << 8) | ((value >> 8)&0xff))
629
630#endif   /* ! ASM */
631
632#ifdef __cplusplus
633}
634#endif
635
636#endif   /* ! __CPU_h */
Note: See TracBrowser for help on using the repository browser.