source: rtems/cpukit/score/cpu/hppa1.1/cpu.c @ 3652ad35

4.104.114.84.95
Last change on this file since 3652ad35 was 3652ad35, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 19, 1995 at 2:53:29 PM

Minor bug fixes to get all targets compilable and running. The
single biggest changes were the expansion of the workspace size
macro to include other types of objects and the increase in the
minimum stack size for most CPUs.

  • Property mode set to 100644
File size: 8.0 KB
Line 
1/*
2 *  HP PA-RISC Dependent Source
3 *
4 *  COPYRIGHT (c) 1994 by Division Incorporated
5 *
6 *  To anyone who acknowledges that this file is provided "AS IS"
7 *  without any express or implied warranty:
8 *      permission to use, copy, modify, and distribute this file
9 *      for any purpose is hereby granted without fee, provided that
10 *      the above copyright notice and this notice appears in all
11 *      copies, and that the name of Division Incorporated not be
12 *      used in advertising or publicity pertaining to distribution
13 *      of the software without specific, written prior permission.
14 *      Division Incorporated makes no representations about the
15 *      suitability of this software for any purpose.
16 *
17 *  $Id$
18 */
19
20#include <rtems/system.h>
21#include <rtems/fatal.h>
22#include <rtems/core/isr.h>
23#include <rtems/core/wkspace.h>
24
25void hppa_external_interrupt_initialize(void);
26void hppa_external_interrupt_enable(unsigned32);
27void hppa_external_interrupt_disable(unsigned32);
28void hppa_external_interrupt(unsigned32, CPU_Interrupt_frame *);
29
30/*
31 * Our interrupt handlers take a 2nd argument:
32 *   a pointer to a CPU_Interrupt_frame
33 * So we use our own prototype instead of rtems_isr_entry
34 */
35
36typedef void ( *hppa_rtems_isr_entry )(
37    ISR_Vector_number,
38    CPU_Interrupt_frame *
39 );
40
41
42/*
43 * who are we?  cpu number
44 * Not used by executive proper, just kept (or not) as a convenience
45 * for libcpu and libbsp stuff that wants it.
46 *
47 * Defaults to 0.  If the BSP doesn't like it, it can change it.
48 */
49
50int cpu_number;                 /* from 0; cpu number in a multi cpu system */
51
52
53/*  _CPU_Initialize
54 *
55 *  This routine performs processor dependent initialization.
56 *
57 *  INPUT PARAMETERS:
58 *    cpu_table       - CPU table to initialize
59 *    thread_dispatch - address of disptaching routine
60 *
61 */
62
63void _CPU_Initialize(
64  rtems_cpu_table  *cpu_table,
65  void      (*thread_dispatch)      /* ignored on this CPU */
66)
67{
68    register unsigned8  *fp_context;
69    unsigned32 iva;
70    unsigned32 iva_table;
71    int i;
72
73    extern void IVA_Table(void);
74
75    /*
76     * XXX; need to setup fpsr smarter perhaps
77     */
78
79    fp_context = (unsigned8*) &_CPU_Null_fp_context;
80    for (i=0 ; i<sizeof(Context_Control_fp); i++)
81        *fp_context++ = 0;
82
83    /*
84     *  Set _CPU_Default_gr27 here so it will hopefully be the correct
85     *  global data pointer for the entire system.
86     */
87
88    asm volatile( "stw   %%r27,%0" : "=m" (_CPU_Default_gr27): );
89
90    /*
91     * Stabilize the interrupt stuff
92     */
93
94    (void) hppa_external_interrupt_initialize();
95
96    /*
97     * Set the IVA to point to physical address of the IVA_Table
98     */
99
100    iva_table = (unsigned32) IVA_Table;
101    HPPA_ASM_LPA(0, iva_table, iva);
102    set_iva(iva);
103
104    _CPU_Table = *cpu_table;
105}
106
107/*PAGE
108 *
109 *  _CPU_ISR_install_raw_handler
110 */
111 
112void _CPU_ISR_install_raw_handler(
113  unsigned32  vector,
114  proc_ptr    new_handler,
115  proc_ptr   *old_handler
116)
117{
118  /*
119   *  This is unsupported.
120   */
121
122  _CPU_Fatal_halt( 0xdeaddead );
123}
124
125/*PAGE
126 *
127 *  _CPU_ISR_install_vector
128 *
129 *  This kernel routine installs the RTEMS handler for the
130 *  specified vector.
131 *
132 *  Input parameters:
133 *    vector      - interrupt vector number
134 *    old_handler - former ISR for this vector number
135 *    new_handler - replacement ISR for this vector number
136 *
137 *  Output parameters:  NONE
138 *
139 */
140
141/*
142 * HPPA has 8w for each vector instead of an address to jump to.
143 * We put the actual ISR address in '_ISR_vector_table'.  This will
144 * be pulled by the code in the vector.
145 */
146
147void _CPU_ISR_install_vector(
148  unsigned32  vector,
149  proc_ptr    new_handler,
150  proc_ptr   *old_handler
151)
152{
153    *old_handler = _ISR_Vector_table[vector];
154
155    _ISR_Vector_table[vector] = new_handler;
156
157    if (vector >= HPPA_INTERRUPT_EXTERNAL_BASE)
158    {
159        unsigned32 external_vector;
160
161        external_vector = vector - HPPA_INTERRUPT_EXTERNAL_BASE;
162        if (new_handler)
163            hppa_external_interrupt_enable(external_vector);
164        else
165            /* XXX this can never happen due to _ISR_Is_valid_user_handler */
166            hppa_external_interrupt_disable(external_vector);
167    }
168}
169
170
171/*
172 * Support for external and spurious interrupts on HPPA
173 *
174 *  TODO:
175 *    delete interrupt.c etc.
176 *    Count interrupts
177 *    make sure interrupts disabled properly
178 *    should handler check again for more interrupts before exit?
179 *    How to enable interrupts from an interrupt handler?
180 *    Make sure there is an entry for everything in ISR_Vector_Table
181 */
182
183#define DISMISS(mask)           set_eirr(mask)
184#define DISABLE(mask)           set_eiem(get_eiem() & ~(mask))
185#define ENABLE(mask)            set_eiem(get_eiem() | (mask))
186#define VECTOR_TO_MASK(v)       (1 << (31 - (v)))
187
188/*
189 * Init the external interrupt scheme
190 * called by bsp_start()
191 */
192
193void
194hppa_external_interrupt_initialize(void)
195{
196    hppa_rtems_isr_entry ignore = 0;
197
198    /* mark them all unused */
199
200    DISABLE(~0);
201    DISMISS(~0);
202
203    /* install the external interrupt handler */
204  _CPU_ISR_install_vector(
205    HPPA_INTERRUPT_EXTERNAL_INTERRUPT,
206    (proc_ptr)hppa_external_interrupt,
207    (proc_ptr *)ignore
208  );
209}
210
211/*
212 * Enable a specific external interrupt
213 */
214
215void
216hppa_external_interrupt_enable(unsigned32 v)
217{
218    unsigned32 isrlevel;
219
220    _CPU_ISR_Disable(isrlevel);
221    ENABLE(VECTOR_TO_MASK(v));
222    _CPU_ISR_Enable(isrlevel);
223}
224
225/*
226 * Does not clear or otherwise affect any pending requests
227 */
228
229void
230hppa_external_interrupt_disable(unsigned32 v)
231{
232    unsigned32 isrlevel;
233
234    _CPU_ISR_Disable(isrlevel);
235    DISABLE(VECTOR_TO_MASK(v));
236    _CPU_ISR_Enable(isrlevel);
237}
238
239void
240hppa_external_interrupt_spurious_handler(unsigned32           vector,
241                                         CPU_Interrupt_frame *iframe)
242{
243/* XXX should not be printing :)
244    printf("spurious external interrupt: %d at pc 0x%x; disabling\n",
245       vector, iframe->Interrupt.pcoqfront);
246*/
247    DISMISS(VECTOR_TO_MASK(vector));
248    DISABLE(VECTOR_TO_MASK(vector));
249}
250
251void
252hppa_external_interrupt_report_spurious(unsigned32           spurious,
253                                        CPU_Interrupt_frame *iframe)
254{
255    int v;
256    for (v=0; v < HPPA_EXTERNAL_INTERRUPTS; v++)
257        if (VECTOR_TO_MASK(v) & spurious)
258            hppa_external_interrupt_spurious_handler(v, iframe);
259    DISMISS(spurious);
260}
261
262
263/*
264 * External interrupt handler.
265 * This is installed as cpu interrupt handler for
266 * HPPA_INTERRUPT_EXTERNAL_INTERRUPT. It vectors out to
267 * specific external interrupt handlers.
268 */
269
270void
271hppa_external_interrupt(unsigned32           vector,
272                        CPU_Interrupt_frame *iframe)
273{
274    unsigned32   mask;
275    unsigned32  *vp, *max_vp;
276    unsigned32   external_vector;
277    unsigned32   global_vector;
278    hppa_rtems_isr_entry handler;
279
280    max_vp = &_CPU_Table.external_interrupt[_CPU_Table.external_interrupts];
281    while ( (mask = (get_eirr() & get_eiem())) )
282    {
283        for (vp = _CPU_Table.external_interrupt; (vp < max_vp) && mask; vp++)
284        {
285            unsigned32 m;
286
287            external_vector = *vp;
288            global_vector = external_vector + HPPA_INTERRUPT_EXTERNAL_BASE;
289            m = VECTOR_TO_MASK(external_vector);
290            handler = (hppa_rtems_isr_entry) _ISR_Vector_table[global_vector];
291            if ((m & mask) && handler)
292            {
293                DISMISS(m);
294                mask &= ~m;
295                (*handler)(global_vector, iframe);
296            }
297        }
298
299        if (mask != 0) {
300            if ( _CPU_Table.spurious_handler )
301              (*((hppa_rtems_isr_entry) _CPU_Table.spurious_handler))(
302                  mask,
303                  iframe
304                );
305            else
306              hppa_external_interrupt_report_spurious(mask, iframe);
307        }
308    }
309}
310
311/*
312 * Halt the system.
313 * Called by the _CPU_Fatal_halt macro
314 *
315 * XXX
316 * Later on, this will allow us to return to the prom.
317 * For now, we just ignore 'type_of_halt'
318 */
319
320void
321hppa_cpu_halt(unsigned32 type_of_halt,
322              unsigned32 the_error)
323{
324    unsigned32 isrlevel;
325
326    _CPU_ISR_Disable(isrlevel);
327
328    asm volatile( "copy %0,%%r1" : : "r" (the_error) );
329    HPPA_ASM_BREAK(1, 0);
330}
Note: See TracBrowser for help on using the repository browser.