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

4.104.114.84.95
Last change on this file since ac7d5ef0 was ac7d5ef0, checked in by Joel Sherrill <joel.sherrill@…>, on 05/11/95 at 17:39:37

Initial revision

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