OSDN Git Service

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