Reviewed and approved by Daniel Jacobowitz <drow@false.org>
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.base / ovlymgr.c
1
2 /*
3 * Ovlymgr.c -- Runtime Overlay Manager for the GDB testsuite.
4 */
5
6 #include "ovlymgr.h"
7
8 /* Local functions and data: */
9
10 extern unsigned long _ovly_table[][4];
11 extern unsigned long _novlys __attribute__ ((section (".data")));
12 enum ovly_index { VMA, SIZE, LMA, MAPPED};
13
14 static void ovly_copy (unsigned long dst, unsigned long src, long size);
15
16 /* Flush the data and instruction caches at address START for SIZE bytes.
17 Support for each new port must be added here. */
18 /* FIXME: Might be better to have a standard libgloss function that
19 ports provide that we can then use. Use libgloss instead of newlib
20 since libgloss is the one intended to handle low level system issues.
21 I would suggest something like _flush_cache to avoid the user's namespace
22 but not be completely obscure as other things may need this facility. */
23
24 static void
25 FlushCache (void)
26 {
27 #ifdef __M32R__
28 volatile char *mspr = (char *) 0xfffffff7;
29 *mspr = 1;
30 #endif
31 }
32
33 /* _ovly_debug_event:
34 * Debuggers may set a breakpoint here, to be notified
35 * when the overlay table has been modified.
36 */
37 static void
38 _ovly_debug_event (void)
39 {
40 }
41
42 /* OverlayLoad:
43 * Copy the overlay into its runtime region,
44 * and mark the overlay as "mapped".
45 */
46
47 bool
48 OverlayLoad (unsigned long ovlyno)
49 {
50 unsigned long i;
51
52 if (ovlyno < 0 || ovlyno >= _novlys)
53 exit (-1); /* fail, bad ovly number */
54
55 if (_ovly_table[ovlyno][MAPPED])
56 return TRUE; /* this overlay already mapped -- nothing to do! */
57
58 for (i = 0; i < _novlys; i++)
59 if (i == ovlyno)
60 _ovly_table[i][MAPPED] = 1; /* this one now mapped */
61 else if (_ovly_table[i][VMA] == _ovly_table[ovlyno][VMA])
62 _ovly_table[i][MAPPED] = 0; /* this one now un-mapped */
63
64 ovly_copy (_ovly_table[ovlyno][VMA],
65 _ovly_table[ovlyno][LMA],
66 _ovly_table[ovlyno][SIZE]);
67
68 FlushCache ();
69 _ovly_debug_event ();
70 return TRUE;
71 }
72
73 /* OverlayUnload:
74 * Copy the overlay back into its "load" region.
75 * Does NOT mark overlay as "unmapped", therefore may be called
76 * more than once for the same mapped overlay.
77 */
78
79 bool
80 OverlayUnload (unsigned long ovlyno)
81 {
82 if (ovlyno < 0 || ovlyno >= _novlys)
83 exit (-1); /* fail, bad ovly number */
84
85 if (!_ovly_table[ovlyno][MAPPED])
86 exit (-1); /* error, can't copy out a segment that's not "in" */
87
88 ovly_copy (_ovly_table[ovlyno][LMA],
89 _ovly_table[ovlyno][VMA],
90 _ovly_table[ovlyno][SIZE]);
91
92 _ovly_debug_event ();
93 return TRUE;
94 }
95
96 #ifdef __D10V__
97 #define IMAP0 (*(short *)(0xff00))
98 #define IMAP1 (*(short *)(0xff02))
99 #define DMAP (*(short *)(0xff04))
100
101 static void
102 D10VTranslate (unsigned long logical,
103 short *dmap,
104 unsigned long **addr)
105 {
106 unsigned long physical;
107 unsigned long seg;
108 unsigned long off;
109
110 /* to access data, we use the following mapping
111 0x00xxxxxx: Logical data address segment (DMAP translated memory)
112 0x01xxxxxx: Logical instruction address segment (IMAP translated memory)
113 0x10xxxxxx: Physical data memory segment (On-chip data memory)
114 0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)
115 0x12xxxxxx: Phisical unified memory segment (Unified memory)
116 */
117
118 /* Addresses must be correctly aligned */
119 if (logical & (sizeof (**addr) - 1))
120 exit (-1);
121
122 /* If the address is in one of the two logical address spaces, it is
123 first translated into a physical address */
124 seg = (logical >> 24);
125 off = (logical & 0xffffffL);
126 switch (seg)
127 {
128 case 0x00: /* in logical data address segment */
129 if (off <= 0x7fffL)
130 physical = (0x10L << 24) + off;
131 else
132 /* Logical address out side of on-chip segment, not
133 supported */
134 exit (-1);
135 break;
136 case 0x01: /* in logical instruction address segment */
137 {
138 short map;
139 if (off <= 0x1ffffL)
140 map = IMAP0;
141 else if (off <= 0x3ffffL)
142 map = IMAP1;
143 else
144 /* Logical address outside of IMAP[01] segment, not
145 supported */
146 exit (-1);
147 if (map & 0x1000L)
148 {
149 /* Instruction memory */
150 physical = (0x11L << 24) | off;
151 }
152 else
153 {
154 /* Unified memory */
155 physical = ((map & 0x7fL) << 17) + (off & 0x1ffffL);
156 if (physical > 0xffffffL)
157 /* Address outside of unified address segment */
158 exit (-1);
159 physical |= (0x12L << 24);
160 }
161 break;
162 }
163 case 0x10:
164 case 0x11:
165 case 0x12:
166 physical = logical;
167 break;
168 default:
169 exit (-1); /* error */
170 }
171
172 seg = (physical >> 24);
173 off = (physical & 0xffffffL);
174 switch (seg)
175 {
176 case 0x10: /* dst is a 15 bit offset into the on-chip memory */
177 *dmap = 0;
178 *addr = (long *) (0x0000 + ((short)off & 0x7fff));
179 break;
180 case 0x11: /* dst is an 18-bit offset into the on-chip
181 instruction memory */
182 *dmap = 0x1000L | ((off & 0x3ffffL) >> 14);
183 *addr = (long *) (0x8000 + ((short)off & 0x3fff));
184 break;
185 case 0x12: /* dst is a 24-bit offset into unified memory */
186 *dmap = off >> 14;
187 *addr = (long *) (0x8000 + ((short)off & 0x3fff));
188 break;
189 default:
190 exit (-1); /* error */
191 }
192 }
193 #endif /* __D10V__ */
194
195 static void
196 ovly_copy (unsigned long dst, unsigned long src, long size)
197 {
198 #ifdef __D10V__
199 unsigned long *s, *d, tmp;
200 short dmap_src, dmap_dst;
201 short dmap_save;
202
203 /* all section sizes should by multiples of 4 bytes */
204 dmap_save = DMAP;
205
206 D10VTranslate (src, &dmap_src, &s);
207 D10VTranslate (dst, &dmap_dst, &d);
208
209 while (size > 0)
210 {
211 /* NB: Transfer 4 byte (long) quantites, problems occure
212 when only two bytes are transfered */
213 DMAP = dmap_src;
214 tmp = *s;
215 DMAP = dmap_dst;
216 *d = tmp;
217 d++;
218 s++;
219 size -= sizeof (tmp);
220 src += sizeof (tmp);
221 dst += sizeof (tmp);
222 if ((src & 0x3fff) == 0)
223 D10VTranslate (src, &dmap_src, &s);
224 if ((dst & 0x3fff) == 0)
225 D10VTranslate (dst, &dmap_dst, &d);
226 }
227 DMAP = dmap_save;
228 #else
229 memcpy ((void *) dst, (void *) src, size);
230 #endif /* D10V */
231 return;
232 }
233
This page took 0.034625 seconds and 4 git commands to generate.