source: rtems/c/src/lib/libcpu/powerpc/mpc6xx/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: 8.9 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    rtems_interrupt_level       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    rtems_interrupt_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    rtems_interrupt_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  rtems_interrupt_level 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  rtems_interrupt_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  rtems_interrupt_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    int                    i;
315    rtems_interrupt_level  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    rtems_interrupt_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    rtems_interrupt_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.