* Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir,
[binutils-gdb.git] / sim / erc32 / interf.c
1 /*
2 * This file is part of SIS.
3 *
4 * SIS, SPARC instruction simulator V1.6 Copyright (C) 1995 Jiri Gaisler,
5 * European Space Agency
6 *
7 * This program is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 675
19 * Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23 #include <signal.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include "sis.h"
27 #include "bfd.h"
28 #include <dis-asm.h>
29
30 #ifndef fprintf
31 extern fprintf();
32 #endif
33
34 #define VAL(x) strtol(x,(char *)NULL,0)
35
36 extern char **buildargv(char *input);
37
38 extern struct disassemble_info dinfo;
39 extern struct pstate sregs;
40 extern struct estate ebase;
41
42 extern int ctrl_c;
43 extern int nfp;
44 extern int sis_verbose;
45 extern char *sis_version;
46 extern struct estate ebase;
47 extern struct evcell evbuf[];
48 extern struct irqcell irqarr[];
49 extern int irqpend, ext_irl;
50 extern char uart_dev1[], uart_dev2[];
51
52 int sis_gdb_break = 1;
53
54 #ifdef IUREV0
55 extern int iurev0;
56 #endif
57
58 #ifdef MECREV0
59 extern int mecrev0;
60 #endif
61
62 run_sim(sregs, go, icount, dis)
63 struct pstate *sregs;
64 int go;
65 unsigned int icount;
66 int dis;
67 {
68 int mexc, ws;
69
70 if (sis_verbose)
71 printf_filtered("resuming at %x\n", sregs->pc);
72 sregs->starttime = time(NULL);
73 while ((!sregs->err_mode & (go || (icount > 0))) &&
74 ((sregs->bptnum == 0) || !(sregs->bphit = check_bpt(sregs)))) {
75
76 sregs->fhold = 0;
77 sregs->hold = 0;
78 sregs->icnt = 0;
79
80 check_interrupts(sregs);
81 if (sregs->trap) {
82 sregs->err_mode = execute_trap(sregs);
83 } else {
84 if (sregs->psr & 0x080)
85 sregs->asi = 8;
86 else
87 sregs->asi = 9;
88 #ifdef IUREV0
89 if (iurev0 && sregs->rett_err) {
90 sregs->asi &= ~0x1;
91 sregs->asi |= ((sregs->psr & 0x040) >> 6);
92 }
93 #endif
94
95 mexc = memory_read(sregs->asi, sregs->pc, &sregs->inst, &sregs->hold);
96 if (sregs->annul) {
97 sregs->annul = 0;
98 sregs->icnt = 1;
99 sregs->pc = sregs->npc;
100 sregs->npc = sregs->npc + 4;
101 } else {
102 if (mexc) {
103 sregs->trap = I_ACC_EXC;
104 } else {
105 if (sregs->histlen) {
106 sregs->histbuf[sregs->histind].addr = sregs->pc;
107 sregs->histbuf[sregs->histind].time = ebase.simtime;
108 sregs->histind++;
109 if (sregs->histind >= sregs->histlen)
110 sregs->histind = 0;
111 }
112 if (dis) {
113 printf(" %8d ", ebase.simtime);
114 dis_mem(sregs->pc, 1, &dinfo);
115 }
116 if ((sis_gdb_break) && (sregs->inst == 0x91d02001)) {
117 if (sis_verbose)
118 printf_filtered("SW BP hit at %x\n", sregs->pc);
119 return (BPT_HIT);
120 } else
121 dispatch_instruction(sregs);
122 }
123 icount--;
124 }
125 if (sregs->trap) {
126 sregs->err_mode = execute_trap(sregs);
127 }
128 }
129 advance_time(sregs);
130 if (ctrl_c) {
131 go = icount = 0;
132 }
133 }
134 sregs->tottime += time(NULL) - sregs->starttime;
135 if (sregs->err_mode)
136 error_mode(sregs->pc);
137 if (sregs->err_mode)
138 return (ERROR);
139 if (sregs->bphit) {
140 if (sis_verbose)
141 printf_filtered("HW BP hit at %x\n", sregs->pc);
142 return (BPT_HIT);
143 }
144 if (ctrl_c) {
145 ctrl_c = 0;
146 return (CTRL_C);
147 }
148 return (TIME_OUT);
149 }
150
151
152 void
153 sim_open(char *args)
154 {
155
156 int argc = 0;
157 char **argv;
158 int cont = 1;
159 int stat = 0;
160 int grdl = 0;
161 int freq = 15;
162
163 printf_filtered("\n SIS - SPARC instruction simulator %s\n", sis_version);
164 printf_filtered(" Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n");
165 argv = buildargv(args);
166 if (argv != NULL)
167 while (argv[argc])
168 argc++;
169 while (stat < argc) {
170 if (argv[stat][0] == '-') {
171 if (strcmp(argv[stat], "-v") == 0) {
172 sis_verbose = 1;
173 }
174 #ifdef IUREV0
175 if (strcmp(argv[stat], "-iurev0") == 0) {
176 iurev0 = 1;
177 printf_filtered(" simulating IU rev.0 jmpl/restore bug\n");
178 }
179 #endif
180 #ifdef MECREV0
181 if (strcmp(argv[stat], "-mecrev0") == 0) {
182 mecrev0 = 1;
183 printf_filtered(" simulating MEC rev.0 timer and uart interrupt bug\n");
184 }
185 #endif
186 if (strcmp(argv[stat], "-nfp") == 0) {
187 printf_filtered("no FPU\n");
188 nfp = 1;
189 }
190 if (strcmp(argv[stat], "-uart1") == 0) {
191 if ((stat + 1) < argc)
192 strcpy(uart_dev1, argv[++stat]);
193 }
194 if (strcmp(argv[stat], "-uart2") == 0) {
195 if ((stat + 1) < argc)
196 strcpy(uart_dev2, argv[++stat]);
197 }
198 if (strcmp(argv[stat], "-nogdb") == 0) {
199 printf_filtered("disabling GDB trap handling for breakpoints\n");
200 sis_gdb_break = 0;
201 }
202 if (strcmp(argv[stat], "-freq") == 0)
203 if ((stat + 1) < argc) {
204 freq = VAL(argv[++stat]);
205 printf_filtered(" ERC32 freq %d Mhz\n", freq);
206 }
207 } else
208 bfd_load(argv[stat]);
209 stat++;
210 }
211 freeargv(argv);
212 sregs.freq = freq;
213
214 INIT_DISASSEMBLE_INFO(dinfo, stdout, fprintf);
215 init_signals();
216 reset_all();
217 ebase.simtime = 0;
218 init_sim();
219 init_bpt(&sregs);
220 reset_stat(&sregs);
221 }
222
223 void
224 sim_close(int quitting)
225 {
226
227 exit_sim();
228
229 };
230
231 int
232 sim_load(char *prog, int from_tty)
233 {
234 bfd_load(*prog);
235 return (0);
236 }
237
238 void
239 sim_create_inferior(int start_address, char **argv, char **env)
240 {
241 ebase.simtime = 0;
242 reset_all();
243 reset_stat(&sregs);
244 sregs.pc = start_address & ~3;
245 sregs.npc = sregs.pc + 4;
246
247 }
248
249 void
250 sim_store_register(regno, value)
251 int regno;
252 unsigned char *value;
253 {
254 /* FIXME: Review the computation of regval. */
255 int regval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
256 set_regi(&sregs, regno, regval);
257 }
258
259
260 void
261 sim_fetch_register(regno, buf)
262 int regno;
263 unsigned char *buf;
264 {
265 get_regi(&sregs, regno, buf);
266 }
267
268 int
269 sim_write(mem, buf, length)
270 int mem;
271 unsigned char *buf;
272 int length;
273 {
274 return (sis_memory_write(mem, buf, length));
275 }
276
277 int
278 sim_read(int mem, unsigned char *buf, int length)
279 {
280 return (sis_memory_read(mem, buf, length));
281 }
282
283 void
284 sim_info(int verbose)
285 {
286 show_stat(&sregs);
287
288
289 }
290
291 int simstat = OK;
292
293 enum sim_stop {
294 sim_exited, sim_stopped, sim_signalled
295 };
296
297 void
298 sim_stop_reason(enum sim_stop * reason, int *sigrc)
299 {
300
301 switch (simstat) {
302 case CTRL_C:
303 *reason = sim_stopped;
304 *sigrc = SIGINT;
305 break;
306 case OK:
307 case TIME_OUT:
308 case BPT_HIT:
309 *reason = sim_stopped;
310 *sigrc = SIGTRAP;
311 break;
312 case ERROR:
313 *sigrc = 0;
314 *reason = sim_exited;
315 }
316 ctrl_c = 0;
317 simstat = OK;
318 }
319
320
321 void
322 sim_resume(int step, int siggnal)
323 {
324 simstat = run_sim(&sregs, 1, 0, 0);
325 }
326
327 void
328 sim_kill(void)
329 {
330 };
331
332
333
334 void
335 sim_do_command(cmd)
336 char *cmd;
337 {
338 exec_cmd(&sregs, cmd);
339 }
340
341
342
343 int
344 sim_insert_breakpoint(int addr)
345 {
346 if (sregs.bptnum < BPT_MAX) {
347 sregs.bpts[sregs.bptnum] = addr & ~0x3;
348 sregs.bptnum++;
349 if (sis_verbose)
350 printf_filtered("inserted HW BP at %x\n", addr);
351 return 0;
352 } else
353 return 1;
354 }
355
356 int
357 sim_remove_breakpoint(int addr)
358 {
359 int i = 0;
360
361 while ((i < sregs.bptnum) && (sregs.bpts[i] != addr))
362 i++;
363 if (addr == sregs.bpts[i]) {
364 for (; i < sregs.bptnum - 1; i++)
365 sregs.bpts[i] = sregs.bpts[i + 1];
366 sregs.bptnum -= 1;
367 if (sis_verbose)
368 printf_filtered("removed HW BP at %x\n", addr);
369 return 0;
370 }
371 return 1;
372 }