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

4.104.114.95
Last change on this file since 3c6fe2e was 3c6fe2e, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 07/14/08 at 08:46:06

added haleakala BSP contributed by Michael Hamel

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