source: rtems/c/src/lib/libbsp/m68k/uC5282/startup/bspstart.c @ 4c5212e

4.104.115
Last change on this file since 4c5212e was 4c5212e, checked in by Joel Sherrill <joel.sherrill@…>, on 09/16/08 at 22:16:26

2008-09-16 Joel Sherrill <joel.sherrill@…>

  • Makefile.am, startup/bspstart.c, startup/linkcmds: Use top level shared bsp_get_work_area() implementation.
  • Property mode set to 100644
File size: 20.2 KB
RevLine 
[572484f]1/*
2 *  BSP startup
3 *
4 *  This routine starts the application.  It includes application,
5 *  board, and monitor specific initialization and configuration.
6 *  The generic CPU dependent initialization has been performed
7 *  before this routine is invoked.
8 *
[12b36efe]9 *  Author: W. Eric Norum <norume@aps.anl.gov>
[572484f]10 *
[12b36efe]11 *  COPYRIGHT (c) 2005.
[572484f]12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
[688696e4]16 *  http://www.rtems.com/license/LICENSE.
[572484f]17 *
18 *  $Id$
19 */
20
21#include <bsp.h>
[e846fc9]22#include <rtems/error.h>
[7eab0f78]23#include <errno.h>
[572484f]24 
25/*
26 * Location of 'VME' access
27 */
28#define VME_ONE_BASE    0x30000000
29#define VME_TWO_BASE    0x31000000
30
[18aa55ee]31/*
32 * Linker Script Defined Variables
33 */
[4c5212e]34extern char RamSize[];
35extern char RamBase[];
[18aa55ee]36
[572484f]37/*
38 * CPU-space access
[cbb615b]39 * The NOP after writing the CACR is there to address the following issue as
40 * described in "Device Errata MCF5282DE", Rev. 1.7, 09/2004:
41 *
42 * 6 Possible Cache Corruption after Setting  CACR[CINV]
43 * 6.1 Description
44 * The cache on the MCF5282 was enhanced to function as a unified data and
45 * instruction cache, an instruction cache, or an operand cache.  The cache
46 * function and organization is controlled by the cache control register (CACR).
47 * The CINV (Bit 24 = cache invalidate) bit in the CACR causes a cache clear.
48 * If the cache is configured as a unified cache and the CINV bit is set, the
49 * scope of the cache clear is controlled by two other bits in the CACR,
50 * INVI (BIT 21 = CINV instruction cache only) and INVD (BIT 20 = CINV data
51 * cache only).  These bits allow the entire cache, just the instruction
52 * portion of the cache, or just the data portion of the cache to be cleared.
53 * If a write to the CACR is performed to clear the cache (CINV = BIT 24 set)
54 * and only a partial clear will be done (INVI = BIT 21 or INVD = BIT 20 set),
55 * then cache corruption may  occur.
56 *
57 * 6.2 Workaround
58 * All loads of the CACR that perform a cache clear operation (CINV = BIT 24)
59 * should be followed immediately by a NOP instruction.  This avoids the cache
60 * corruption problem.
61 * DATECODES AFFECTED: All
[572484f]62 */
[ac9bbe7]63#define m68k_set_cacr_nop(_cacr) asm volatile ("movec %0,%%cacr\n\tnop" : : "d" (_cacr))
64#define m68k_set_cacr(_cacr) asm volatile ("movec %0,%%cacr" : : "d" (_cacr))
[572484f]65#define m68k_set_acr0(_acr0) asm volatile ("movec %0,%%acr0" : : "d" (_acr0))
66#define m68k_set_acr1(_acr1) asm volatile ("movec %0,%%acr1" : : "d" (_acr1))
67
68/*
[d5fe91e]69 * Read/write copy of cache registers
[ac9bbe7]70 *   Split instruction/data or instruction-only
[572484f]71 *   Allow CPUSHL to invalidate a cache line
72 *   Enable buffered writes
73 *   No burst transfers on non-cacheable accesses
74 *   Default cache mode is *disabled* (cache only ACRx areas)
75 */
[d5fe91e]76uint32_t mcf5282_cacr_mode = MCF5XXX_CACR_CENB |
[ac9bbe7]77#ifndef RTEMS_MCF5282_BSP_ENABLE_DATA_CACHE
78                             MCF5XXX_CACR_DISD |
79#endif
[d5fe91e]80                             MCF5XXX_CACR_DBWE |
81                             MCF5XXX_CACR_DCM;
82uint32_t mcf5282_acr0_mode = 0;
83uint32_t mcf5282_acr1_mode = 0;
[572484f]84/*
85 * Cannot be frozen
86 */
87void _CPU_cache_freeze_data(void) {}
88void _CPU_cache_unfreeze_data(void) {}
89void _CPU_cache_freeze_instruction(void) {}
90void _CPU_cache_unfreeze_instruction(void) {}
91
92/*
93 * Write-through data cache -- flushes are unnecessary
94 */
95void _CPU_cache_flush_1_data_line(const void *d_addr) {}
96void _CPU_cache_flush_entire_data(void) {}
97
98void _CPU_cache_enable_instruction(void)
99{
100    rtems_interrupt_level level;
101
102    rtems_interrupt_disable(level);
[d5fe91e]103    mcf5282_cacr_mode &= ~MCF5XXX_CACR_DIDI;
104    m68k_set_cacr(mcf5282_cacr_mode);
[572484f]105    rtems_interrupt_enable(level);
106}
107
108void _CPU_cache_disable_instruction(void)
109{
110    rtems_interrupt_level level;
111
112    rtems_interrupt_disable(level);
[d5fe91e]113    mcf5282_cacr_mode |= MCF5XXX_CACR_DIDI;
114    m68k_set_cacr(mcf5282_cacr_mode);
[572484f]115    rtems_interrupt_enable(level);
116}
117
118void _CPU_cache_invalidate_entire_instruction(void)
119{
[ac9bbe7]120    m68k_set_cacr_nop(mcf5282_cacr_mode | MCF5XXX_CACR_CINV | MCF5XXX_CACR_INVI);
[572484f]121}
122
123void _CPU_cache_invalidate_1_instruction_line(const void *addr)
124{
[518edef]125    /*
126     * Top half of cache is I-space
127     */
128    addr = (void *)((int)addr | 0x400);
129    asm volatile ("cpushl %%bc,(%0)" :: "a" (addr));
[572484f]130}
131
132void _CPU_cache_enable_data(void)
133{
[ac9bbe7]134#ifdef RTEMS_MCF5282_BSP_ENABLE_DATA_CACHE
[572484f]135    rtems_interrupt_level level;
136
137    rtems_interrupt_disable(level);
[ac9bbe7]138    mcf5282_cacr_mode &= ~MCF5XXX_CACR_CENB;
[d5fe91e]139    m68k_set_cacr(mcf5282_cacr_mode);
[572484f]140    rtems_interrupt_enable(level);
[ac9bbe7]141#endif
[572484f]142}
143
144void _CPU_cache_disable_data(void)
145{
[ac9bbe7]146#ifdef RTEMS_MCF5282_BSP_ENABLE_DATA_CACHE
[572484f]147    rtems_interrupt_level level;
148
[518edef]149    rtems_interrupt_disable(level);
[572484f]150    rtems_interrupt_disable(level);
[ac9bbe7]151    mcf5282_cacr_mode |= MCF5XXX_CACR_CENB;
[d5fe91e]152    m68k_set_cacr(mcf5282_cacr_mode);
[572484f]153    rtems_interrupt_enable(level);
[ac9bbe7]154#endif
[572484f]155}
156
157void _CPU_cache_invalidate_entire_data(void)
158{
[ac9bbe7]159#ifdef RTEMS_MCF5282_BSP_ENABLE_DATA_CACHE
160    m68k_set_cacr_nop(mcf5282_cacr_mode | MCF5XXX_CACR_CINV | MCF5XXX_CACR_INVD);
161#endif
[572484f]162}
163
164void _CPU_cache_invalidate_1_data_line(const void *addr)
165{
[ac9bbe7]166#ifdef RTEMS_MCF5282_BSP_ENABLE_DATA_CACHE
[518edef]167    /*
168     * Bottom half of cache is D-space
169     */
170    addr = (void *)((int)addr & ~0x400);
171    asm volatile ("cpushl %%bc,(%0)" :: "a" (addr));
[ac9bbe7]172#endif
[572484f]173}
174
[e846fc9]175/*
176 * The Arcturus boot ROM prints exception information improperly
177 * so use this default exception handler instead.  This one also
178 * prints a call backtrace
179 */
180static void handler(int pc)
181{
182    int level;
183    static volatile int reent;
184
185    rtems_interrupt_disable(level);
186    if (reent++) bsp_reset(0);
187    {
188    int *p = &pc;
189    int info = p[-1];
190    int pc = p[0];
191    int format = (info >> 28) & 0xF;
192    int faultStatus = ((info >> 24) & 0xC) | ((info >> 16) & 0x3);
193    int vector = (info >> 18) & 0xFF;
194    int statusRegister = info & 0xFFFF;
195    int *fp;
196
197    printk("\n\nPC:%x  SR:%x  VEC:%x  FORMAT:%x  STATUS:%x\n", pc,
198                                                               statusRegister,
199                                                               vector,
200                                                               format,
201                                                               faultStatus);
202    fp = &p[-2];
203    for(;;) {
204        int *nfp = (int *)*fp;
205        if ((nfp <= fp)
[4c5212e]206         || ((char *)nfp >= RamSize)
207         || ((char *)(nfp[1]) >= RamSize))
[e846fc9]208            break;
209        printk("FP:%x -> %x    PC:%x\n", fp, nfp, nfp[1]);
210        fp = nfp;
211    }
212    }
213    rtems_task_suspend(0);
214    rtems_panic("done");
215}
216
[572484f]217/*
218 *  bsp_start
219 *
220 *  This routine does the bulk of the system initialisation.
221 */
222void bsp_start( void )
223{
[e846fc9]224  int i;
[b5b9e75]225
226  /*
[18aa55ee]227   * Set up default exception handler
[b5b9e75]228   */
[18aa55ee]229  for (i = 2 ; i < 256 ; i++)
230      if (i != (32+2)) /* Catch all but bootrom system calls */
231          *((void (**)(int))(i * 4)) = handler;
[572484f]232
[1693c131]233  /*
234   * Invalidate the cache and disable it
235   */
236  m68k_set_acr0(mcf5282_acr0_mode);
237  m68k_set_acr1(mcf5282_acr1_mode);
238  m68k_set_cacr_nop(MCF5XXX_CACR_CINV);
[572484f]239
[1693c131]240  /*
241   * Cache SDRAM
242   */
[4c5212e]243  mcf5282_acr0_mode = MCF5XXX_ACR_AB((uint32_t)RamBase)     |
244                      MCF5XXX_ACR_AM((uint32_t)RamSize-1)   |
[1693c131]245                      MCF5XXX_ACR_EN                         |
246                      MCF5XXX_ACR_BWE                        |
247                      MCF5XXX_ACR_SM_IGNORE;
248  m68k_set_acr0(mcf5282_acr0_mode);
[572484f]249
[1693c131]250  /*
251   * Enable the cache
252   */
253  m68k_set_cacr(mcf5282_cacr_mode);
[572484f]254
[1693c131]255  /*
256   * Set up CS* space (fake 'VME')
257   *   Two A24/D16 spaces, supervisor data acces
258   */
259  MCF5282_CS1_CSAR = MCF5282_CS_CSAR_BA(VME_ONE_BASE);
260  MCF5282_CS1_CSMR = MCF5282_CS_CSMR_BAM_16M |
261                     MCF5282_CS_CSMR_CI |
262                     MCF5282_CS_CSMR_SC |
263                     MCF5282_CS_CSMR_UC |
264                     MCF5282_CS_CSMR_UD |
265                     MCF5282_CS_CSMR_V;
266  MCF5282_CS1_CSCR = MCF5282_CS_CSCR_PS_16;
267  MCF5282_CS2_CSAR = MCF5282_CS_CSAR_BA(VME_TWO_BASE);
268  MCF5282_CS2_CSMR = MCF5282_CS_CSMR_BAM_16M |
269                     MCF5282_CS_CSMR_CI |
270                     MCF5282_CS_CSMR_SC |
271                     MCF5282_CS_CSMR_UC |
272                     MCF5282_CS_CSMR_UD |
273                     MCF5282_CS_CSMR_V;
274  MCF5282_CS2_CSCR = MCF5282_CS_CSCR_PS_16;
275  MCF5282_GPIO_PJPAR |= 0x06;
[572484f]276}
277
[18aa55ee]278extern char _CPUClockSpeed[];
279
[0b2c943]280uint32_t bsp_get_CPU_clock_speed(void)
[572484f]281{
[1693c131]282  return( (uint32_t)_CPUClockSpeed);
[572484f]283}
[7eab0f78]284
[5b6111b]285/*
286 * Interrupt controller allocation
287 */
[d75023e]288rtems_status_code
289bsp_allocate_interrupt(int level, int priority)
[5b6111b]290{
[1693c131]291  static char used[7];
292  rtems_interrupt_level l;
293  rtems_status_code ret = RTEMS_RESOURCE_IN_USE;
294
295  if ((level < 1) || (level > 7) || (priority < 0) || (priority > 7))
296    return RTEMS_INVALID_NUMBER;
297  rtems_interrupt_disable(l);
298  if ((used[level-1] & (1 << priority)) == 0) {
299    used[level-1] |= (1 << priority);
300    ret = RTEMS_SUCCESSFUL;
301  }
302  rtems_interrupt_enable(l);
303  return ret;
[5b6111b]304}
305
[7eab0f78]306/*
[12993b3]307 * Arcturus bootloader system calls
[7eab0f78]308 */
[12993b3]309#define syscall_return(type, ret)                      \
310do {                                                   \
311   if ((unsigned long)(ret) >= (unsigned long)(-64)) { \
312      errno = -(ret);                                  \
313      ret = -1;                                        \
314   }                                                   \
315   return (type)(ret);                                 \
[7eab0f78]316} while (0)
[1693c131]317
[12993b3]318#define syscall_1(type,name,d1type,d1)                      \
[8af3643]319type bsp_##name(d1type d1)                                  \
[12993b3]320{                                                           \
321   long ret;                                                \
322   register long __d1 __asm__ ("%d1") = (long)d1;           \
[16ae480]323   __asm__ __volatile__ ("move.l %1,%%d0\n\t"               \
[12993b3]324                         "trap #2\n\t"                      \
325                         "move.l %%d0,%0"                   \
326                         : "=g" (ret)                       \
[8af3643]327                         : "i" (SysCode_##name), "d" (__d1) \
[12993b3]328                         : "d0" );                          \
329   syscall_return(type,ret);                                \
[7eab0f78]330}
[1693c131]331
[16ae480]332#define syscall_2(type,name,d1type,d1,d2type,d2)            \
[8af3643]333type bsp_##name(d1type d1, d2type d2)                       \
[16ae480]334{                                                           \
335   long ret;                                                \
336   register long __d1 __asm__ ("%d1") = (long)d1;           \
337   register long __d2 __asm__ ("%d2") = (long)d2;           \
338   __asm__ __volatile__ ("move.l %1,%%d0\n\t"               \
339                         "trap #2\n\t"                      \
340                         "move.l %%d0,%0"                   \
341                         : "=g" (ret)                       \
[8af3643]342                         : "i" (SysCode_##name), "d" (__d1),\
[16ae480]343                                                 "d" (__d2) \
344                         : "d0" );                          \
345   syscall_return(type,ret);                                \
346}
[1693c131]347
[8af3643]348#define syscall_3(type,name,d1type,d1,d2type,d2,d3type,d3)  \
349type bsp_##name(d1type d1, d2type d2, d3type d3)            \
350{                                                           \
351   long ret;                                                \
352   register long __d1 __asm__ ("%d1") = (long)d1;           \
353   register long __d2 __asm__ ("%d2") = (long)d2;           \
354   register long __d3 __asm__ ("%d3") = (long)d3;           \
355   __asm__ __volatile__ ("move.l %1,%%d0\n\t"               \
356                         "trap #2\n\t"                      \
357                         "move.l %%d0,%0"                   \
358                         : "=g" (ret)                       \
359                         : "i" (SysCode_##name), "d" (__d1),\
360                                                 "d" (__d2),\
361                                                 "d" (__d3) \
362                         : "d0" );                          \
363   syscall_return(type,ret);                                \
364}
[1693c131]365
[8af3643]366#define SysCode_reset              0 /* reset */
367#define SysCode_program            5 /* program flash memory */
368#define SysCode_gethwaddr         12 /* get hardware address */
369#define SysCode_getbenv           14 /* get bootloader environment variable */
[167818a]370#define SysCode_setbenv           15 /* set bootloader environment variable */
[8af3643]371#define SysCode_flash_erase_range 19 /* erase a section of flash */
372#define SysCode_flash_write_range 20 /* write a section of flash */
[b7115915]373syscall_1(int, reset, int, flags)
[12993b3]374syscall_1(unsigned const char *, gethwaddr, int, a)
375syscall_1(const char *, getbenv, const char *, a)
[167818a]376syscall_1(int, setbenv, const char *, a)
[16ae480]377syscall_2(int, program, bsp_mnode_t *, chain, int, flags)
[8af3643]378syscall_3(int, flash_erase_range, volatile unsigned short *, flashptr, int, start, int, end);
379syscall_3(int, flash_write_range, volatile unsigned short *, flashptr, bsp_mnode_t *, chain, int, offset);
[d75023e]380
381/*
382 * 'Extended BSP' routines
383 * Should move to cpukit/score/cpu/m68k/cpu.c someday.
384 */
385
386rtems_status_code bspExtInit(void) { return RTEMS_SUCCESSFUL; }
387int BSP_enableVME_int_lvl(unsigned int level) { return 0; }
388int BSP_disableVME_int_lvl(unsigned int level) { return 0; }
389
390/*
[a81e4f1]391 * 'VME' interrupt support
[402f4df]392 * Interrupt vectors 192-255 are set aside for use by external logic which
393 * drives IRQ1*.  The actual interrupt source is read from the external
394 * logic at FPGA_IRQ_INFO.  The most-significant bit of the least-significant
395 * byte read from this location is set as long as the external logic has
396 * interrupts to be serviced.  The least-significant six bits indicate the
397 * interrupt source within the external logic and are used to select the
398 * specified interupt handler.
[d75023e]399 */
[a7e6bc96]400#define NVECTOR 256
[a81e4f1]401#define FPGA_VECTOR (64+1)  /* IRQ1* pin connected to external FPGA */
402#define FPGA_IRQ_INFO    *((vuint16 *)(0x31000000 + 0xfffffe))
[a7e6bc96]403
[d75023e]404static struct handlerTab {
[1693c131]405  BSP_VME_ISR_t func;
406  void         *arg;
[a7e6bc96]407} handlerTab[NVECTOR];
[d75023e]408
409BSP_VME_ISR_t
410BSP_getVME_isr(unsigned long vector, void **pusrArg)
411{
[1693c131]412  if (vector >= NVECTOR)
413    return (BSP_VME_ISR_t)NULL;
414  if (pusrArg)
415    *pusrArg = handlerTab[vector].arg;
416  return handlerTab[vector].func;
[d75023e]417}
418
[215e019]419static rtems_isr
420fpga_trampoline (rtems_vector_number v)
421{
[1693c131]422  /*
423   * Handle FPGA interrupts until all have been consumed
424   */
425  int loopcount = 0;
426  while (((v = FPGA_IRQ_INFO) & 0x80) != 0) {
427    v = 192 + (v & 0x3f);
428    if (++loopcount >= 50) {
429      rtems_interrupt_level level;
430      rtems_interrupt_disable(level);
431      printk("\nTOO MANY FPGA INTERRUPTS (LAST WAS 0x%x) -- DISABLING ALL FPGA INTERRUPTS.\n", v & 0x3f);
432      MCF5282_INTC0_IMRL |= MCF5282_INTC_IMRL_INT1;
433      rtems_interrupt_enable(level);
434      return;
435    }
436    if (handlerTab[v].func)  {
437      (*handlerTab[v].func)(handlerTab[v].arg, (unsigned long)v);
438    }
439    else {
440      rtems_interrupt_level level;
441      rtems_vector_number nv;
442      rtems_interrupt_disable(level);
443      printk("\nSPURIOUS FPGA INTERRUPT (0x%x).\n", v & 0x3f);
444      if ((((nv = FPGA_IRQ_INFO) & 0x80) != 0)
445          && ((nv & 0x3f) == (v & 0x3f))) {
446        printk("DISABLING ALL FPGA INTERRUPTS.\n");
447        MCF5282_INTC0_IMRL |= MCF5282_INTC_IMRL_INT1;
448      }
449      rtems_interrupt_enable(level);
450      return;
451    }
452  }
[215e019]453}
454
[d75023e]455static rtems_isr
[a7e6bc96]456trampoline (rtems_vector_number v)
[d75023e]457{
[215e019]458    if (handlerTab[v].func)
459        (*handlerTab[v].func)(handlerTab[v].arg, (unsigned long)v);
460}
461
462static void
463enable_irq(unsigned source)
464{
465rtems_interrupt_level level;
[1693c131]466  rtems_interrupt_disable(level);
467  if (source >= 32)
468    MCF5282_INTC0_IMRH &= ~(1 << (source - 32));
469  else
470    MCF5282_INTC0_IMRL &= ~((1 << source) |
471        MCF5282_INTC_IMRL_MASKALL);
472  rtems_interrupt_enable(level);
[215e019]473}
474
475static void
476disable_irq(unsigned source)
477{
478rtems_interrupt_level level;
479
[1693c131]480  rtems_interrupt_disable(level);
481  if (source >= 32)
482    MCF5282_INTC0_IMRH |= (1 << (source - 32));
483  else
484    MCF5282_INTC0_IMRL |= (1 << source);
485  rtems_interrupt_enable(level);
[215e019]486}
487
488void
489BSP_enable_irq_at_pic(rtems_vector_number v)
490{
491int                   source = v - 64;
492
[1693c131]493  if ( source > 0 && source < 64 ) {
494    enable_irq(source);
495  }
[215e019]496}
497
498void
499BSP_disable_irq_at_pic(rtems_vector_number v)
500{
501int                   source = v - 64;
502
[1693c131]503  if ( source > 0 && source < 64 ) {
504    disable_irq(source);
505  }
[215e019]506}
507
508int
509BSP_irq_is_enabled_at_pic(rtems_vector_number v)
510{
511int                   source = v - 64;
512
[1693c131]513  if ( source > 0 && source < 64 ) {
514    return ! ((source >= 32) ?
515      MCF5282_INTC0_IMRH & (1 << (source - 32)) :
516      MCF5282_INTC0_IMRL & (1 << source));
517  }
518  return -1;
[215e019]519}
520
521
522static int
523init_intc0_bit(unsigned long vector)
524{
525rtems_interrupt_level level;
526
[a81e4f1]527    /*
[215e019]528     * Find an unused level/priority if this is an on-chip (INTC0)
529     * source and this is the first time the source is being used.
530     * Interrupt sources 1 through 7 are fixed level/priority
[a81e4f1]531     */
[215e019]532
533    if ((vector >= 65) && (vector <= 127)) {
534        int l, p;
535        int source = vector - 64;
536        static unsigned char installed[8];
537
538        rtems_interrupt_disable(level);
539        if (installed[source/8] & (1 << (source % 8))) {
540            rtems_interrupt_enable(level);
541            return 0;
542        }
543        installed[source/8] |= (1 << (source % 8));
544        rtems_interrupt_enable(level);
545        for (l = 1 ; l < 7 ; l++) {
546            for (p = 0 ; p < 8 ; p++) {
547                if ((source < 8)
548                 || (bsp_allocate_interrupt(l,p) == RTEMS_SUCCESSFUL)) {
[9797991]549                    if (source < 8)
550                        MCF5282_EPORT_EPIER |= 1 << source;
551                    else
[215e019]552                        *(&MCF5282_INTC0_ICR1 + (source - 1)) =
553                                                       MCF5282_INTC_ICR_IL(l) |
554                                                       MCF5282_INTC_ICR_IP(p);
[1693c131]555          enable_irq(source);
[215e019]556                    return 0;
[8a742dd]557                }
[a7edc92]558            }
[a81e4f1]559        }
[215e019]560        return -1;
[a81e4f1]561    }
[1693c131]562  return 0;
[d75023e]563}
564
565int
566BSP_installVME_isr(unsigned long vector, BSP_VME_ISR_t handler, void *usrArg)
567{
[1693c131]568  rtems_isr_entry old_handler;
569  rtems_interrupt_level level;
[d75023e]570
[1693c131]571  /*
572   * Register the handler information
573   */
574  if (vector >= NVECTOR)
575    return -1;
576  handlerTab[vector].func = handler;
577  handlerTab[vector].arg = usrArg;
[a81e4f1]578
[1693c131]579  /*
580   * If this is an external FPGA ('VME') vector set up the real IRQ.
581   */
582  if ((vector >= 192) && (vector <= 255)) {
583    int i;
584    static volatile int setupDone;
585    rtems_interrupt_disable(level);
586    if (setupDone) {
587      rtems_interrupt_enable(level);
588      return 0;
[a81e4f1]589    }
[7decb66]590    setupDone = 1;
[1693c131]591    rtems_interrupt_catch(fpga_trampoline, FPGA_VECTOR, &old_handler);
592    i = init_intc0_bit(FPGA_VECTOR);
593    rtems_interrupt_enable(level);
594    return i;
595  }
[a81e4f1]596
[1693c131]597  /*
598   * Make the connection between the interrupt and the local handler
599   */
600  rtems_interrupt_catch(trampoline, vector, &old_handler);
[d75023e]601
[1693c131]602  return init_intc0_bit(vector);
[d75023e]603}
604
605int
606BSP_removeVME_isr(unsigned long vector, BSP_VME_ISR_t handler, void *usrArg)
607{
[1693c131]608  if (vector >= NVECTOR)
609    return -1;
610  if ((handlerTab[vector].func != handler)
[d75023e]611     || (handlerTab[vector].arg != usrArg))
[1693c131]612    return -1;
613  handlerTab[vector].func = (BSP_VME_ISR_t)NULL;
614  return 0;
[d75023e]615}
616
617int
618BSP_vme2local_adrs(unsigned am, unsigned long vmeaddr, unsigned long *plocaladdr)
619{
[1693c131]620  unsigned long offset;
[d75023e]621
[1693c131]622  switch (am) {
[d75023e]623    default:    return -1;
[008c4b5]624    case VME_AM_SUP_SHORT_IO: offset = 0x31FF0000; break; /* A16/D16 */
[d75023e]625    case VME_AM_STD_SUP_DATA: offset = 0x30000000; break; /* A24/D16 */
[008c4b5]626    case VME_AM_EXT_SUP_DATA: offset = 0x31000000; break; /* A32/D32 */
[1693c131]627  }
628  *plocaladdr = vmeaddr + offset;
629  return 0;
[d75023e]630}
[91cb065]631
632void
633rtems_bsp_reset_cause(char *buf, size_t capacity)
634{
[1693c131]635  int bit, rsr;
636  size_t i;
637  const char *cp;
[91cb065]638   
[1693c131]639  if (buf == NULL)
640    return;
641  if (capacity)
642    buf[0] = '\0';
643  rsr = MCF5282_RESET_RSR;
644  for (i = 0, bit = 0x80 ; bit != 0 ; bit >>= 1) {
645    if (rsr & bit) {
646      switch (bit) {
647        case MCF5282_RESET_RSR_LVD:  cp = "Low voltage";        break;
648        case MCF5282_RESET_RSR_SOFT: cp = "Software reset";     break;
649        case MCF5282_RESET_RSR_WDR:  cp = "Watchdog reset";     break;
650        case MCF5282_RESET_RSR_POR:  cp = "Power-on reset";     break;
651        case MCF5282_RESET_RSR_EXT:  cp = "External reset";     break;
652        case MCF5282_RESET_RSR_LOC:  cp = "Loss of clock";      break;
653        case MCF5282_RESET_RSR_LOL:  cp = "Loss of lock";       break;
654        default:                     cp = "??";                 break;
655      }
656      i += snprintf(buf+i, capacity-i, cp);
657      if (i >= capacity)
658        break;
659      rsr &= ~bit;
660      if (rsr == 0)
661        break;
662      i += snprintf(buf+i, capacity-i, ", ");
663      if (i >= capacity)
664        break;
[91cb065]665    }
[1693c131]666  }
[91cb065]667}
Note: See TracBrowser for help on using the repository browser.