source: rtems/c/src/lib/libcpu/powerpc/new-exceptions/raw_exception.c @ bcd5368

4.104.114.95
Last change on this file since bcd5368 was bcd5368, checked in by Ralf Corsepius <ralf.corsepius@…>, on 09/05/08 at 12:41:40

Convert to "bool".

  • Property mode set to 100644
File size: 18.8 KB
Line 
1/*
2 * raw_exception.c  - This file contains implementation of C function to
3 *                    Instantiate 60x ppc primary exception entries.
4 *                    More detailed information can be found on motorola
5 *                    site and more precisely in the following book :
6 *
7 *                    MPC750
8 *                    Risc Microporcessor User's Manual
9 *                    Motorola REF : MPC750UM/AD 8/97
10 *
11 * Copyright (C) 1999  Eric Valette (valette@crf.canon.fr)
12 *                     Canon Centre Recherche France.
13 *
14 * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
15 * to support 603, 603e, 604, 604e exceptions
16 *
17 * moved to "libcpu/powerpc/new-exceptions and consolidated
18 * by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
19 * to be common for all PPCs with new excpetions
20 *
21 *  The license and distribution terms for this file may be
22 *  found in found in the file LICENSE in this distribution or at
23 *  http://www.rtems.com/license/LICENSE.
24 *
25 * $Id$
26 */
27#include <rtems.h>
28#include <rtems/system.h>
29#include <rtems/score/powerpc.h>
30#include <rtems/score/isr.h>
31#include <rtems/bspIo.h>
32#include <libcpu/raw_exception.h>
33#include <libcpu/cpuIdent.h>
34
35#include <string.h>
36
37/* DO NOT INTRODUCE #ifdef <cpu_flavor> in this file */
38
39/* enum ppc_raw_exception_category should fit into this type;
40 * we are setting up arrays of these for all known CPUs
41 * hence the attempt to save a few bytes.
42 */
43typedef uint8_t cat_ini_t;
44
45static rtems_raw_except_connect_data*           raw_except_table;
46static rtems_raw_except_connect_data            default_raw_except_entry;
47static rtems_raw_except_global_settings*        local_settings;
48
49void * codemove(void *, const void *, unsigned int, unsigned long);
50
51bool bsp_exceptions_in_RAM = true;
52
53/* DEPRECATED VARIABLE; we need this to support
54 * libbsp/powerpc/shared/vectors/vectors.S;
55 * new BSPs should NOT use this.
56 */
57uint32_t bsp_raw_vector_is_405_critical = 0;
58
59uint32_t ppc_exc_vector_base = 0;
60
61void* ppc_get_vector_addr(rtems_vector vector)
62{
63        unsigned vaddr;
64
65        vaddr = ((unsigned)vector) << 8;
66
67        switch(vector) {
68                /*
69                 * some vectors are located at odd addresses and only available
70                 * on some CPU derivates. this construct will handle them
71                 * if available
72                 */
73                /* Special case; altivec unavailable doesn't fit :-( */
74                case ASM_60X_VEC_VECTOR:
75#ifndef ASM_60X_VEC_VECTOR_OFFSET
76#define ASM_60X_VEC_VECTOR_OFFSET 0xf20
77#endif
78                        if ( ppc_cpu_has_altivec() )
79                                vaddr = ASM_60X_VEC_VECTOR_OFFSET;
80                        break;
81
82                default:
83                        break;
84        }
85
86        if ( PPC_405 == current_ppc_cpu ) {
87                switch ( vector ) {
88                        case ASM_BOOKE_FIT_VECTOR:
89#ifndef ASM_PPC405_FIT_VECTOR_OFFSET
90#define ASM_PPC405_FIT_VECTOR_OFFSET 0x1010
91#endif
92                                vaddr = ASM_PPC405_FIT_VECTOR_OFFSET;
93                                break;
94                        case ASM_BOOKE_WDOG_VECTOR:
95#ifndef ASM_PPC405_WDOG_VECTOR_OFFSET
96#define ASM_PPC405_WDOG_VECTOR_OFFSET 0x1020
97#endif
98                                vaddr = ASM_PPC405_WDOG_VECTOR_OFFSET;
99                                break;
100                        case ASM_TRACE_VECTOR:
101#ifndef ASM_PPC405_TRACE_VECTOR_OFFSET
102#define ASM_PPC405_TRACE_VECTOR_OFFSET  0x2000
103#endif
104                                vaddr = ASM_PPC405_TRACE_VECTOR_OFFSET;
105                                break;
106                        case ASM_PPC405_APU_UNAVAIL_VECTOR:
107                                vaddr = ASM_60X_VEC_VECTOR_OFFSET;
108                        default:
109                                break;
110                }
111        }
112
113        if (bsp_exceptions_in_RAM) {
114                if (ppc_cpu_has_ivpr_and_ivor()) {
115                        return ((void*) ((vaddr >> 4) + ppc_exc_vector_base));
116                } else {
117                        return ((void*) (vaddr + ppc_exc_vector_base));
118                }
119        }
120
121        return ((void*)  (vaddr + 0xfff00000));
122}
123
124static const cat_ini_t mpc_860_vector_categories[LAST_VALID_EXC + 1] = {
125  [ ASM_RESET_VECTOR           ] = PPC_EXC_CLASSIC,
126  [ ASM_MACH_VECTOR            ] = PPC_EXC_CLASSIC,
127  [ ASM_PROT_VECTOR            ] = PPC_EXC_CLASSIC,
128  [ ASM_ISI_VECTOR             ] = PPC_EXC_CLASSIC,
129  [ ASM_EXT_VECTOR             ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
130  [ ASM_ALIGN_VECTOR           ] = PPC_EXC_CLASSIC,
131  [ ASM_PROG_VECTOR            ] = PPC_EXC_CLASSIC,
132  [ ASM_FLOAT_VECTOR           ] = PPC_EXC_CLASSIC,
133  [ ASM_DEC_VECTOR             ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
134   
135  [ ASM_SYS_VECTOR             ] = PPC_EXC_CLASSIC,
136  [ ASM_TRACE_VECTOR           ] = PPC_EXC_CLASSIC,
137  [ ASM_8XX_FLOATASSIST_VECTOR ] = PPC_EXC_CLASSIC,
138
139  [ ASM_8XX_SOFTEMUL_VECTOR    ] = PPC_EXC_CLASSIC,
140  [ ASM_8XX_ITLBMISS_VECTOR    ] = PPC_EXC_CLASSIC,
141  [ ASM_8XX_DTLBMISS_VECTOR    ] = PPC_EXC_CLASSIC,
142  [ ASM_8XX_ITLBERROR_VECTOR   ] = PPC_EXC_CLASSIC,
143  [ ASM_8XX_DTLBERROR_VECTOR   ] = PPC_EXC_CLASSIC,
144
145  [ ASM_8XX_DBREAK_VECTOR      ] = PPC_EXC_CLASSIC,
146  [ ASM_8XX_IBREAK_VECTOR      ] = PPC_EXC_CLASSIC,
147  [ ASM_8XX_PERIFBREAK_VECTOR  ] = PPC_EXC_CLASSIC,
148  [ ASM_8XX_DEVPORT_VECTOR     ] = PPC_EXC_CLASSIC,
149};
150
151
152static const cat_ini_t mpc_5xx_vector_categories[LAST_VALID_EXC + 1] = {
153  [ ASM_RESET_VECTOR           ] = PPC_EXC_CLASSIC,
154  [ ASM_MACH_VECTOR            ] = PPC_EXC_CLASSIC,
155
156  [ ASM_EXT_VECTOR             ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
157  [ ASM_ALIGN_VECTOR           ] = PPC_EXC_CLASSIC,
158  [ ASM_PROG_VECTOR            ] = PPC_EXC_CLASSIC,
159  [ ASM_FLOAT_VECTOR           ] = PPC_EXC_CLASSIC,
160  [ ASM_DEC_VECTOR             ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
161
162  [ ASM_SYS_VECTOR             ] = PPC_EXC_CLASSIC,
163  [ ASM_TRACE_VECTOR           ] = PPC_EXC_CLASSIC,
164  [ ASM_5XX_FLOATASSIST_VECTOR ] = PPC_EXC_CLASSIC,
165
166  [ ASM_5XX_SOFTEMUL_VECTOR    ] = PPC_EXC_CLASSIC,
167
168  [ ASM_5XX_IPROT_VECTOR       ] = PPC_EXC_CLASSIC,
169  [ ASM_5XX_DPROT_VECTOR       ] = PPC_EXC_CLASSIC,
170
171  [ ASM_5XX_DBREAK_VECTOR      ] = PPC_EXC_CLASSIC,
172  [ ASM_5XX_IBREAK_VECTOR      ] = PPC_EXC_CLASSIC,
173  [ ASM_5XX_MEBREAK_VECTOR     ] = PPC_EXC_CLASSIC,
174  [ ASM_5XX_NMEBREAK_VECTOR    ] = PPC_EXC_CLASSIC,
175};
176
177static const cat_ini_t ppc_405_vector_categories[LAST_VALID_EXC + 1] = {
178  [ ASM_BOOKE_CRIT_VECTOR      ] = PPC_EXC_405_CRITICAL | PPC_EXC_ASYNC,
179  [ ASM_MACH_VECTOR            ] = PPC_EXC_405_CRITICAL,
180  [ ASM_PROT_VECTOR            ] = PPC_EXC_CLASSIC,
181  [ ASM_ISI_VECTOR             ] = PPC_EXC_CLASSIC,
182  [ ASM_EXT_VECTOR             ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
183  [ ASM_ALIGN_VECTOR           ] = PPC_EXC_CLASSIC,
184  [ ASM_PROG_VECTOR            ] = PPC_EXC_CLASSIC,
185  [ ASM_FLOAT_VECTOR           ] = PPC_EXC_CLASSIC,
186
187  [ ASM_PPC405_APU_UNAVAIL_VECTOR] = PPC_EXC_CLASSIC,
188
189  [ ASM_SYS_VECTOR             ] = PPC_EXC_CLASSIC,
190
191
192
193  [ ASM_BOOKE_DEC_VECTOR       ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,             /* PIT */
194  [ ASM_BOOKE_FIT_VECTOR       ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,             /* FIT */
195  [ ASM_BOOKE_WDOG_VECTOR      ] = PPC_EXC_405_CRITICAL | PPC_EXC_ASYNC,
196  [ ASM_BOOKE_DTLBMISS_VECTOR  ] = PPC_EXC_CLASSIC,
197  [ ASM_BOOKE_ITLBMISS_VECTOR  ] = PPC_EXC_CLASSIC,
198  [ ASM_TRACE_VECTOR           ] = PPC_EXC_405_CRITICAL,
199};
200
201
202#define PPC_BASIC_VECS \
203  [ ASM_RESET_VECTOR      ] = PPC_EXC_CLASSIC, \
204  [ ASM_MACH_VECTOR       ] = PPC_EXC_CLASSIC, \
205  [ ASM_PROT_VECTOR       ] = PPC_EXC_CLASSIC, \
206  [ ASM_ISI_VECTOR        ] = PPC_EXC_CLASSIC, \
207  [ ASM_EXT_VECTOR        ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC, \
208  [ ASM_ALIGN_VECTOR      ] = PPC_EXC_CLASSIC, \
209  [ ASM_PROG_VECTOR       ] = PPC_EXC_CLASSIC, \
210  [ ASM_FLOAT_VECTOR      ] = PPC_EXC_CLASSIC, \
211  [ ASM_DEC_VECTOR        ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC, \
212  [ ASM_SYS_VECTOR        ] = PPC_EXC_CLASSIC, \
213  [ ASM_TRACE_VECTOR      ] = PPC_EXC_CLASSIC
214
215static ppc_raw_exception_category altivec_vector_is_valid(rtems_vector vector)
216{
217        if ( ppc_cpu_has_altivec() ) {
218                switch(vector) {
219                        case ASM_60X_VEC_VECTOR:
220                        case ASM_60X_VEC_ASSIST_VECTOR:
221                                return PPC_EXC_CLASSIC;
222                        default:
223                                break;
224                }
225        }
226  return PPC_EXC_INVALID;
227}
228
229static const cat_ini_t mpc_750_vector_categories[LAST_VALID_EXC + 1] = {
230        PPC_BASIC_VECS,
231  [ ASM_60X_SYSMGMT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
232  [ ASM_60X_ADDR_VECTOR    ] = PPC_EXC_CLASSIC,
233  [ ASM_60X_ITM_VECTOR     ] = PPC_EXC_CLASSIC,
234};
235
236static const cat_ini_t psim_vector_categories[LAST_VALID_EXC + 1] = {
237  [ ASM_RESET_VECTOR       ] = PPC_EXC_CLASSIC,
238  [ ASM_MACH_VECTOR        ] = PPC_EXC_CLASSIC,
239  [ ASM_PROT_VECTOR        ] = PPC_EXC_CLASSIC,
240  [ ASM_ISI_VECTOR         ] = PPC_EXC_CLASSIC,
241  [ ASM_EXT_VECTOR         ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
242  [ ASM_ALIGN_VECTOR       ] = PPC_EXC_CLASSIC,
243  [ ASM_PROG_VECTOR        ] = PPC_EXC_CLASSIC,
244  [ ASM_FLOAT_VECTOR       ] = PPC_EXC_CLASSIC,
245  [ ASM_DEC_VECTOR         ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
246  [ ASM_SYS_VECTOR         ] = PPC_EXC_INVALID,
247  [ ASM_TRACE_VECTOR       ] = PPC_EXC_CLASSIC,
248  [ ASM_60X_PERFMON_VECTOR ] = PPC_EXC_INVALID,
249  [ ASM_60X_SYSMGMT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
250  [ ASM_60X_IMISS_VECTOR   ] = PPC_EXC_CLASSIC,
251  [ ASM_60X_DLMISS_VECTOR  ] = PPC_EXC_CLASSIC,
252  [ ASM_60X_DSMISS_VECTOR  ] = PPC_EXC_CLASSIC,
253  [ ASM_60X_ADDR_VECTOR    ] = PPC_EXC_CLASSIC,
254  [ ASM_60X_ITM_VECTOR     ] = PPC_EXC_INVALID,
255};
256
257static const cat_ini_t mpc_603_vector_categories[LAST_VALID_EXC + 1] = {
258        PPC_BASIC_VECS,
259  [ ASM_60X_PERFMON_VECTOR ] = PPC_EXC_INVALID,
260  [ ASM_60X_SYSMGMT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
261  [ ASM_60X_IMISS_VECTOR   ] = PPC_EXC_CLASSIC,
262  [ ASM_60X_DLMISS_VECTOR  ] = PPC_EXC_CLASSIC,
263  [ ASM_60X_DSMISS_VECTOR  ] = PPC_EXC_CLASSIC,
264  [ ASM_60X_ADDR_VECTOR    ] = PPC_EXC_CLASSIC,
265  [ ASM_60X_ITM_VECTOR     ] = PPC_EXC_INVALID,
266};
267
268static const cat_ini_t mpc_604_vector_categories[LAST_VALID_EXC + 1] = {
269        PPC_BASIC_VECS,
270  [ ASM_60X_PERFMON_VECTOR ] = PPC_EXC_CLASSIC,
271  [ ASM_60X_IMISS_VECTOR   ] = PPC_EXC_INVALID,
272  [ ASM_60X_DLMISS_VECTOR  ] = PPC_EXC_INVALID,
273  [ ASM_60X_DSMISS_VECTOR  ] = PPC_EXC_INVALID,
274  [ ASM_60X_SYSMGMT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
275  [ ASM_60X_ADDR_VECTOR    ] = PPC_EXC_CLASSIC,
276  [ ASM_60X_ITM_VECTOR     ] = PPC_EXC_INVALID,
277};
278
279static const cat_ini_t e200_vector_categories [LAST_VALID_EXC + 1] = {
280        [ASM_MACH_VECTOR]                 = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
281        [ASM_PROT_VECTOR]                 = PPC_EXC_CLASSIC,
282        [ASM_ISI_VECTOR]                  = PPC_EXC_CLASSIC,
283        [ASM_EXT_VECTOR]                  = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
284        [ASM_ALIGN_VECTOR]                = PPC_EXC_CLASSIC,
285        [ASM_PROG_VECTOR]                 = PPC_EXC_CLASSIC,
286        [ASM_FLOAT_VECTOR]                = PPC_EXC_CLASSIC,
287        [ASM_SYS_VECTOR]                  = PPC_EXC_CLASSIC,
288        [ASM_BOOKE_DEC_VECTOR]            = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
289        [ASM_BOOKE_FIT_VECTOR]            = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
290        [ASM_BOOKE_WDOG_VECTOR]           = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
291        [ASM_BOOKE_ITLBMISS_VECTOR]       = PPC_EXC_CLASSIC,
292        [ASM_BOOKE_DTLBMISS_VECTOR]       = PPC_EXC_CLASSIC,
293
294        /* FIXME: Depending on HDI0[DAPUEN] this is a critical or debug exception */
295        [ASM_TRACE_VECTOR]                = PPC_EXC_CLASSIC | PPC_EXC_BOOKE_CRITICAL,
296
297        [ASM_E200_SPE_UNAVAILABLE_VECTOR] = PPC_EXC_CLASSIC,
298        [ASM_E200_SPE_DATA_VECTOR]        = PPC_EXC_CLASSIC,
299        [ASM_E200_SPE_ROUND_VECTOR]       = PPC_EXC_CLASSIC,
300};
301
302static const cat_ini_t e300_vector_categories [LAST_VALID_EXC + 1] = {
303        PPC_BASIC_VECS,
304        [ASM_E300_CRIT_VECTOR]    = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
305        [ASM_E300_PERFMON_VECTOR] = PPC_EXC_CLASSIC,
306        [ASM_E300_IMISS_VECTOR]   = PPC_EXC_CLASSIC,
307        [ASM_E300_DLMISS_VECTOR]  = PPC_EXC_CLASSIC,
308        [ASM_E300_DSMISS_VECTOR]  = PPC_EXC_CLASSIC,
309        [ASM_E300_ADDR_VECTOR]    = PPC_EXC_CLASSIC,
310        [ASM_E300_SYSMGMT_VECTOR] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
311};
312
313static const cat_ini_t e500_vector_categories[LAST_VALID_EXC + 1] = {
314  [ ASM_MACH_VECTOR                 ] = PPC_EXC_E500_MACHCHK,
315
316  [ ASM_BOOKE_CRIT_VECTOR           ] = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
317  [ ASM_BOOKE_WDOG_VECTOR           ] = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
318  [ ASM_TRACE_VECTOR                ] = PPC_EXC_BOOKE_CRITICAL,
319
320  [ ASM_EXT_VECTOR                  ] = PPC_EXC_CLASSIC        | PPC_EXC_ASYNC,
321  [ ASM_BOOKE_DEC_VECTOR            ] = PPC_EXC_CLASSIC        | PPC_EXC_ASYNC,
322  [ ASM_BOOKE_FIT_VECTOR            ] = PPC_EXC_CLASSIC        | PPC_EXC_ASYNC,
323
324  [ ASM_PROT_VECTOR                 ] = PPC_EXC_CLASSIC,
325  [ ASM_ISI_VECTOR                  ] = PPC_EXC_CLASSIC,
326  [ ASM_ALIGN_VECTOR                ] = PPC_EXC_CLASSIC,
327  [ ASM_PROG_VECTOR                 ] = PPC_EXC_CLASSIC,
328  [ ASM_FLOAT_VECTOR                ] = PPC_EXC_CLASSIC,
329  [ ASM_SYS_VECTOR                  ] = PPC_EXC_CLASSIC,
330  [ /* APU unavailable      */ 0x0b ] = PPC_EXC_CLASSIC,
331
332  [ ASM_60X_DLMISS_VECTOR           ] = PPC_EXC_CLASSIC,
333  [ ASM_60X_DSMISS_VECTOR           ] = PPC_EXC_CLASSIC,
334  [ ASM_60X_VEC_VECTOR              ] = PPC_EXC_CLASSIC,
335  [ ASM_60X_PERFMON_VECTOR          ] = PPC_EXC_CLASSIC,
336
337  [ /* emb FP data          */ 0x15 ] = PPC_EXC_CLASSIC,
338  [ /* emb FP round         */ 0x16 ] = PPC_EXC_CLASSIC,
339};
340
341ppc_raw_exception_category ppc_vector_is_valid(rtems_vector vector)
342{
343ppc_raw_exception_category rval = PPC_EXC_INVALID;
344
345        if ( vector > LAST_VALID_EXC )
346                return PPC_EXC_INVALID;
347
348     switch (current_ppc_cpu) {
349        case PPC_7400:
350            if ( ( rval = altivec_vector_is_valid(vector)) )
351                return rval;
352            /* else fall thru */
353        case PPC_750:
354                        rval = mpc_750_vector_categories[vector];
355            break;
356        case PPC_7455:   /* Kate Feng */
357        case PPC_7457:
358            if ( ( rval = altivec_vector_is_valid(vector) ) )
359                return rval;
360            /* else fall thru */
361        case PPC_604:
362        case PPC_604e:
363        case PPC_604r:
364                        rval = mpc_604_vector_categories[vector];
365            break;
366        case PPC_603:
367        case PPC_603e:
368        case PPC_603le:
369        case PPC_603ev:
370        case PPC_8260:
371        /* case PPC_8240: -- same value as 8260 */
372        case PPC_8245:
373                        rval = mpc_603_vector_categories[vector];
374            break;
375        case PPC_e300c1:
376        case PPC_e300c2:
377        case PPC_e300c3:
378                        rval = e300_vector_categories[vector];
379            break;
380        case PPC_PSIM:
381                        rval = psim_vector_categories[vector];
382            break;
383        case PPC_8540:
384                        rval = e500_vector_categories[vector];
385            break;
386        case PPC_e200z6:
387                        rval = e200_vector_categories[vector];
388            break;
389        case PPC_5XX:
390                        rval = mpc_5xx_vector_categories[vector];
391            break;
392        case PPC_860:
393                        rval = mpc_860_vector_categories[vector];
394            break;
395        case PPC_405:
396        case PPC_405GP:
397        case PPC_405EX:
398                        rval = ppc_405_vector_categories[vector];
399            break;
400        default:
401            printk("Please complete "
402                   "libcpu/powerpc/new-exceptions/raw_exception.c\n"
403                   "current_ppc_cpu = %x\n", current_ppc_cpu);
404            return PPC_EXC_INVALID;
405     }
406     return rval;
407}
408
409int ppc_set_exception  (const rtems_raw_except_connect_data* except)
410{
411    rtems_interrupt_level k;
412
413    if ( PPC_EXC_INVALID == ppc_vector_is_valid(except->hdl.vector) ) {
414      printk("ppc_set_exception: vector %d is not valid\n",
415              except->hdl.vector);
416      return 0;
417    }
418    /*
419     * Check if default handler is actually connected. If not issue an error.
420     * You must first get the current handler via mpc60x_get_current_exception
421     * and then disconnect it using mpc60x_delete_exception.
422     * RATIONALE : to always have the same transition by forcing the user
423     * to get the previous handler before accepting to disconnect.
424     */
425
426    if (memcmp(ppc_get_vector_addr(except->hdl.vector),
427               (void*)default_raw_except_entry.hdl.raw_hdl,
428               default_raw_except_entry.hdl.raw_hdl_size)) {
429      printk("ppc_set_exception: raw vector not installed\n");
430      return 0;
431    }
432
433    rtems_interrupt_disable(k);
434
435    raw_except_table [except->exceptIndex] = *except;
436    codemove(ppc_get_vector_addr(except->hdl.vector),
437             except->hdl.raw_hdl,
438             except->hdl.raw_hdl_size,
439             PPC_CACHE_ALIGNMENT);
440        if (except->on)
441        except->on(except);
442
443    rtems_interrupt_enable(k);
444    return 1;
445}
446
447int ppc_get_current_exception (rtems_raw_except_connect_data* except)
448{
449        rtems_interrupt_level k;
450        int i;
451
452        if ( PPC_EXC_INVALID == ppc_vector_is_valid(except->hdl.vector) ) {
453                return 0;
454        }
455
456        for (i=0; i < local_settings->exceptSize; i++) {
457                if ( raw_except_table[i].hdl.vector == except->hdl.vector ) {
458                        rtems_interrupt_disable(k);
459                                if ( raw_except_table[i].hdl.vector == except->hdl.vector ) {
460                                        *except = raw_except_table[i]; 
461                                        rtems_interrupt_enable(k);
462                                        return 1;
463                                }
464                        rtems_interrupt_enable(k);
465                }
466        }
467
468        return 0;
469}
470
471int ppc_delete_exception (const rtems_raw_except_connect_data* except)
472{
473  rtems_interrupt_level k;
474
475  if ( PPC_EXC_INVALID == ppc_vector_is_valid(except->hdl.vector) ) {
476    return 0;
477  }
478  /*
479   * Check if handler passed is actually connected. If not issue an error.
480   * You must first get the current handler via ppc_get_current_exception
481   * and then disconnect it using ppc_delete_exception.
482   * RATIONALE : to always have the same transition by forcing the user
483   * to get the previous handler before accepting to disconnect.
484   */
485  if (memcmp(ppc_get_vector_addr(except->hdl.vector),
486             (void*)except->hdl.raw_hdl,
487             except->hdl.raw_hdl_size)) {
488      return 0;
489  }
490  rtems_interrupt_disable(k);
491
492  if (except->off)
493          except->off(except);
494  codemove(ppc_get_vector_addr(except->hdl.vector),
495           default_raw_except_entry.hdl.raw_hdl,
496           default_raw_except_entry.hdl.raw_hdl_size,
497           PPC_CACHE_ALIGNMENT);
498
499
500  raw_except_table[except->exceptIndex] = default_raw_except_entry;
501  raw_except_table[except->exceptIndex].exceptIndex = except->exceptIndex;
502  raw_except_table[except->exceptIndex].hdl.vector  = except->hdl.vector;
503
504  rtems_interrupt_enable(k);
505
506  return 1;
507}
508
509/*
510 * Exception global init.
511 */
512int ppc_init_exceptions (rtems_raw_except_global_settings* config)
513{
514        rtems_interrupt_level k;
515    int                   i;
516        unsigned              c;
517
518    /*
519     * store various accelerators
520     */
521    raw_except_table            = config->rawExceptHdlTbl;
522    local_settings              = config;
523    default_raw_except_entry    = config->defaultRawEntry;
524
525    rtems_interrupt_disable(k);
526
527        /* FIXME special case selection method */
528        if (current_ppc_cpu == PPC_e200z6) {
529                e200_setup_raw_exceptions();
530        } else if ( (c = ppc_cpu_is_bookE()) && PPC_BOOKE_405 != c ) {
531                e500_setup_raw_exceptions();
532        }
533
534        /* Need to support libbsp/powerpc/shared/vectors.S
535         * (hopefully this can go away some day)
536         * We also rely on LAST_VALID_EXC < 32
537         */
538        for ( i=0; i <= LAST_VALID_EXC; i++ ) {
539                if ( PPC_EXC_405_CRITICAL == (ppc_vector_is_valid( i ) & ~PPC_EXC_ASYNC) )
540                        bsp_raw_vector_is_405_critical |= (1<<i);
541        }
542
543        for (i=0; i < config->exceptSize; i++) {
544                if ( PPC_EXC_INVALID == ppc_vector_is_valid(raw_except_table[i].hdl.vector) ) {
545                        continue;
546                }
547                codemove(ppc_get_vector_addr(raw_except_table[i].hdl.vector),
548                                raw_except_table[i].hdl.raw_hdl,
549                                raw_except_table[i].hdl.raw_hdl_size,
550                                PPC_CACHE_ALIGNMENT);
551                if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) {
552                        if (raw_except_table[i].on)
553                                raw_except_table[i].on(&raw_except_table[i]);
554                }
555                else {
556                        if (raw_except_table[i].off)
557                                raw_except_table[i].off(&raw_except_table[i]);
558                }
559        }
560    rtems_interrupt_enable(k);
561
562    return 1;
563}
564
565int ppc_get_exception_config (rtems_raw_except_global_settings** config)
566{
567  *config = local_settings;
568  return 1;
569}
Note: See TracBrowser for help on using the repository browser.