source: rtems/c/src/lib/libcpu/powerpc/mpc6xx/exceptions/raw_exception.c @ 261a1b2

4.104.114.84.95
Last change on this file since 261a1b2 was 261a1b2, checked in by Till Straumann <strauman@…>, on Jun 19, 2006 at 8:24:08 PM

Added altivec exception. Unfortunately, this doesn't fit
the normal scheme of vector = exception # << 8. So we picked
an unused vector number (currently 0xa) where we map the special
vector 0xf20 (altivec).

  • Property mode set to 100644
File size: 8.8 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 *  The license and distribution terms for this file may be
18 *  found in found in the file LICENSE in this distribution or at
19 *  http://www.rtems.com/license/LICENSE.
20 *
21 * $Id$
22 */
23#include <rtems/system.h>
24#include <rtems/score/powerpc.h>
25#include <rtems/bspIo.h>
26#include <libcpu/raw_exception.h>
27#include <libcpu/cpuIdent.h>
28
29#include <string.h>
30
31static rtems_raw_except_connect_data*           raw_except_table;
32static rtems_raw_except_connect_data            default_raw_except_entry;
33static rtems_raw_except_global_settings*        local_settings;
34
35void * codemove(void *, const void *, unsigned int, unsigned long);
36
37void* mpc60x_get_vector_addr(rtems_vector vector)
38{
39  unsigned vaddr = ((unsigned)vector) << 8;
40  extern rtems_cpu_table Cpu_table;
41
42  /* Special case; altivec unavailable doesn't fit :-( */
43  if ( ASM_VEC_VECTOR == vector )
44                vaddr = ASM_VEC_VECTOR_OFFSET;
45
46  if ( Cpu_table.exceptions_in_RAM )
47    return ((void*)  vaddr);
48
49  return ((void*)  (vaddr + 0xfff00000));
50}
51
52int altivec_vector_is_valid(rtems_vector vector)
53{
54  switch(vector) {
55  case ASM_VEC_VECTOR:
56  case ASM_VEC_ASSIST_VECTOR:
57    return 1;
58    default:
59      break;
60  }
61  return 0;
62}
63
64int mpc750_vector_is_valid(rtems_vector vector)
65
66{
67  switch(vector) {
68  case ASM_RESET_VECTOR: /* fall through */
69  case ASM_MACH_VECTOR:
70  case ASM_PROT_VECTOR:
71  case ASM_ISI_VECTOR:
72  case ASM_EXT_VECTOR:
73  case ASM_ALIGN_VECTOR:
74  case ASM_PROG_VECTOR:
75  case ASM_FLOAT_VECTOR:
76  case ASM_DEC_VECTOR:
77  case ASM_SYS_VECTOR:
78  case ASM_TRACE_VECTOR:
79  case ASM_ADDR_VECTOR:
80  case ASM_SYSMGMT_VECTOR:
81  case ASM_ITM_VECTOR:
82    return 1;
83  default: return 0;
84  }
85}
86
87int PSIM_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    return 1;
100  case ASM_SYS_VECTOR:
101    return 0;
102  case ASM_TRACE_VECTOR:
103    return 1;
104  case ASM_PERFMON_VECTOR:
105    return 0;
106  case ASM_IMISS_VECTOR: /* fall through */
107  case ASM_DLMISS_VECTOR:
108  case ASM_DSMISS_VECTOR:
109  case ASM_ADDR_VECTOR:
110  case ASM_SYSMGMT_VECTOR:
111    return 1;
112  case ASM_ITM_VECTOR:
113    return 0;
114  }
115  return 0;
116}
117
118int mpc603_vector_is_valid(rtems_vector vector)
119{
120  switch(vector) {
121  case ASM_RESET_VECTOR: /* fall through */
122  case ASM_MACH_VECTOR:
123  case ASM_PROT_VECTOR:
124  case ASM_ISI_VECTOR:
125  case ASM_EXT_VECTOR:
126  case ASM_ALIGN_VECTOR:
127  case ASM_PROG_VECTOR:
128  case ASM_FLOAT_VECTOR:
129  case ASM_DEC_VECTOR:
130  case ASM_SYS_VECTOR:
131  case ASM_TRACE_VECTOR:
132    return 1;
133  case ASM_PERFMON_VECTOR:
134    return 0;
135  case ASM_IMISS_VECTOR: /* fall through */
136  case ASM_DLMISS_VECTOR:
137  case ASM_DSMISS_VECTOR:
138  case ASM_ADDR_VECTOR:
139  case ASM_SYSMGMT_VECTOR:
140    return 1;
141  case ASM_ITM_VECTOR:
142    return 0;
143  }
144  return 0;
145}
146
147int mpc604_vector_is_valid(rtems_vector vector)
148{
149  switch(vector) {
150  case ASM_RESET_VECTOR: /* fall through */
151  case ASM_MACH_VECTOR:
152  case ASM_PROT_VECTOR:
153  case ASM_ISI_VECTOR:
154  case ASM_EXT_VECTOR:
155  case ASM_ALIGN_VECTOR:
156  case ASM_PROG_VECTOR:
157  case ASM_FLOAT_VECTOR:
158  case ASM_DEC_VECTOR:
159  case ASM_SYS_VECTOR:
160  case ASM_TRACE_VECTOR:
161  case ASM_PERFMON_VECTOR:
162    return 1;
163  case ASM_IMISS_VECTOR: /* fall through */
164  case ASM_DLMISS_VECTOR:
165  case ASM_DSMISS_VECTOR:
166    return 0;
167  case ASM_ADDR_VECTOR: /* fall through */
168  case ASM_SYSMGMT_VECTOR:
169    return 1;
170  case ASM_ITM_VECTOR:
171    return 0;
172  }
173  return 0;
174}
175
176int mpc60x_vector_is_valid(rtems_vector vector)
177{
178     switch (current_ppc_cpu) {
179        case PPC_7400:
180            if ( altivec_vector_is_valid(vector) )
181                return 1;
182            /* else fall thru */
183        case PPC_750:
184            if (!mpc750_vector_is_valid(vector)) {
185                return 0;
186            }
187            break;
188        case PPC_7455:   /* Kate Feng */
189        case PPC_7457: 
190            if ( altivec_vector_is_valid(vector) )
191                return 1;
192            /* else fall thru */
193        case PPC_604:
194        case PPC_604e:
195        case PPC_604r:
196            if (!mpc604_vector_is_valid(vector)) {
197                return 0;
198            }
199            break;
200        case PPC_603:
201        case PPC_603e:
202        case PPC_603le:
203        case PPC_603ev:
204        case PPC_8260:
205        /* case PPC_8240: -- same value as 8260 */
206        case PPC_8245:
207            if (!mpc603_vector_is_valid(vector)) {
208                return 0;
209            }
210            break;
211        case PPC_PSIM:
212            if (!PSIM_vector_is_valid(vector)) {
213                return 0;
214            }
215            break;
216         default:
217            printk("Please complete "
218                   "libcpu/powerpc/mpc6xx/exceptions/raw_exception.c\n"
219                   "current_ppc_cpu = %x\n", current_ppc_cpu);
220            return 0;
221     }
222     return 1;
223}
224
225int mpc60x_set_exception  (const rtems_raw_except_connect_data* except)
226{
227    unsigned int level;
228
229    if (!mpc60x_vector_is_valid(except->exceptIndex)) {
230      printk("mpc60x_set_exception: vector %d is not valid\n",
231              except->exceptIndex);
232      return 0;
233    }
234    /*
235     * Check if default handler is actually connected. If not issue an error.
236     * You must first get the current handler via mpc60x_get_current_exception
237     * and then disconnect it using mpc60x_delete_exception.
238     * RATIONALE : to always have the same transition by forcing the user
239     * to get the previous handler before accepting to disconnect.
240     */
241
242    if (memcmp(mpc60x_get_vector_addr(except->exceptIndex),
243               (void*)default_raw_except_entry.hdl.raw_hdl,
244               default_raw_except_entry.hdl.raw_hdl_size)) {
245      printk("mpc60x_set_exception: raw vector not installed\n");
246      return 0;
247    }
248
249    _CPU_ISR_Disable(level);
250
251    raw_except_table [except->exceptIndex] = *except;
252    codemove((void*)mpc60x_get_vector_addr(except->exceptIndex),
253             except->hdl.raw_hdl,
254             except->hdl.raw_hdl_size,
255             PPC_CACHE_ALIGNMENT);
256    except->on(except);
257
258    _CPU_ISR_Enable(level);
259    return 1;
260}
261
262int mpc60x_get_current_exception (rtems_raw_except_connect_data* except)
263{
264  if (!mpc60x_vector_is_valid(except->exceptIndex)){
265    return 0;
266  }
267
268  *except = raw_except_table [except->exceptIndex];
269
270  return 1;
271}
272
273int mpc60x_delete_exception (const rtems_raw_except_connect_data* except)
274{
275  unsigned int level;
276
277  if (!mpc60x_vector_is_valid(except->exceptIndex)){
278    return 0;
279  }
280  /*
281   * Check if handler passed is actually connected. If not issue an error.
282   * You must first get the current handler via mpc60x_get_current_exception
283   * and then disconnect it using mpc60x_delete_exception.
284   * RATIONALE : to always have the same transition by forcing the user
285   * to get the previous handler before accepting to disconnect.
286   */
287  if (memcmp(mpc60x_get_vector_addr(except->exceptIndex),
288             (void*)except->hdl.raw_hdl,
289             except->hdl.raw_hdl_size)) {
290      return 0;
291  }
292  _CPU_ISR_Disable(level);
293
294  except->off(except);
295  codemove((void*)mpc60x_get_vector_addr(except->exceptIndex),
296           default_raw_except_entry.hdl.raw_hdl,
297           default_raw_except_entry.hdl.raw_hdl_size,
298           PPC_CACHE_ALIGNMENT);
299
300
301  raw_except_table[except->exceptIndex] = default_raw_except_entry;
302  raw_except_table[except->exceptIndex].exceptIndex = except->exceptIndex;
303
304  _CPU_ISR_Enable(level);
305
306  return 1;
307}
308
309/*
310 * Exception global init.
311 */
312int mpc60x_init_exceptions (rtems_raw_except_global_settings* config)
313{
314    unsigned                    i;
315    unsigned int level;
316
317    /*
318     * store various accelerators
319     */
320    raw_except_table            = config->rawExceptHdlTbl;
321    local_settings              = config;
322    default_raw_except_entry    = config->defaultRawEntry;
323
324    _CPU_ISR_Disable(level);
325
326    for (i=0; i <= LAST_VALID_EXC; i++) {
327      if (!mpc60x_vector_is_valid(i)){
328        continue;
329      }
330      codemove((void*)mpc60x_get_vector_addr(i),
331             raw_except_table[i].hdl.raw_hdl,
332             raw_except_table[i].hdl.raw_hdl_size,
333             PPC_CACHE_ALIGNMENT);
334      if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) {
335        raw_except_table[i].on(&raw_except_table[i]);
336      }
337      else {
338        raw_except_table[i].off(&raw_except_table[i]);
339      }
340    }
341    _CPU_ISR_Enable(level);
342
343    return 1;
344}
345
346int mpc60x_get_exception_config (rtems_raw_except_global_settings** config)
347{
348  *config = local_settings;
349  return 1;
350}
Note: See TracBrowser for help on using the repository browser.