source: rtems/c/src/lib/libcpu/m68k/shared/misc/memProbe.c @ 359e537

4.104.115
Last change on this file since 359e537 was 359e537, checked in by Ralf Corsepius <ralf.corsepius@…>, on 11/30/09 at 05:09:41

Whitespace removal.

  • Property mode set to 100644
File size: 2.5 KB
Line 
1/*
2 * Address Probing for M68k/ColdFire
3 */
4
5#include <bsp.h>
6#include <string.h>
7
8#if (M68K_COLDFIRE_ARCH == 1)
9# define EXCEPTION_FRAME_PC_OFFSET "4"
10#else
11# define EXCEPTION_FRAME_PC_OFFSET "2"
12#endif
13
14typedef int (*MemProber)(void *from, void *to);
15int memProbeByte(void *from, void *to);
16int memProbeShort(void *from, void *to);
17int memProbeLong(void *from, void *to);
18int memProbeCatcher(void);
19
20__asm__(
21    ".text\n"
22    "memProbeByte:        \n"
23    "   move.l %sp@(4),%a0\n"
24    "   move.b %a0@,%d0   \n"
25    "   move.l %sp@(8),%a0\n"
26    "   move.b %d0,%a0@   \n"
27    "   bra.b 1f          \n"
28    "memProbeShort:       \n"
29    "   move.l %sp@(4),%a0\n"
30    "   move.w %a0@,%d0   \n"
31    "   move.l %sp@(8),%a0\n"
32    "   move.w %d0,%a0@   \n"
33    "   bra.b 1f          \n"
34    "memProbeLong:        \n"
35    "   move.l %sp@(4),%a0\n"
36    "   move.l %a0@,%d0   \n"
37    "   move.l %sp@(8),%a0\n"
38    "   move.l %d0,%a0@   \n"
39    "1: nop               \n"
40    "   moveq.l #1,%d0    \n"
41    "   rts               \n"
42    "memProbeCatcher:     \n"
43    "   move.l #1f,%d0    \n"
44    "   move.l %d0,%sp@(" EXCEPTION_FRAME_PC_OFFSET ")\n"
45    "   rte               \n"
46    "1: clr.l  %d0        \n"
47    "   rts               \n"
48);
49
50rtems_status_code
51bspExtMemProbe(void *addr, int write, int size, void *pval)
52{
53    rtems_status_code rval=RTEMS_SUCCESSFUL;
54    rtems_interrupt_level level;
55    unsigned long buf;
56    MemProber probe;
57    void *saveVector;
58    void **exceptionPointer;
59    void *vbr;
60
61    /*
62     * Sanity check
63     */
64    switch (size) {
65        case sizeof(char):  probe=memProbeByte; break;
66        case sizeof(short): probe=memProbeShort; break;
67        case sizeof(long):  probe=memProbeLong; break;
68        default: return RTEMS_INVALID_SIZE;
69    }
70
71    /*
72     * use a buffer to make sure we don't end up probing 'pval'.
73     */
74    if (write && pval)
75        memcpy(&buf, pval, size);
76
77    /*
78     * Get location of access fault exception
79     */
80    m68k_get_vbr(vbr);
81    exceptionPointer = (void **)((char *)vbr + (2 * 4));
82
83    /*
84     * Probe!
85     */
86    rtems_interrupt_disable(level);
87    saveVector = *exceptionPointer;
88    *exceptionPointer = memProbeCatcher;
89    if (write) {
90        if (probe(&buf, addr) == 0)
91            rval = RTEMS_INVALID_ADDRESS;
92    }
93    else {
94        if (probe(addr, &buf) == 0)
95            rval = RTEMS_INVALID_ADDRESS;
96    }
97    *exceptionPointer = saveVector;
98    rtems_interrupt_enable(level);
99
100    if (!write && pval && (rval == RTEMS_SUCCESSFUL))
101        memcpy(pval, &buf, size);
102    return rval;
103}
Note: See TracBrowser for help on using the repository browser.