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

4.104.114.9
Last change on this file since 25a92bc1 was 25a92bc1, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Jul 11, 2008 at 10:02:12 AM

adapted powerpc exception code

  • Property mode set to 100644
File size: 18.1 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
51boolean 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  case ASM_BOOKE_FIT_VECTOR:
83#ifndef ASM_BOOKE_FIT_VECTOR_OFFSET
84#define ASM_BOOKE_FIT_VECTOR_OFFSET 0x1010
85#endif
86        if ( PPC_405 == current_ppc_cpu )
87        vaddr = ASM_BOOKE_FIT_VECTOR_OFFSET;
88    break;
89  case ASM_BOOKE_WDOG_VECTOR:
90#ifndef ASM_BOOKE_WDOG_VECTOR_OFFSET
91#define ASM_BOOKE_WDOG_VECTOR_OFFSET 0x1020
92#endif
93        if ( PPC_405 == current_ppc_cpu )
94        vaddr = ASM_BOOKE_WDOG_VECTOR_OFFSET;
95    break;
96  default:
97    break;
98  }
99  if (bsp_exceptions_in_RAM) {
100    if (ppc_cpu_has_ivpr_and_ivor()) {
101      return ((void*) ((vaddr >> 4) + ppc_exc_vector_base));
102    } else {
103      return ((void*) (vaddr + ppc_exc_vector_base));
104    }
105  }
106
107  return ((void*)  (vaddr + 0xfff00000));
108}
109
110static const cat_ini_t mpc_860_vector_categories[LAST_VALID_EXC + 1] = {
111  [ ASM_RESET_VECTOR           ] = PPC_EXC_CLASSIC,
112  [ ASM_MACH_VECTOR            ] = PPC_EXC_CLASSIC,
113  [ ASM_PROT_VECTOR            ] = PPC_EXC_CLASSIC,
114  [ ASM_ISI_VECTOR             ] = PPC_EXC_CLASSIC,
115  [ ASM_EXT_VECTOR             ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
116  [ ASM_ALIGN_VECTOR           ] = PPC_EXC_CLASSIC,
117  [ ASM_PROG_VECTOR            ] = PPC_EXC_CLASSIC,
118  [ ASM_FLOAT_VECTOR           ] = PPC_EXC_CLASSIC,
119  [ ASM_DEC_VECTOR             ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
120   
121  [ ASM_SYS_VECTOR             ] = PPC_EXC_CLASSIC,
122  [ ASM_TRACE_VECTOR           ] = PPC_EXC_CLASSIC,
123  [ ASM_8XX_FLOATASSIST_VECTOR ] = PPC_EXC_CLASSIC,
124
125  [ ASM_8XX_SOFTEMUL_VECTOR    ] = PPC_EXC_CLASSIC,
126  [ ASM_8XX_ITLBMISS_VECTOR    ] = PPC_EXC_CLASSIC,
127  [ ASM_8XX_DTLBMISS_VECTOR    ] = PPC_EXC_CLASSIC,
128  [ ASM_8XX_ITLBERROR_VECTOR   ] = PPC_EXC_CLASSIC,
129  [ ASM_8XX_DTLBERROR_VECTOR   ] = PPC_EXC_CLASSIC,
130
131  [ ASM_8XX_DBREAK_VECTOR      ] = PPC_EXC_CLASSIC,
132  [ ASM_8XX_IBREAK_VECTOR      ] = PPC_EXC_CLASSIC,
133  [ ASM_8XX_PERIFBREAK_VECTOR  ] = PPC_EXC_CLASSIC,
134  [ ASM_8XX_DEVPORT_VECTOR     ] = PPC_EXC_CLASSIC,
135};
136
137
138static const cat_ini_t mpc_5xx_vector_categories[LAST_VALID_EXC + 1] = {
139  [ ASM_RESET_VECTOR           ] = PPC_EXC_CLASSIC,
140  [ ASM_MACH_VECTOR            ] = PPC_EXC_CLASSIC,
141
142  [ ASM_EXT_VECTOR             ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
143  [ ASM_ALIGN_VECTOR           ] = PPC_EXC_CLASSIC,
144  [ ASM_PROG_VECTOR            ] = PPC_EXC_CLASSIC,
145  [ ASM_FLOAT_VECTOR           ] = PPC_EXC_CLASSIC,
146  [ ASM_DEC_VECTOR             ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
147
148  [ ASM_SYS_VECTOR             ] = PPC_EXC_CLASSIC,
149  [ ASM_TRACE_VECTOR           ] = PPC_EXC_CLASSIC,
150  [ ASM_5XX_FLOATASSIST_VECTOR ] = PPC_EXC_CLASSIC,
151
152  [ ASM_5XX_SOFTEMUL_VECTOR    ] = PPC_EXC_CLASSIC,
153
154  [ ASM_5XX_IPROT_VECTOR       ] = PPC_EXC_CLASSIC,
155  [ ASM_5XX_DPROT_VECTOR       ] = PPC_EXC_CLASSIC,
156
157  [ ASM_5XX_DBREAK_VECTOR      ] = PPC_EXC_CLASSIC,
158  [ ASM_5XX_IBREAK_VECTOR      ] = PPC_EXC_CLASSIC,
159  [ ASM_5XX_MEBREAK_VECTOR     ] = PPC_EXC_CLASSIC,
160  [ ASM_5XX_NMEBREAK_VECTOR    ] = PPC_EXC_CLASSIC,
161};
162
163static const cat_ini_t ppc_405_vector_categories[LAST_VALID_EXC + 1] = {
164  [ ASM_EXT_VECTOR             ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
165  [ ASM_BOOKE_DEC_VECTOR       ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
166
167  [ ASM_PROT_VECTOR            ] = PPC_EXC_CLASSIC,
168  [ ASM_ISI_VECTOR             ] = PPC_EXC_CLASSIC,
169  [ ASM_ALIGN_VECTOR           ] = PPC_EXC_CLASSIC,
170  [ ASM_PROG_VECTOR            ] = PPC_EXC_CLASSIC,
171  [ ASM_SYS_VECTOR             ] = PPC_EXC_CLASSIC,
172  [ ASM_BOOKE_ITLBMISS_VECTOR  ] = PPC_EXC_CLASSIC,
173  [ ASM_BOOKE_DTLBMISS_VECTOR  ] = PPC_EXC_CLASSIC,
174
175  [ ASM_BOOKE_CRIT_VECTOR      ] = PPC_EXC_405_CRITICAL | PPC_EXC_ASYNC,
176  [ ASM_MACH_VECTOR            ] = PPC_EXC_405_CRITICAL,
177};
178
179
180#define PPC_BASIC_VECS \
181  [ ASM_RESET_VECTOR      ] = PPC_EXC_CLASSIC, \
182  [ ASM_MACH_VECTOR       ] = PPC_EXC_CLASSIC, \
183  [ ASM_PROT_VECTOR       ] = PPC_EXC_CLASSIC, \
184  [ ASM_ISI_VECTOR        ] = PPC_EXC_CLASSIC, \
185  [ ASM_EXT_VECTOR        ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC, \
186  [ ASM_ALIGN_VECTOR      ] = PPC_EXC_CLASSIC, \
187  [ ASM_PROG_VECTOR       ] = PPC_EXC_CLASSIC, \
188  [ ASM_FLOAT_VECTOR      ] = PPC_EXC_CLASSIC, \
189  [ ASM_DEC_VECTOR        ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC, \
190  [ ASM_SYS_VECTOR        ] = PPC_EXC_CLASSIC, \
191  [ ASM_TRACE_VECTOR      ] = PPC_EXC_CLASSIC
192
193static ppc_raw_exception_category altivec_vector_is_valid(rtems_vector vector)
194{
195        if ( ppc_cpu_has_altivec() ) {
196                switch(vector) {
197                        case ASM_60X_VEC_VECTOR:
198                        case ASM_60X_VEC_ASSIST_VECTOR:
199                                return PPC_EXC_CLASSIC;
200                        default:
201                                break;
202                }
203        }
204  return PPC_EXC_INVALID;
205}
206
207static const cat_ini_t mpc_750_vector_categories[LAST_VALID_EXC + 1] = {
208        PPC_BASIC_VECS,
209  [ ASM_60X_SYSMGMT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
210  [ ASM_60X_ADDR_VECTOR    ] = PPC_EXC_CLASSIC,
211  [ ASM_60X_ITM_VECTOR     ] = PPC_EXC_CLASSIC,
212};
213
214static const cat_ini_t psim_vector_categories[LAST_VALID_EXC + 1] = {
215  [ ASM_RESET_VECTOR       ] = PPC_EXC_CLASSIC,
216  [ ASM_MACH_VECTOR        ] = PPC_EXC_CLASSIC,
217  [ ASM_PROT_VECTOR        ] = PPC_EXC_CLASSIC,
218  [ ASM_ISI_VECTOR         ] = PPC_EXC_CLASSIC,
219  [ ASM_EXT_VECTOR         ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
220  [ ASM_ALIGN_VECTOR       ] = PPC_EXC_CLASSIC,
221  [ ASM_PROG_VECTOR        ] = PPC_EXC_CLASSIC,
222  [ ASM_FLOAT_VECTOR       ] = PPC_EXC_CLASSIC,
223  [ ASM_DEC_VECTOR         ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
224  [ ASM_SYS_VECTOR         ] = PPC_EXC_INVALID,
225  [ ASM_TRACE_VECTOR       ] = PPC_EXC_CLASSIC,
226  [ ASM_60X_PERFMON_VECTOR ] = PPC_EXC_INVALID,
227  [ ASM_60X_SYSMGMT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
228  [ ASM_60X_IMISS_VECTOR   ] = PPC_EXC_CLASSIC,
229  [ ASM_60X_DLMISS_VECTOR  ] = PPC_EXC_CLASSIC,
230  [ ASM_60X_DSMISS_VECTOR  ] = PPC_EXC_CLASSIC,
231  [ ASM_60X_ADDR_VECTOR    ] = PPC_EXC_CLASSIC,
232  [ ASM_60X_ITM_VECTOR     ] = PPC_EXC_INVALID,
233};
234
235static const cat_ini_t mpc_603_vector_categories[LAST_VALID_EXC + 1] = {
236        PPC_BASIC_VECS,
237  [ ASM_60X_PERFMON_VECTOR ] = PPC_EXC_INVALID,
238  [ ASM_60X_SYSMGMT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
239  [ ASM_60X_IMISS_VECTOR   ] = PPC_EXC_CLASSIC,
240  [ ASM_60X_DLMISS_VECTOR  ] = PPC_EXC_CLASSIC,
241  [ ASM_60X_DSMISS_VECTOR  ] = PPC_EXC_CLASSIC,
242  [ ASM_60X_ADDR_VECTOR    ] = PPC_EXC_CLASSIC,
243  [ ASM_60X_ITM_VECTOR     ] = PPC_EXC_INVALID,
244};
245
246static const cat_ini_t mpc_604_vector_categories[LAST_VALID_EXC + 1] = {
247        PPC_BASIC_VECS,
248  [ ASM_60X_PERFMON_VECTOR ] = PPC_EXC_CLASSIC,
249  [ ASM_60X_IMISS_VECTOR   ] = PPC_EXC_INVALID,
250  [ ASM_60X_DLMISS_VECTOR  ] = PPC_EXC_INVALID,
251  [ ASM_60X_DSMISS_VECTOR  ] = PPC_EXC_INVALID,
252  [ ASM_60X_SYSMGMT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
253  [ ASM_60X_ADDR_VECTOR    ] = PPC_EXC_CLASSIC,
254  [ ASM_60X_ITM_VECTOR     ] = PPC_EXC_INVALID,
255};
256
257static const cat_ini_t e200_vector_categories [LAST_VALID_EXC + 1] = {
258        [ASM_MACH_VECTOR]                 = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
259        [ASM_PROT_VECTOR]                 = PPC_EXC_CLASSIC,
260        [ASM_ISI_VECTOR]                  = PPC_EXC_CLASSIC,
261        [ASM_EXT_VECTOR]                  = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
262        [ASM_ALIGN_VECTOR]                = PPC_EXC_CLASSIC,
263        [ASM_PROG_VECTOR]                 = PPC_EXC_CLASSIC,
264        [ASM_FLOAT_VECTOR]                = PPC_EXC_CLASSIC,
265        [ASM_SYS_VECTOR]                  = PPC_EXC_CLASSIC,
266        [ASM_BOOKE_DEC_VECTOR]            = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
267        [ASM_BOOKE_FIT_VECTOR]            = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
268        [ASM_BOOKE_WDOG_VECTOR]           = PPC_EXC_BOOKE_CRITICAL,
269        [ASM_BOOKE_ITLBMISS_VECTOR]       = PPC_EXC_CLASSIC,
270        [ASM_BOOKE_DTLBMISS_VECTOR]       = PPC_EXC_CLASSIC,
271
272        /* FIXME: Depending on HDI0[DAPUEN] this is a critical or debug exception */
273        [ASM_TRACE_VECTOR]                = PPC_EXC_CLASSIC | PPC_EXC_BOOKE_CRITICAL,
274
275        [ASM_E200_SPE_UNAVAILABLE_VECTOR] = PPC_EXC_CLASSIC,
276        [ASM_E200_SPE_DATA_VECTOR]        = PPC_EXC_CLASSIC,
277        [ASM_E200_SPE_ROUND_VECTOR]       = PPC_EXC_CLASSIC,
278};
279
280static const cat_ini_t e300_vector_categories [LAST_VALID_EXC + 1] = {
281        PPC_BASIC_VECS,
282        [ASM_E300_CRIT_VECTOR]    = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
283        [ASM_E300_PERFMON_VECTOR] = PPC_EXC_CLASSIC,
284        [ASM_E300_IMISS_VECTOR]   = PPC_EXC_CLASSIC,
285        [ASM_E300_DLMISS_VECTOR]  = PPC_EXC_CLASSIC,
286        [ASM_E300_DSMISS_VECTOR]  = PPC_EXC_CLASSIC,
287        [ASM_E300_ADDR_VECTOR]    = PPC_EXC_CLASSIC,
288        [ASM_E300_SYSMGMT_VECTOR] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
289};
290
291static const cat_ini_t e500_vector_categories[LAST_VALID_EXC + 1] = {
292  [ ASM_MACH_VECTOR                 ] = PPC_EXC_E500_MACHCHK,
293
294  [ ASM_BOOKE_CRIT_VECTOR           ] = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
295  [ ASM_BOOKE_WDOG_VECTOR           ] = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC,
296  [ ASM_TRACE_VECTOR                ] = PPC_EXC_BOOKE_CRITICAL,
297
298  [ ASM_EXT_VECTOR                  ] = PPC_EXC_CLASSIC        | PPC_EXC_ASYNC,
299  [ ASM_BOOKE_DEC_VECTOR            ] = PPC_EXC_CLASSIC        | PPC_EXC_ASYNC,
300  [ ASM_BOOKE_FIT_VECTOR            ] = PPC_EXC_CLASSIC        | PPC_EXC_ASYNC,
301
302  [ ASM_PROT_VECTOR                 ] = PPC_EXC_CLASSIC,
303  [ ASM_ISI_VECTOR                  ] = PPC_EXC_CLASSIC,
304  [ ASM_ALIGN_VECTOR                ] = PPC_EXC_CLASSIC,
305  [ ASM_PROG_VECTOR                 ] = PPC_EXC_CLASSIC,
306  [ ASM_FLOAT_VECTOR                ] = PPC_EXC_CLASSIC,
307  [ ASM_SYS_VECTOR                  ] = PPC_EXC_CLASSIC,
308  [ /* APU unavailable      */ 0x0b ] = PPC_EXC_CLASSIC,
309
310  [ ASM_60X_DLMISS_VECTOR           ] = PPC_EXC_CLASSIC,
311  [ ASM_60X_DSMISS_VECTOR           ] = PPC_EXC_CLASSIC,
312  [ ASM_60X_VEC_VECTOR              ] = PPC_EXC_CLASSIC,
313  [ ASM_60X_PERFMON_VECTOR          ] = PPC_EXC_CLASSIC,
314
315  [ /* emb FP data          */ 0x15 ] = PPC_EXC_CLASSIC,
316  [ /* emb FP round         */ 0x16 ] = PPC_EXC_CLASSIC,
317};
318
319ppc_raw_exception_category ppc_vector_is_valid(rtems_vector vector)
320{
321ppc_raw_exception_category rval = PPC_EXC_INVALID;
322
323        if ( vector > LAST_VALID_EXC )
324                return PPC_EXC_INVALID;
325
326     switch (current_ppc_cpu) {
327        case PPC_7400:
328            if ( ( rval = altivec_vector_is_valid(vector)) )
329                return rval;
330            /* else fall thru */
331        case PPC_750:
332                        rval = mpc_750_vector_categories[vector];
333            break;
334        case PPC_7455:   /* Kate Feng */
335        case PPC_7457: 
336            if ( ( rval = altivec_vector_is_valid(vector) ) )
337                return rval;
338            /* else fall thru */
339        case PPC_604:
340        case PPC_604e:
341        case PPC_604r:
342                        rval = mpc_604_vector_categories[vector];
343            break;
344        case PPC_603:
345        case PPC_603e:
346        case PPC_603le:
347        case PPC_603ev:
348        case PPC_8260:
349        /* case PPC_8240: -- same value as 8260 */
350        case PPC_8245:
351                        rval = mpc_603_vector_categories[vector];
352            break;
353        case PPC_e300c1:
354        case PPC_e300c2:
355        case PPC_e300c3:
356                        rval = e300_vector_categories[vector];
357            break;
358        case PPC_PSIM:
359                        rval = psim_vector_categories[vector];
360            break;
361        case PPC_8540:
362                        rval = e500_vector_categories[vector];
363            break;
364        case PPC_e200z6:
365                        rval = e200_vector_categories[vector];
366            break;
367        case PPC_5XX:
368                        rval = mpc_5xx_vector_categories[vector];
369            break;
370        case PPC_860:
371                        rval = mpc_860_vector_categories[vector];
372            break;
373        case PPC_405:
374                        rval = ppc_405_vector_categories[vector];
375            break;
376        default:
377            printk("Please complete "
378                   "libcpu/powerpc/new-exceptions/raw_exception.c\n"
379                   "current_ppc_cpu = %x\n", current_ppc_cpu);
380            return PPC_EXC_INVALID;
381     }
382     return rval;
383}
384
385int ppc_set_exception  (const rtems_raw_except_connect_data* except)
386{
387    rtems_interrupt_level k;
388
389    if ( PPC_EXC_INVALID == ppc_vector_is_valid(except->hdl.vector) ) {
390      printk("ppc_set_exception: vector %d is not valid\n",
391              except->hdl.vector);
392      return 0;
393    }
394    /*
395     * Check if default handler is actually connected. If not issue an error.
396     * You must first get the current handler via mpc60x_get_current_exception
397     * and then disconnect it using mpc60x_delete_exception.
398     * RATIONALE : to always have the same transition by forcing the user
399     * to get the previous handler before accepting to disconnect.
400     */
401
402    if (memcmp(ppc_get_vector_addr(except->hdl.vector),
403               (void*)default_raw_except_entry.hdl.raw_hdl,
404               default_raw_except_entry.hdl.raw_hdl_size)) {
405      printk("ppc_set_exception: raw vector not installed\n");
406      return 0;
407    }
408
409    rtems_interrupt_disable(k);
410
411    raw_except_table [except->exceptIndex] = *except;
412    codemove(ppc_get_vector_addr(except->hdl.vector),
413             except->hdl.raw_hdl,
414             except->hdl.raw_hdl_size,
415             PPC_CACHE_ALIGNMENT);
416        if (except->on)
417        except->on(except);
418
419    rtems_interrupt_enable(k);
420    return 1;
421}
422
423int ppc_get_current_exception (rtems_raw_except_connect_data* except)
424{
425        rtems_interrupt_level k;
426        int i;
427
428        if ( PPC_EXC_INVALID == ppc_vector_is_valid(except->hdl.vector) ) {
429                return 0;
430        }
431
432        for (i=0; i < local_settings->exceptSize; i++) {
433                if ( raw_except_table[i].hdl.vector == except->hdl.vector ) {
434                        rtems_interrupt_disable(k);
435                                if ( raw_except_table[i].hdl.vector == except->hdl.vector ) {
436                                        *except = raw_except_table[i]; 
437                                        rtems_interrupt_enable(k);
438                                        return 1;
439                                }
440                        rtems_interrupt_enable(k);
441                }
442        }
443
444        return 0;
445}
446
447int ppc_delete_exception (const rtems_raw_except_connect_data* except)
448{
449  rtems_interrupt_level k;
450
451  if ( PPC_EXC_INVALID == ppc_vector_is_valid(except->hdl.vector) ) {
452    return 0;
453  }
454  /*
455   * Check if handler passed is actually connected. If not issue an error.
456   * You must first get the current handler via ppc_get_current_exception
457   * and then disconnect it using ppc_delete_exception.
458   * RATIONALE : to always have the same transition by forcing the user
459   * to get the previous handler before accepting to disconnect.
460   */
461  if (memcmp(ppc_get_vector_addr(except->hdl.vector),
462             (void*)except->hdl.raw_hdl,
463             except->hdl.raw_hdl_size)) {
464      return 0;
465  }
466  rtems_interrupt_disable(k);
467
468  if (except->off)
469          except->off(except);
470  codemove(ppc_get_vector_addr(except->hdl.vector),
471           default_raw_except_entry.hdl.raw_hdl,
472           default_raw_except_entry.hdl.raw_hdl_size,
473           PPC_CACHE_ALIGNMENT);
474
475
476  raw_except_table[except->exceptIndex] = default_raw_except_entry;
477  raw_except_table[except->exceptIndex].exceptIndex = except->exceptIndex;
478  raw_except_table[except->exceptIndex].hdl.vector  = except->hdl.vector;
479
480  rtems_interrupt_enable(k);
481
482  return 1;
483}
484
485/*
486 * Exception global init.
487 */
488int ppc_init_exceptions (rtems_raw_except_global_settings* config)
489{
490        rtems_interrupt_level k;
491    int                   i;
492        unsigned              c;
493
494    /*
495     * store various accelerators
496     */
497    raw_except_table            = config->rawExceptHdlTbl;
498    local_settings              = config;
499    default_raw_except_entry    = config->defaultRawEntry;
500
501    rtems_interrupt_disable(k);
502
503        /* FIXME special case selection method */
504        if (current_ppc_cpu == PPC_e200z6) {
505                e200_setup_raw_exceptions();
506        } else if ( (c = ppc_cpu_is_bookE()) && PPC_BOOKE_405 != c ) {
507                e500_setup_raw_exceptions();
508        }
509
510        /* Need to support libbsp/powerpc/shared/vectors.S
511         * (hopefully this can go away some day)
512         * We also rely on LAST_VALID_EXC < 32
513         */
514        for ( i=0; i <= LAST_VALID_EXC; i++ ) {
515                if ( PPC_EXC_405_CRITICAL == (ppc_vector_is_valid( i ) & ~PPC_EXC_ASYNC) )
516                        bsp_raw_vector_is_405_critical |= (1<<i);
517        }
518
519        for (i=0; i < config->exceptSize; i++) {
520                if ( PPC_EXC_INVALID == ppc_vector_is_valid(raw_except_table[i].hdl.vector) ) {
521                        continue;
522                }
523                codemove(ppc_get_vector_addr(raw_except_table[i].hdl.vector),
524                                raw_except_table[i].hdl.raw_hdl,
525                                raw_except_table[i].hdl.raw_hdl_size,
526                                PPC_CACHE_ALIGNMENT);
527                if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) {
528                        if (raw_except_table[i].on)
529                                raw_except_table[i].on(&raw_except_table[i]);
530                }
531                else {
532                        if (raw_except_table[i].off)
533                                raw_except_table[i].off(&raw_except_table[i]);
534                }
535        }
536    rtems_interrupt_enable(k);
537
538    return 1;
539}
540
541int ppc_get_exception_config (rtems_raw_except_global_settings** config)
542{
543  *config = local_settings;
544  return 1;
545}
Note: See TracBrowser for help on using the repository browser.