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

4.104.114.84.95
Last change on this file since 75f09e5 was 75f09e5, checked in by Joel Sherrill <joel.sherrill@…>, on 02/21/96 at 14:43:34

Dispersal of internal thread handler resulted in IDLE thread becoming
part of the Thread Handler. This required the name of the optional
CPU dependent IDLE thread implementation to change.

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