Updated copyright notices for most files.
[deliverable/binutils-gdb.git] / sim / m32c / mem.c
CommitLineData
d45a4bef
JB
1/* mem.c --- memory for M32C simulator.
2
9b254dd1 3Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
d45a4bef
JB
4Contributed by Red Hat, Inc.
5
6This file is part of the GNU simulators.
7
4744ac1b
JB
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3 of the License, or
11(at your option) any later version.
d45a4bef 12
4744ac1b
JB
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
d45a4bef
JB
17
18You should have received a copy of the GNU General Public License
4744ac1b 19along with this program. If not, see <http://www.gnu.org/licenses/>. */
d45a4bef
JB
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
39static unsigned char **pt[L1_LEN];
40
41/* [ get=0/put=1 ][ byte size ] */
42static unsigned int mem_counters[2][4];
43
44#define COUNT(isput,bytes) \
45 if (verbose && enable_counting) mem_counters[isput][bytes]++
46
47void
48init_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
64static unsigned char *
65mem_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
88static void
89used (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
99static char *
100mcs (int isput, int bytes)
101{
102 return comma (mem_counters[isput][bytes]);
103}
104
105void
106mem_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
148static int tpr = 0;
149static void
150s (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)
158static void
159e ()
160{
161 if (!trace)
162 return;
163 tpr--;
164 if (tpr == 0)
165 printf ("\n");
166}
167
168#define E() if (trace) e()
169
170void
171mem_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 " };