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

4.104.114.84.95
Last change on this file since c64e4ed4 was c64e4ed4, checked in by Joel Sherrill <joel.sherrill@…>, on 01/15/96 at 21:50:28

updates from Tony Bennett for PA and UNIX ports

  • Property mode set to 100644
File size: 9.2 KB
RevLine 
[ac7d5ef0]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 *
[eb5a7e07]17 *  $Id$
[ac7d5ef0]18 */
19
20#include <rtems/system.h>
[ca201c9]21#include <rtems/score/isr.h>
[ac7d5ef0]22
[3a4ae6c]23void hppa_external_interrupt_initialize(void);
[ac7d5ef0]24void hppa_external_interrupt_enable(unsigned32);
25void hppa_external_interrupt_disable(unsigned32);
26void hppa_external_interrupt(unsigned32, CPU_Interrupt_frame *);
[c64e4ed4]27void hppa_cpu_halt(unsigned32);
[ac7d5ef0]28
29/*
[c64e4ed4]30 * The first level interrupt handler for first 32 interrupts/traps.
31 * Indexed by vector; generally each entry is _Generic_ISR_Handler.
32 * Some TLB traps may have their own first level handler.
[ac7d5ef0]33 */
34
[c64e4ed4]35extern void _Generic_ISR_Handler(void);
36unsigned32 HPPA_first_level_interrupt_handler[HPPA_INTERNAL_INTERRUPTS];
[ac7d5ef0]37
38/*  _CPU_Initialize
39 *
40 *  This routine performs processor dependent initialization.
41 *
42 *  INPUT PARAMETERS:
43 *    cpu_table       - CPU table to initialize
44 *    thread_dispatch - address of disptaching routine
45 *
46 */
47
48void _CPU_Initialize(
49  rtems_cpu_table  *cpu_table,
50  void      (*thread_dispatch)      /* ignored on this CPU */
51)
52{
53    register unsigned8  *fp_context;
54    unsigned32 iva;
55    unsigned32 iva_table;
56    int i;
57
58    extern void IVA_Table(void);
59
60    /*
61     * XXX; need to setup fpsr smarter perhaps
62     */
63
64    fp_context = (unsigned8*) &_CPU_Null_fp_context;
65    for (i=0 ; i<sizeof(Context_Control_fp); i++)
66        *fp_context++ = 0;
67
68    /*
69     *  Set _CPU_Default_gr27 here so it will hopefully be the correct
70     *  global data pointer for the entire system.
71     */
72
73    asm volatile( "stw   %%r27,%0" : "=m" (_CPU_Default_gr27): );
74
[c64e4ed4]75    /*
76     * Init the first level interrupt handlers
77     */
78
79    for (i=0; i <= HPPA_INTERNAL_INTERRUPTS; i++)
80        HPPA_first_level_interrupt_handler[i] = (unsigned32) _Generic_ISR_Handler;
81
82    /*
83     * Init the 2nd level interrupt handlers
84     */
85
86    for (i=0; i <= CPU_INTERRUPT_NUMBER_OF_VECTORS; i++)
87        _ISR_Vector_table[i] = (ISR_Handler_entry) hppa_cpu_halt;
88
[ac7d5ef0]89    /*
90     * Stabilize the interrupt stuff
91     */
92
93    (void) hppa_external_interrupt_initialize();
94
95    /*
96     * Set the IVA to point to physical address of the IVA_Table
97     */
98
99    iva_table = (unsigned32) IVA_Table;
[c64e4ed4]100#if defined(hppa1_1)
101    /*
102     * HACK:  (from PA72000 TRM, page 4-19)
103     * "The hardware TLB miss handler will never attempt to service
104     *  a non-access TLB miss or a TLB protection violation.  It
105     *  will only attempt to service TLB accesses that would cause
106     *  Trap Numbers 6 (Instruction TLB miss) and 15 (Data TLB miss)."
107     *
108     * The LPA instruction is used to translate a virtual address to
109     * a physical address, however, if the requested virtual address
110     * is not currently resident in the TLB, the hardware TLB miss
111     * handler will NOT insert it.  In this situation Trap Number
112     * #17 is invoked (Non-access Data TLB miss fault).
113     *
114     * To work around this, a dummy data access is first performed
115     * to the virtual address prior to the LPA.  The dummy access
116     * causes the TLB entry to be inserted (if not already present)
117     * and then the following LPA instruction will not generate
118     * a non-access data TLB miss fault.
119     *
120     * It is unclear whether or not this behaves the same way for
121     * the PA8000.
122     *
123     */
124    iva = *(volatile unsigned32 *)iva_table;  /* dummy access */
125#endif
126
[ac7d5ef0]127    HPPA_ASM_LPA(0, iva_table, iva);
128    set_iva(iva);
129
130    _CPU_Table = *cpu_table;
131}
132
[11290355]133/*PAGE
134 *
135 *  _CPU_ISR_Get_level
136 */
137 
138unsigned32 _CPU_ISR_Get_level(void)
139{
140    int level;
141    HPPA_ASM_SSM(0, level);     /* change no bits; just get copy */
142    if (level & HPPA_PSW_I)
[c64e4ed4]143        return 0;
144    return 1;
[11290355]145}
146
[637df35]147/*PAGE
148 *
149 *  _CPU_ISR_install_raw_handler
150 */
151 
152void _CPU_ISR_install_raw_handler(
153  unsigned32  vector,
154  proc_ptr    new_handler,
155  proc_ptr   *old_handler
156)
157{
158  /*
159   *  This is unsupported.
160   */
161
162  _CPU_Fatal_halt( 0xdeaddead );
163}
164
165/*PAGE
166 *
167 *  _CPU_ISR_install_vector
[ac7d5ef0]168 *
169 *  This kernel routine installs the RTEMS handler for the
170 *  specified vector.
171 *
172 *  Input parameters:
173 *    vector      - interrupt vector number
174 *    old_handler - former ISR for this vector number
175 *    new_handler - replacement ISR for this vector number
176 *
177 *  Output parameters:  NONE
178 *
179 */
180
181/*
182 * HPPA has 8w for each vector instead of an address to jump to.
183 * We put the actual ISR address in '_ISR_vector_table'.  This will
184 * be pulled by the code in the vector.
185 */
186
187void _CPU_ISR_install_vector(
188  unsigned32  vector,
189  proc_ptr    new_handler,
190  proc_ptr   *old_handler
191)
192{
193    *old_handler = _ISR_Vector_table[vector];
194
195    _ISR_Vector_table[vector] = new_handler;
196
197    if (vector >= HPPA_INTERRUPT_EXTERNAL_BASE)
198    {
199        unsigned32 external_vector;
200
201        external_vector = vector - HPPA_INTERRUPT_EXTERNAL_BASE;
202        if (new_handler)
203            hppa_external_interrupt_enable(external_vector);
204        else
205            /* XXX this can never happen due to _ISR_Is_valid_user_handler */
206            hppa_external_interrupt_disable(external_vector);
207    }
208}
209
210
211/*
212 * Support for external and spurious interrupts on HPPA
213 *
214 *  TODO:
215 *    Count interrupts
216 *    make sure interrupts disabled properly
217 */
218
219#define DISMISS(mask)           set_eirr(mask)
220#define DISABLE(mask)           set_eiem(get_eiem() & ~(mask))
221#define ENABLE(mask)            set_eiem(get_eiem() | (mask))
222#define VECTOR_TO_MASK(v)       (1 << (31 - (v)))
223
224/*
225 * Init the external interrupt scheme
226 * called by bsp_start()
227 */
228
[3a4ae6c]229void
[ac7d5ef0]230hppa_external_interrupt_initialize(void)
231{
[591d45e]232    proc_ptr ignore;
[ac7d5ef0]233
234    /* mark them all unused */
235    DISABLE(~0);
236    DISMISS(~0);
237
238    /* install the external interrupt handler */
[c64e4ed4]239    _CPU_ISR_install_vector(
240        HPPA_INTERRUPT_EXTERNAL_INTERRUPT,
241        (proc_ptr)hppa_external_interrupt, &ignore
242);
[ac7d5ef0]243}
244
245/*
246 * Enable a specific external interrupt
247 */
248
249void
250hppa_external_interrupt_enable(unsigned32 v)
251{
252    unsigned32 isrlevel;
253
254    _CPU_ISR_Disable(isrlevel);
255    ENABLE(VECTOR_TO_MASK(v));
256    _CPU_ISR_Enable(isrlevel);
257}
258
259/*
260 * Does not clear or otherwise affect any pending requests
261 */
262
263void
264hppa_external_interrupt_disable(unsigned32 v)
265{
266    unsigned32 isrlevel;
267
268    _CPU_ISR_Disable(isrlevel);
269    DISABLE(VECTOR_TO_MASK(v));
270    _CPU_ISR_Enable(isrlevel);
271}
272
273void
274hppa_external_interrupt_spurious_handler(unsigned32           vector,
275                                         CPU_Interrupt_frame *iframe)
276{
277/* XXX should not be printing :)
278    printf("spurious external interrupt: %d at pc 0x%x; disabling\n",
279       vector, iframe->Interrupt.pcoqfront);
280*/
281}
282
283void
[c64e4ed4]284hppa_external_interrupt_report_spurious(unsigned32           spurious_mask,
[ac7d5ef0]285                                        CPU_Interrupt_frame *iframe)
286{
287    int v;
288    for (v=0; v < HPPA_EXTERNAL_INTERRUPTS; v++)
[c64e4ed4]289        if (VECTOR_TO_MASK(v) & spurious_mask)
290        {
291            DISMISS(VECTOR_TO_MASK(v));
292            DISABLE(VECTOR_TO_MASK(v));
[ac7d5ef0]293            hppa_external_interrupt_spurious_handler(v, iframe);
[c64e4ed4]294        }
295    DISMISS(spurious_mask);
[ac7d5ef0]296}
297
298
299/*
300 * External interrupt handler.
301 * This is installed as cpu interrupt handler for
302 * HPPA_INTERRUPT_EXTERNAL_INTERRUPT. It vectors out to
303 * specific external interrupt handlers.
304 */
305
306void
307hppa_external_interrupt(unsigned32           vector,
308                        CPU_Interrupt_frame *iframe)
309{
310    unsigned32   mask;
311    unsigned32  *vp, *max_vp;
312    unsigned32   external_vector;
313    unsigned32   global_vector;
314    hppa_rtems_isr_entry handler;
315
316    max_vp = &_CPU_Table.external_interrupt[_CPU_Table.external_interrupts];
317    while ( (mask = (get_eirr() & get_eiem())) )
318    {
319        for (vp = _CPU_Table.external_interrupt; (vp < max_vp) && mask; vp++)
320        {
321            unsigned32 m;
322
323            external_vector = *vp;
324            global_vector = external_vector + HPPA_INTERRUPT_EXTERNAL_BASE;
325            m = VECTOR_TO_MASK(external_vector);
326            handler = (hppa_rtems_isr_entry) _ISR_Vector_table[global_vector];
327            if ((m & mask) && handler)
328            {
329                DISMISS(m);
330                mask &= ~m;
[c64e4ed4]331                handler(global_vector, iframe);
[ac7d5ef0]332            }
333        }
334
335        if (mask != 0) {
336            if ( _CPU_Table.spurious_handler )
[c64e4ed4]337            {
338                handler = (hppa_rtems_isr_entry) _CPU_Table.spurious_handler;
339                handler(mask, iframe);
340            }
[ac7d5ef0]341            else
[c64e4ed4]342                hppa_external_interrupt_report_spurious(mask, iframe);
[ac7d5ef0]343        }
344    }
345}
346
347/*
348 * Halt the system.
349 * Called by the _CPU_Fatal_halt macro
350 *
351 * XXX
352 * Later on, this will allow us to return to the prom.
353 * For now, we just ignore 'type_of_halt'
354 */
355
356void
[c64e4ed4]357hppa_cpu_halt(unsigned32 the_error)
[ac7d5ef0]358{
359    unsigned32 isrlevel;
360
361    _CPU_ISR_Disable(isrlevel);
362
[c64e4ed4]363    HPPA_ASM_LABEL("_hppa_cpu_halt");
[ac7d5ef0]364    HPPA_ASM_BREAK(1, 0);
365}
Note: See TracBrowser for help on using the repository browser.