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

4.104.114.84.95
Last change on this file since f93630d was f93630d, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 12, 2007 at 3:23:44 PM

2007-09-12 Joel Sherrill <joel.sherrill@…>

PR 1257/bsps

  • mpc5xx/exceptions/raw_exception.c, mpc5xx/irq/irq.c, mpc6xx/exceptions/raw_exception.c, mpc8260/exceptions/raw_exception.c, mpc8xx/exceptions/raw_exception.c, new-exceptions/raw_exception.c, ppc403/ictrl/ictrl.c, ppc403/irq/ictrl.c: Code outside of cpukit should use the public API for rtems_interrupt_disable/rtems_interrupt_enable. By bypassing the public API and directly accessing _CPU_ISR_Disable and _CPU_ISR_Enable, they were bypassing the compiler memory barrier directive which could lead to problems. This patch also changes the type of the variable passed into these routines and addresses minor style issues.
  • Property mode set to 100644
File size: 12.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/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 rtems_cpu_table Cpu_table;
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 ( Cpu_table.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    except->on(except);
419
420    _ISR_Enable(level);
421    return 1;
422}
423
424int ppc_get_current_exception (rtems_raw_except_connect_data* except)
425{
426  if (!ppc_vector_is_valid(except->exceptIndex)){
427    return 0;
428  }
429
430  *except = raw_except_table [except->exceptIndex];
431
432  return 1;
433}
434
435int ppc_delete_exception (const rtems_raw_except_connect_data* except)
436{
437  ISR_Level level;
438
439  if (!ppc_vector_is_valid(except->exceptIndex)){
440    return 0;
441  }
442  /*
443   * Check if handler passed is actually connected. If not issue an error.
444   * You must first get the current handler via ppc_get_current_exception
445   * and then disconnect it using ppc_delete_exception.
446   * RATIONALE : to always have the same transition by forcing the user
447   * to get the previous handler before accepting to disconnect.
448   */
449  if (memcmp(ppc_get_vector_addr(except->exceptIndex),
450             (void*)except->hdl.raw_hdl,
451             except->hdl.raw_hdl_size)) {
452      return 0;
453  }
454  _ISR_Disable(level);
455
456  except->off(except);
457  codemove((void*)ppc_get_vector_addr(except->exceptIndex),
458           default_raw_except_entry.hdl.raw_hdl,
459           default_raw_except_entry.hdl.raw_hdl_size,
460           PPC_CACHE_ALIGNMENT);
461
462
463  raw_except_table[except->exceptIndex] = default_raw_except_entry;
464  raw_except_table[except->exceptIndex].exceptIndex = except->exceptIndex;
465
466  _ISR_Enable(level);
467
468  return 1;
469}
470
471/*
472 * Exception global init.
473 */
474int ppc_init_exceptions (rtems_raw_except_global_settings* config)
475{
476    int        i;
477    ISR_Level  level;
478
479    /*
480     * store various accelerators
481     */
482    raw_except_table            = config->rawExceptHdlTbl;
483    local_settings              = config;
484    default_raw_except_entry    = config->defaultRawEntry;
485
486    _ISR_Disable(level);
487
488    for (i=0; i <= LAST_VALID_EXC; i++) {
489      if (!ppc_vector_is_valid(i)){
490        continue;
491      }
492      codemove((void*)ppc_get_vector_addr(i),
493             raw_except_table[i].hdl.raw_hdl,
494             raw_except_table[i].hdl.raw_hdl_size,
495             PPC_CACHE_ALIGNMENT);
496      if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) {
497        raw_except_table[i].on(&raw_except_table[i]);
498      }
499      else {
500        raw_except_table[i].off(&raw_except_table[i]);
501      }
502    }
503    _ISR_Enable(level);
504
505    return 1;
506}
507
508int ppc_get_exception_config (rtems_raw_except_global_settings** config)
509{
510  *config = local_settings;
511  return 1;
512}
Note: See TracBrowser for help on using the repository browser.