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

4.104.114.84.95
Last change on this file since 862c2317 was 862c2317, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 07/04/07 at 12:37:36

added virtex BSP support and some missing files for common PPC
exception handling

  • Property mode set to 100644
File size: 12.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/system.h>
28#include <rtems/score/powerpc.h>
29#include <rtems/bspIo.h>
30#include <libcpu/raw_exception.h>
31#include <libcpu/cpuIdent.h>
32
33#include <string.h>
34
35static rtems_raw_except_connect_data*           raw_except_table;
36static rtems_raw_except_connect_data            default_raw_except_entry;
37static rtems_raw_except_global_settings*        local_settings;
38
39void * codemove(void *, const void *, unsigned int, unsigned long);
40
41
42static void* ppc_get_vector_addr(rtems_vector vector)
43{
44  unsigned vaddr;
45  extern rtems_cpu_table Cpu_table;
46
47  switch(vector) {
48    /*
49     * some vectors are located at odd addresses and only available
50     * on some CPU derivates. this construct will handle them
51     * if available
52     */
53#if defined(PPC_HAS_60X_VECTORS)
54  /* Special case; altivec unavailable doesn't fit :-( */
55  case ASM_VEC_VECTOR:
56    vaddr = ASM_VEC_VECTOR_OFFSET;
57    break;
58#endif
59#if defined(ASM_PIT_VECTOR)
60  case ASM_PIT_VECTOR:
61    vaddr = ASM_PIT_VECTOR_OFFSET;
62    break;
63#endif
64#if defined(ASM_FIT_VECTOR)
65  case ASM_FIT_VECTOR:
66    vaddr = ASM_FIT_VECTOR_OFFSET;
67    break;
68#endif
69#if defined(ASM_WDOG_VECTOR)
70  case ASM_WDOG_VECTOR:
71    vaddr = ASM_WDOG_VECTOR_OFFSET;
72    break;
73#endif
74  default:
75    vaddr = ((unsigned)vector) << 8;
76    break;
77  }
78  if ( Cpu_table.exceptions_in_RAM )
79    return ((void*)  vaddr);
80
81  return ((void*)  (vaddr + 0xfff00000));
82}
83
84
85#if ( defined(mpc860) || defined(mpc821) )
86
87int mpc860_vector_is_valid(rtems_vector vector)
88{
89  switch(vector) {
90  case ASM_RESET_VECTOR: /* fall through */
91  case ASM_MACH_VECTOR:
92  case ASM_PROT_VECTOR:
93  case ASM_ISI_VECTOR:
94  case ASM_EXT_VECTOR:
95  case ASM_ALIGN_VECTOR:
96  case ASM_PROG_VECTOR:
97  case ASM_FLOAT_VECTOR:
98  case ASM_DEC_VECTOR:
99   
100  case ASM_SYS_VECTOR:
101  case ASM_TRACE_VECTOR:
102  case ASM_FLOATASSIST_VECTOR:
103
104  case ASM_SOFTEMUL_VECTOR:
105  case ASM_ITLBMISS_VECTOR:
106  case ASM_DTLBMISS_VECTOR:
107  case ASM_ITLBERROR_VECTOR:
108  case ASM_DTLBERROR_VECTOR:
109
110  case ASM_DBREAK_VECTOR:
111  case ASM_IBREAK_VECTOR:
112  case ASM_PERIFBREAK_VECTOR:
113  case ASM_DEVPORT_VECTOR:
114    return 1;
115  default: return 0;
116  }
117}
118#endif
119
120#if (defined(mpc555) || defined(mpc505))
121
122int ppc_vector_is_valid(rtems_vector vector)
123{
124  switch (current_ppc_cpu) {
125    case PPC_5XX:
126      switch(vector) {
127        case ASM_RESET_VECTOR:
128        case ASM_MACH_VECTOR:
129
130        case ASM_EXT_VECTOR:
131        case ASM_ALIGN_VECTOR:
132        case ASM_PROG_VECTOR:
133        case ASM_FLOAT_VECTOR:
134        case ASM_DEC_VECTOR:
135
136        case ASM_SYS_VECTOR:
137        case ASM_TRACE_VECTOR:
138        case ASM_FLOATASSIST_VECTOR:
139
140        case ASM_SOFTEMUL_VECTOR:
141
142        case ASM_IPROT_VECTOR:
143        case ASM_DPROT_VECTOR:
144
145        case ASM_DBREAK_VECTOR:
146        case ASM_IBREAK_VECTOR:
147        case ASM_MEBREAK_VECTOR:
148        case ASM_NMEBREAK_VECTOR:
149          return 1;
150        default:
151          return 0;
152      }
153    default:
154      printk("Please complete libcpu/powerpc/shared/new-exceptions/raw_exception.c\n");
155      printk("current_ppc_cpu = %x\n", current_ppc_cpu);
156      return 0;
157  }
158}
159#endif
160
161#if defined(ppc405)
162int ppc405_vector_is_valid(rtems_vector vector)
163
164{
165  switch(vector) {
166  case ASM_RESET_VECTOR: /* fall through */
167  case ASM_MACH_VECTOR:
168  case ASM_PROT_VECTOR:
169  case ASM_ISI_VECTOR:
170  case ASM_EXT_VECTOR:
171  case ASM_ALIGN_VECTOR:
172  case ASM_PROG_VECTOR:
173  case ASM_SYS_VECTOR:
174  case ASM_PIT_VECTOR:
175  case ASM_ITLBMISS_VECTOR:
176  case ASM_DTLBMISS_VECTOR:
177    return 1;
178  default: return 0;
179  }
180}
181#endif /* defined(ppc405) */
182
183#if defined(PPC_HAS_60X_VECTORS) /* 60x style cpu types */
184
185int altivec_vector_is_valid(rtems_vector vector)
186{
187  switch(vector) {
188  case ASM_VEC_VECTOR:
189  case ASM_VEC_ASSIST_VECTOR:
190    return 1;
191    default:
192      break;
193  }
194  return 0;
195}
196
197int mpc750_vector_is_valid(rtems_vector vector)
198
199{
200  switch(vector) {
201  case ASM_RESET_VECTOR: /* fall through */
202  case ASM_MACH_VECTOR:
203  case ASM_PROT_VECTOR:
204  case ASM_ISI_VECTOR:
205  case ASM_EXT_VECTOR:
206  case ASM_ALIGN_VECTOR:
207  case ASM_PROG_VECTOR:
208  case ASM_FLOAT_VECTOR:
209  case ASM_DEC_VECTOR:
210  case ASM_SYS_VECTOR:
211  case ASM_TRACE_VECTOR:
212  case ASM_ADDR_VECTOR:
213  case ASM_SYSMGMT_VECTOR:
214  case ASM_ITM_VECTOR:
215    return 1;
216  default: return 0;
217  }
218}
219
220int PSIM_vector_is_valid(rtems_vector vector)
221{
222  switch(vector) {
223  case ASM_RESET_VECTOR: /* fall through */
224  case ASM_MACH_VECTOR:
225  case ASM_PROT_VECTOR:
226  case ASM_ISI_VECTOR:
227  case ASM_EXT_VECTOR:
228  case ASM_ALIGN_VECTOR:
229  case ASM_PROG_VECTOR:
230  case ASM_FLOAT_VECTOR:
231  case ASM_DEC_VECTOR:
232    return 1;
233  case ASM_SYS_VECTOR:
234    return 0;
235  case ASM_TRACE_VECTOR:
236    return 1;
237  case ASM_PERFMON_VECTOR:
238    return 0;
239  case ASM_IMISS_VECTOR: /* fall through */
240  case ASM_DLMISS_VECTOR:
241  case ASM_DSMISS_VECTOR:
242  case ASM_ADDR_VECTOR:
243  case ASM_SYSMGMT_VECTOR:
244    return 1;
245  case ASM_ITM_VECTOR:
246    return 0;
247  }
248  return 0;
249}
250
251int mpc603_vector_is_valid(rtems_vector vector)
252{
253  switch(vector) {
254  case ASM_RESET_VECTOR: /* fall through */
255  case ASM_MACH_VECTOR:
256  case ASM_PROT_VECTOR:
257  case ASM_ISI_VECTOR:
258  case ASM_EXT_VECTOR:
259  case ASM_ALIGN_VECTOR:
260  case ASM_PROG_VECTOR:
261  case ASM_FLOAT_VECTOR:
262  case ASM_DEC_VECTOR:
263  case ASM_SYS_VECTOR:
264  case ASM_TRACE_VECTOR:
265    return 1;
266  case ASM_PERFMON_VECTOR:
267    return 0;
268  case ASM_IMISS_VECTOR: /* fall through */
269  case ASM_DLMISS_VECTOR:
270  case ASM_DSMISS_VECTOR:
271  case ASM_ADDR_VECTOR:
272  case ASM_SYSMGMT_VECTOR:
273    return 1;
274  case ASM_ITM_VECTOR:
275    return 0;
276  }
277  return 0;
278}
279
280int mpc604_vector_is_valid(rtems_vector vector)
281{
282  switch(vector) {
283  case ASM_RESET_VECTOR: /* fall through */
284  case ASM_MACH_VECTOR:
285  case ASM_PROT_VECTOR:
286  case ASM_ISI_VECTOR:
287  case ASM_EXT_VECTOR:
288  case ASM_ALIGN_VECTOR:
289  case ASM_PROG_VECTOR:
290  case ASM_FLOAT_VECTOR:
291  case ASM_DEC_VECTOR:
292  case ASM_SYS_VECTOR:
293  case ASM_TRACE_VECTOR:
294  case ASM_PERFMON_VECTOR:
295    return 1;
296  case ASM_IMISS_VECTOR: /* fall through */
297  case ASM_DLMISS_VECTOR:
298  case ASM_DSMISS_VECTOR:
299    return 0;
300  case ASM_ADDR_VECTOR: /* fall through */
301  case ASM_SYSMGMT_VECTOR:
302    return 1;
303  case ASM_ITM_VECTOR:
304    return 0;
305  }
306  return 0;
307}
308
309#endif /* 60x style cpu types */
310
311int ppc_vector_is_valid(rtems_vector vector)
312{
313     switch (current_ppc_cpu) {
314#if defined(PPC_HAS_60X_VECTORS)
315        case PPC_7400:
316            if ( altivec_vector_is_valid(vector) )
317                return 1;
318            /* else fall thru */
319        case PPC_750:
320            if (!mpc750_vector_is_valid(vector)) {
321                return 0;
322            }
323            break;
324        case PPC_7455:   /* Kate Feng */
325        case PPC_7457:
326            if ( altivec_vector_is_valid(vector) )
327                return 1;
328            /* else fall thru */
329        case PPC_604:
330        case PPC_604e:
331        case PPC_604r:
332            if (!mpc604_vector_is_valid(vector)) {
333                return 0;
334            }
335            break;
336        case PPC_603:
337        case PPC_603e:
338        case PPC_603le:
339        case PPC_603ev:
340        case PPC_8260:
341        /* case PPC_8240: -- same value as 8260 */
342        case PPC_8245:
343            if (!mpc603_vector_is_valid(vector)) {
344                return 0;
345            }
346            break;
347        case PPC_PSIM:
348            if (!PSIM_vector_is_valid(vector)) {
349                return 0;
350            }
351            break;
352#endif
353#if ( defined(mpc860) || defined(mpc821) )
354        case PPC_860:
355            if (!mpc860_vector_is_valid(vector)) {
356                return 0;
357            }
358            break;
359#endif
360#if defined(ppc405)
361        case PPC_405:
362            if (!ppc405_vector_is_valid(vector)) {
363                return 0;
364            }
365            break;
366#endif
367        default:
368            printk("Please complete "
369                   "libcpu/powerpc/new-exceptions/raw_exception.c\n"
370                   "current_ppc_cpu = %x\n", current_ppc_cpu);
371            return 0;
372     }
373     return 1;
374}
375
376int ppc_set_exception  (const rtems_raw_except_connect_data* except)
377{
378    unsigned int level;
379
380    if (!ppc_vector_is_valid(except->exceptIndex)) {
381      printk("ppc_set_exception: vector %d is not valid\n",
382              except->exceptIndex);
383      return 0;
384    }
385    /*
386     * Check if default handler is actually connected. If not issue an error.
387     * You must first get the current handler via mpc60x_get_current_exception
388     * and then disconnect it using mpc60x_delete_exception.
389     * RATIONALE : to always have the same transition by forcing the user
390     * to get the previous handler before accepting to disconnect.
391     */
392
393    if (memcmp(ppc_get_vector_addr(except->exceptIndex),
394               (void*)default_raw_except_entry.hdl.raw_hdl,
395               default_raw_except_entry.hdl.raw_hdl_size)) {
396      printk("ppc_set_exception: raw vector not installed\n");
397      return 0;
398    }
399
400    _CPU_ISR_Disable(level);
401
402    raw_except_table [except->exceptIndex] = *except;
403    codemove((void*)ppc_get_vector_addr(except->exceptIndex),
404             except->hdl.raw_hdl,
405             except->hdl.raw_hdl_size,
406             PPC_CACHE_ALIGNMENT);
407    except->on(except);
408
409    _CPU_ISR_Enable(level);
410    return 1;
411}
412
413int ppc_get_current_exception (rtems_raw_except_connect_data* except)
414{
415  if (!ppc_vector_is_valid(except->exceptIndex)){
416    return 0;
417  }
418
419  *except = raw_except_table [except->exceptIndex];
420
421  return 1;
422}
423
424int ppc_delete_exception (const rtems_raw_except_connect_data* except)
425{
426  unsigned int level;
427
428  if (!ppc_vector_is_valid(except->exceptIndex)){
429    return 0;
430  }
431  /*
432   * Check if handler passed is actually connected. If not issue an error.
433   * You must first get the current handler via ppc_get_current_exception
434   * and then disconnect it using ppc_delete_exception.
435   * RATIONALE : to always have the same transition by forcing the user
436   * to get the previous handler before accepting to disconnect.
437   */
438  if (memcmp(ppc_get_vector_addr(except->exceptIndex),
439             (void*)except->hdl.raw_hdl,
440             except->hdl.raw_hdl_size)) {
441      return 0;
442  }
443  _CPU_ISR_Disable(level);
444
445  except->off(except);
446  codemove((void*)ppc_get_vector_addr(except->exceptIndex),
447           default_raw_except_entry.hdl.raw_hdl,
448           default_raw_except_entry.hdl.raw_hdl_size,
449           PPC_CACHE_ALIGNMENT);
450
451
452  raw_except_table[except->exceptIndex] = default_raw_except_entry;
453  raw_except_table[except->exceptIndex].exceptIndex = except->exceptIndex;
454
455  _CPU_ISR_Enable(level);
456
457  return 1;
458}
459
460/*
461 * Exception global init.
462 */
463int ppc_init_exceptions (rtems_raw_except_global_settings* config)
464{
465    unsigned                    i;
466    unsigned int level;
467
468    /*
469     * store various accelerators
470     */
471    raw_except_table            = config->rawExceptHdlTbl;
472    local_settings              = config;
473    default_raw_except_entry    = config->defaultRawEntry;
474
475    _CPU_ISR_Disable(level);
476
477    for (i=0; i <= LAST_VALID_EXC; i++) {
478      if (!ppc_vector_is_valid(i)){
479        continue;
480      }
481      codemove((void*)ppc_get_vector_addr(i),
482             raw_except_table[i].hdl.raw_hdl,
483             raw_except_table[i].hdl.raw_hdl_size,
484             PPC_CACHE_ALIGNMENT);
485      if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) {
486        raw_except_table[i].on(&raw_except_table[i]);
487      }
488      else {
489        raw_except_table[i].off(&raw_except_table[i]);
490      }
491    }
492    _CPU_ISR_Enable(level);
493
494    return 1;
495}
496
497int ppc_get_exception_config (rtems_raw_except_global_settings** config)
498{
499  *config = local_settings;
500  return 1;
501}
Note: See TracBrowser for help on using the repository browser.