source: rtems/c/src/lib/libbsp/m68k/uC5282/startup/bspstart.c @ 6ea100c1

4.104.114.95
Last change on this file since 6ea100c1 was 6ea100c1, checked in by Joel Sherrill <joel.sherrill@…>, on 05/12/08 at 18:43:55

2008-05-12 Joel Sherrill <joel.sherrill@…>

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