Updated copyright notices for most files.
[deliverable/binutils-gdb.git] / sim / m32c / mem.c
1 /* mem.c --- memory for M32C simulator.
2
3 Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
5
6 This file is part of the GNU simulators.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "mem.h"
27 #include "cpu.h"
28 #include "syscalls.h"
29 #include "misc.h"
30
31 #define L1_BITS (10)
32 #define L2_BITS (10)
33 #define OFF_BITS (12)
34
35 #define L1_LEN (1 << L1_BITS)
36 #define L2_LEN (1 << L2_BITS)
37 #define OFF_LEN (1 << OFF_BITS)
38
39 static unsigned char **pt[L1_LEN];
40
41 /* [ get=0/put=1 ][ byte size ] */
42 static unsigned int mem_counters[2][4];
43
44 #define COUNT(isput,bytes) \
45 if (verbose && enable_counting) mem_counters[isput][bytes]++
46
47 void
48 init_mem (void)
49 {
50 int i, j;
51
52 for (i = 0; i < L1_LEN; i++)
53 if (pt[i])
54 {
55 for (j = 0; j < L2_LEN; j++)
56 if (pt[i][j])
57 free (pt[i][j]);
58 free (pt[i]);
59 }
60 memset (pt, 0, sizeof (pt));
61 memset (mem_counters, 0, sizeof (mem_counters));
62 }
63
64 static unsigned char *
65 mem_ptr (address)
66 {
67 int pt1 = (address >> (L2_BITS + OFF_BITS)) & ((1 << L1_BITS) - 1);
68 int pt2 = (address >> OFF_BITS) & ((1 << L2_BITS) - 1);
69 int pto = address & ((1 << OFF_BITS) - 1);
70
71 if (address == 0)
72 {
73 printf ("NULL pointer dereference\n");
74 exit (1);
75 }
76
77 if (pt[pt1] == 0)
78 pt[pt1] = (unsigned char **) calloc (L2_LEN, sizeof (char **));
79 if (pt[pt1][pt2] == 0)
80 {
81 pt[pt1][pt2] = (unsigned char *) malloc (OFF_LEN);
82 memset (pt[pt1][pt2], 0, OFF_LEN);
83 }
84
85 return pt[pt1][pt2] + pto;
86 }
87
88 static void
89 used (int rstart, int i, int j)
90 {
91 int rend = i << (L2_BITS + OFF_BITS);
92 rend += j << OFF_BITS;
93 if (rstart == 0xe0000 && rend == 0xe1000)
94 return;
95 printf ("mem: %08x - %08x (%dk bytes)\n", rstart, rend - 1,
96 (rend - rstart) / 1024);
97 }
98
99 static char *
100 mcs (int isput, int bytes)
101 {
102 return comma (mem_counters[isput][bytes]);
103 }
104
105 void
106 mem_usage_stats ()
107 {
108 int i, j;
109 int rstart = 0;
110 int pending = 0;
111
112 for (i = 0; i < L1_LEN; i++)
113 if (pt[i])
114 {
115 for (j = 0; j < L2_LEN; j++)
116 if (pt[i][j])
117 {
118 if (!pending)
119 {
120 pending = 1;
121 rstart = (i << (L2_BITS + OFF_BITS)) + (j << OFF_BITS);
122 }
123 }
124 else if (pending)
125 {
126 pending = 0;
127 used (rstart, i, j);
128 }
129 }
130 else
131 {
132 if (pending)
133 {
134 pending = 0;
135 used (rstart, i, 0);
136 }
137 }
138 /* mem foo: 123456789012 123456789012 123456789012 123456789012
139 123456789012 */
140 printf (" byte short pointer long"
141 " fetch\n");
142 printf ("mem get: %12s %12s %12s %12s %12s\n", mcs (0, 1), mcs (0, 2),
143 mcs (0, 3), mcs (0, 4), mcs (0, 0));
144 printf ("mem put: %12s %12s %12s %12s\n", mcs (1, 1), mcs (1, 2),
145 mcs (1, 3), mcs (1, 4));
146 }
147
148 static int tpr = 0;
149 static void
150 s (int address, char *dir)
151 {
152 if (tpr == 0)
153 printf ("MEM[%0*x] %s", membus_mask == 0xfffff ? 5 : 6, address, dir);
154 tpr++;
155 }
156
157 #define S(d) if (trace) s(address, d)
158 static void
159 e ()
160 {
161 if (!trace)
162 return;
163 tpr--;
164 if (tpr == 0)
165 printf ("\n");
166 }
167
168 #define E() if (trace) e()
169
170 void
171 mem_put_byte (int address, unsigned char value)
172 {
173 unsigned char *m;
174 address &= membus_mask;
175 m = mem_ptr (address);
176 if (trace)
177 printf (" %02x", value);
178 *m = value;
179 switch (address)
180 {
181 case 0x00e1:
182 {
183 static int old_led = -1;
184 static char *led_on[] =
185 { "\033[31m O ", "\033[32m O ", "\033[34m O " };
186 static char *led_off[] = { "\033[0m · ", "\033[0m · ", "\033[0m · " };
187 int i;
188 if (old_led != value)
189 {
190 fputs (" ", stdout);
191 for (i = 0; i < 3; i++)
192 if (value & (1 << i))
193 fputs (led_off[i], stdout);
194 else
195 fputs (led_on[i], stdout);
196 fputs ("\033[0m\r", stdout);
197 fflush (stdout);
198 old_led = value;
199 }
200 }
201 break;
202
203 case 0x3aa: /* uart1tx */
204 {
205 static int pending_exit = 0;
206 if (value == 0)
207 {
208 if (pending_exit)
209 {
210 step_result = M32C_MAKE_EXITED(value);
211 return;
212 }
213 pending_exit = 1;
214 }
215 else
216 putchar(value);
217 }
218 break;
219
220 case 0x400:
221 m32c_syscall (value);
222 break;
223
224 case 0x401:
225 putchar (value);
226 break;
227
228 case 0x402:
229 printf ("SimTrace: %06lx %02x\n", regs.r_pc, value);
230 break;
231
232 case 0x403:
233 printf ("SimTrap: %06lx %02x\n", regs.r_pc, value);
234 abort ();
235 }
236 }
237
238 void
239 mem_put_qi (int address, unsigned char value)
240 {
241 S ("<=");
242 mem_put_byte (address, value & 0xff);
243 E ();
244 COUNT (1, 1);
245 }
246
247 void
248 mem_put_hi (int address, unsigned short value)
249 {
250 if (address == 0x402)
251 {
252 printf ("SimTrace: %06lx %04x\n", regs.r_pc, value);
253 return;
254 }
255 S ("<=");
256 mem_put_byte (address, value & 0xff);
257 mem_put_byte (address + 1, value >> 8);
258 E ();
259 COUNT (1, 2);
260 }
261
262 void
263 mem_put_psi (int address, unsigned long value)
264 {
265 S ("<=");
266 mem_put_byte (address, value & 0xff);
267 mem_put_byte (address + 1, (value >> 8) & 0xff);
268 mem_put_byte (address + 2, value >> 16);
269 E ();
270 COUNT (1, 3);
271 }
272
273 void
274 mem_put_si (int address, unsigned long value)
275 {
276 S ("<=");
277 mem_put_byte (address, value & 0xff);
278 mem_put_byte (address + 1, (value >> 8) & 0xff);
279 mem_put_byte (address + 2, (value >> 16) & 0xff);
280 mem_put_byte (address + 3, (value >> 24) & 0xff);
281 E ();
282 COUNT (1, 4);
283 }
284
285 void
286 mem_put_blk (int address, void *bufptr, int nbytes)
287 {
288 S ("<=");
289 if (enable_counting)
290 mem_counters[1][1] += nbytes;
291 while (nbytes--)
292 mem_put_byte (address++, *(unsigned char *) bufptr++);
293 E ();
294 }
295
296 unsigned char
297 mem_get_pc ()
298 {
299 unsigned char *m = mem_ptr (regs.r_pc & membus_mask);
300 COUNT (0, 0);
301 return *m;
302 }
303
304 static unsigned char
305 mem_get_byte (int address)
306 {
307 unsigned char *m;
308 address &= membus_mask;
309 S ("=>");
310 m = mem_ptr (address);
311 switch (address)
312 {
313 case 0x3ad: /* uart1c1 */
314 E();
315 return 2; /* transmitter empty */
316 break;
317 default:
318 if (trace)
319 printf (" %02x", *m);
320 break;
321 }
322 E ();
323 return *m;
324 }
325
326 unsigned char
327 mem_get_qi (int address)
328 {
329 unsigned char rv;
330 S ("=>");
331 rv = mem_get_byte (address);
332 COUNT (0, 1);
333 E ();
334 return rv;
335 }
336
337 unsigned short
338 mem_get_hi (int address)
339 {
340 unsigned short rv;
341 S ("=>");
342 rv = mem_get_byte (address);
343 rv |= mem_get_byte (address + 1) * 256;
344 COUNT (0, 2);
345 E ();
346 return rv;
347 }
348
349 unsigned long
350 mem_get_psi (int address)
351 {
352 unsigned long rv;
353 S ("=>");
354 rv = mem_get_byte (address);
355 rv |= mem_get_byte (address + 1) * 256;
356 rv |= mem_get_byte (address + 2) * 65536;
357 COUNT (0, 3);
358 E ();
359 return rv;
360 }
361
362 unsigned long
363 mem_get_si (int address)
364 {
365 unsigned long rv;
366 S ("=>");
367 rv = mem_get_byte (address);
368 rv |= mem_get_byte (address + 1) << 8;
369 rv |= mem_get_byte (address + 2) << 16;
370 rv |= mem_get_byte (address + 3) << 24;
371 COUNT (0, 4);
372 E ();
373 return rv;
374 }
375
376 void
377 mem_get_blk (int address, void *bufptr, int nbytes)
378 {
379 S ("=>");
380 if (enable_counting)
381 mem_counters[0][1] += nbytes;
382 while (nbytes--)
383 *(char *) bufptr++ = mem_get_byte (address++);
384 E ();
385 }
386
387 int
388 sign_ext (int v, int bits)
389 {
390 if (bits < 32)
391 {
392 v &= (1 << bits) - 1;
393 if (v & (1 << (bits - 1)))
394 v -= (1 << bits);
395 }
396 return v;
397 }
This page took 0.042774 seconds and 5 git commands to generate.