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

4.104.114.95
Last change on this file since c4cc8199 was c4cc8199, checked in by Joel Sherrill <joel.sherrill@…>, on 11/28/07 at 21:45:06

2007-11-28 Joel Sherrill <joel.sherrill@…>

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