source: rtems/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_hdl.c @ f328b69

4.104.114.95
Last change on this file since f328b69 was f328b69, checked in by Till Straumann <strauman@…>, on 12/11/07 at 05:19:55

2007-12-10 Till Straumann <strauman@…>

  • new-exceptions/bspsupport/ppc_exc_hdl.c: make sure RI is set in the exception frame and panic if it isn't (state info might have been lost). This only affects classic PPC.
  • Property mode set to 100644
File size: 4.4 KB
Line 
1/* PowerPC exception handling middleware; consult README for more
2 * information.
3 *
4 * Author: Till Straumann <strauman@slac.stanford.edu>, 2007
5 *
6 *  The license and distribution terms for this file may be
7 *  found in found in the file LICENSE in this distribution or at
8 *  http://www.rtems.com/license/LICENSE.
9 *
10 *  $Id$
11 */
12
13#include        <stdint.h>
14#include        <string.h>
15
16#include        <rtems.h>
17#include        <rtems/score/cpu.h>
18#include        <libcpu/raw_exception.h>
19#include        <libcpu/spr.h>
20#include        <rtems/score/apiext.h>
21
22#include        "vectors.h"
23#include        "ppc_exc_bspsupp.h"
24
25/* offset into min-prolog where vector # is hardcoded */
26#define         PPC_EXC_PROLOG_VEC_OFFSET       2
27
28/* Provide temp. storage space for a few registers.
29 * This is used by the assembly code prior to setting up
30 * the stack.
31 * One set is needed for each exception type with its
32 * own SRR0/SRR1 pair since such exceptions may nest.
33 *
34 * NOTE: The assembly code needs these variables to
35 *       be in the .sdata section and accesses them
36 *       via R13.
37 */
38uint32_t ppc_exc_lock_std  = 0;
39uint32_t ppc_exc_lock_crit = 0;
40uint32_t ppc_exc_lock_mchk = 0;
41
42uint32_t ppc_exc_gpr3_std     = 0;
43uint32_t ppc_exc_gpr3_crit    = 0;
44uint32_t ppc_exc_gpr3_mchk    = 0;
45
46uint32_t ppc_exc_msr_irq_mask =  MSR_EE;
47
48/* MSR bits to enable once critical status info is saved and the stack
49 * is switched; must be set depending on CPU type
50 *
51 * Default is set here for classic PPC CPUs with a MMU
52 * but is overridden from vectors_init.c
53 */
54uint32_t ppc_exc_msr_bits     = MSR_IR | MSR_DR | MSR_RI;
55
56
57/* Table of C-handlers */
58static ppc_exc_handler_t ppc_exc_handlers[LAST_VALID_EXC + 1] = {0, };
59
60ppc_exc_handler_t
61ppc_exc_get_handler(unsigned vector)
62{
63        if ( vector > LAST_VALID_EXC )
64                return 0;
65        return ppc_exc_handlers[vector];
66}
67
68int
69ppc_exc_set_handler(unsigned vector, ppc_exc_handler_t hdl)
70{
71        if ( vector > LAST_VALID_EXC )
72                return -1;
73        ppc_exc_handlers[vector] = hdl;
74        return 0;
75}
76
77/* This routine executes on the interrupt stack (if vect < 0) */
78int
79ppc_exc_C_wrapper(int vect, BSP_Exception_frame *f)
80{
81unsigned int i    = vect & 0x3f;
82int          rval = 1;
83
84        if ( i <= LAST_VALID_EXC  && ppc_exc_handlers[i] ) {
85                rval = ppc_exc_handlers[i](f, i);
86        }
87
88        if ( rval ) {
89                /* not handled, so far ... */
90                if ( globalExceptHdl ) {
91                        /*
92                         * global handler must be prepared to
93                         * deal with asynchronous exceptions!
94                         */
95                        globalExceptHdl(f);
96                }
97                rval = 0;
98        }
99
100        if ( (ppc_exc_msr_bits ^ f->EXC_SRR1) & MSR_RI ) {
101                printk("unrecoverable exception (RI was clear), spinning to death.\n");
102                while (1)
103                        ;
104        }
105
106        return rval;
107}
108
109void
110ppc_exc_wrapup(int ll_rval, BSP_Exception_frame *f)
111{
112        /* Check if we need to run the global handler now */
113        if ( ll_rval ) {
114                /* We get here if ppc_exc_C_wrapper() returned nonzero.
115                 * This could be useful if we need to do something
116                 * with thread-dispatching enabled (at this point it is)
117                 * after handling an asynchronous exception.
118                 */
119        }
120        /* dispatch_disable level is decremented from assembly code.  */
121        if ( _Context_Switch_necessary )
122                _Thread_Dispatch();
123        else if ( _ISR_Signals_to_thread_executing ) {
124                _ISR_Signals_to_thread_executing = 0;
125                /*
126                 * Process pending signals that have not already been
127                 * processed by _Thread_Dispatch. This happens quite
128                 * unfrequently : the ISR must have posted an action
129                 * to the current running thread.
130                 */
131                if ( _Thread_Do_post_task_switch_extension ||
132                                _Thread_Executing->do_post_task_switch_extension ) {
133                        _Thread_Executing->do_post_task_switch_extension = FALSE;
134                        _API_extensions_Run_postswitch();
135                }
136        }
137}
138
139void
140ppc_exc_min_prolog_expand(ppc_exc_min_prolog_t buf, ppc_exc_min_prolog_template_t templ, uint16_t vec)
141{
142        memcpy(&buf[0], templ, sizeof(ppc_exc_min_prolog_t));
143        /* fixup the vector */
144        buf[PPC_EXC_PROLOG_VEC_OFFSET] = (buf[PPC_EXC_PROLOG_VEC_OFFSET] & 0xffff8000) | (vec & 0x7fff);
145}
146
147#undef TESTING
148#ifdef TESTING
149
150static void noop(const struct __rtems_raw_except_connect_data__*x) {}
151
152rtems_raw_except_connect_data exc_conn = {
153        exceptIndex: ASM_SYS_VECTOR,
154        hdl        : {
155                                        vector: ASM_SYS_VECTOR,
156                                        raw_hdl: 0,
157                                        raw_hdl_size: 0
158                     },
159        on         : noop,
160        off        : noop,
161        isOn       : 0  /* never used AFAIK */
162};
163
164void
165ppc_exc_raise()
166{
167        asm volatile("li 3, 0xffffdead; sc");
168}
169
170
171int
172exc_conn_do()
173{
174        exc_conn.hdl.raw_hdl      = ppc_exc_min_prolog_auto;
175        exc_conn.hdl.raw_hdl_size = 16;
176        return ppc_set_exception(&exc_conn);
177}
178#endif
Note: See TracBrowser for help on using the repository browser.