func.c revision 1.9 1 1.5 christos /* This file is part of SIS (SPARC instruction simulator)
2 1.5 christos
3 1.9 christos Copyright (C) 1995-2020 Free Software Foundation, Inc.
4 1.5 christos Contributed by Jiri Gaisler, European Space Agency
5 1.5 christos
6 1.5 christos This program is free software; you can redistribute it and/or modify
7 1.5 christos it under the terms of the GNU General Public License as published by
8 1.5 christos the Free Software Foundation; either version 3 of the License, or
9 1.5 christos (at your option) any later version.
10 1.5 christos
11 1.5 christos This program is distributed in the hope that it will be useful,
12 1.5 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.5 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.5 christos GNU General Public License for more details.
15 1.5 christos
16 1.5 christos You should have received a copy of the GNU General Public License
17 1.5 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 1.1 christos
19 1.1 christos #include "config.h"
20 1.1 christos #include <signal.h>
21 1.1 christos #include <string.h>
22 1.1 christos #include <stdio.h>
23 1.1 christos #include <stdlib.h>
24 1.1 christos #include <ctype.h>
25 1.1 christos #include "sis.h"
26 1.1 christos #include <dis-asm.h>
27 1.1 christos #include "sim-config.h"
28 1.5 christos #include <inttypes.h>
29 1.1 christos
30 1.1 christos #define VAL(x) strtoul(x,(char **)NULL,0)
31 1.1 christos
32 1.1 christos struct disassemble_info dinfo;
33 1.1 christos struct pstate sregs;
34 1.1 christos extern struct estate ebase;
35 1.1 christos int ctrl_c = 0;
36 1.1 christos int sis_verbose = 0;
37 1.1 christos char *sis_version = "2.7.5";
38 1.1 christos int nfp = 0;
39 1.1 christos int ift = 0;
40 1.1 christos int wrp = 0;
41 1.1 christos int rom8 = 0;
42 1.1 christos int uben = 0;
43 1.1 christos int termsave;
44 1.1 christos int sparclite = 0; /* emulating SPARClite instructions? */
45 1.1 christos int sparclite_board = 0; /* emulating SPARClite board RAM? */
46 1.1 christos char uart_dev1[128] = "";
47 1.1 christos char uart_dev2[128] = "";
48 1.1 christos extern int ext_irl;
49 1.1 christos uint32 last_load_addr = 0;
50 1.1 christos
51 1.1 christos #ifdef ERRINJ
52 1.1 christos uint32 errcnt = 0;
53 1.1 christos uint32 errper = 0;
54 1.1 christos uint32 errtt = 0;
55 1.1 christos uint32 errftt = 0;
56 1.1 christos uint32 errmec = 0;
57 1.1 christos #endif
58 1.1 christos
59 1.1 christos /* Forward declarations */
60 1.1 christos
61 1.1 christos static int batch (struct pstate *sregs, char *fname);
62 1.1 christos static void set_rega (struct pstate *sregs, char *reg, uint32 rval);
63 1.1 christos static void disp_reg (struct pstate *sregs, char *reg);
64 1.1 christos static uint32 limcalc (float32 freq);
65 1.1 christos static void int_handler (int32 sig);
66 1.1 christos static void init_event (void);
67 1.1 christos static int disp_fpu (struct pstate *sregs);
68 1.1 christos static void disp_regs (struct pstate *sregs, int cwp);
69 1.1 christos static void disp_ctrl (struct pstate *sregs);
70 1.1 christos static void disp_mem (uint32 addr, uint32 len);
71 1.1 christos
72 1.1 christos static int
73 1.1 christos batch(sregs, fname)
74 1.1 christos struct pstate *sregs;
75 1.1 christos char *fname;
76 1.1 christos {
77 1.1 christos FILE *fp;
78 1.5 christos char *lbuf = NULL;
79 1.5 christos size_t len = 0;
80 1.5 christos size_t slen;
81 1.1 christos
82 1.1 christos if ((fp = fopen(fname, "r")) == NULL) {
83 1.1 christos fprintf(stderr, "couldn't open batch file %s\n", fname);
84 1.5 christos return 0;
85 1.1 christos }
86 1.5 christos while (getline(&lbuf, &len, fp) > -1) {
87 1.5 christos slen = strlen(lbuf);
88 1.5 christos if (slen && (lbuf[slen - 1] == '\n')) {
89 1.5 christos lbuf[slen - 1] = 0;
90 1.5 christos printf("sis> %s\n", lbuf);
91 1.5 christos exec_cmd(sregs, lbuf);
92 1.5 christos }
93 1.1 christos }
94 1.5 christos free(lbuf);
95 1.1 christos fclose(fp);
96 1.5 christos return 1;
97 1.1 christos }
98 1.1 christos
99 1.1 christos void
100 1.1 christos set_regi(sregs, reg, rval)
101 1.1 christos struct pstate *sregs;
102 1.1 christos int32 reg;
103 1.1 christos uint32 rval;
104 1.1 christos {
105 1.1 christos uint32 cwp;
106 1.1 christos
107 1.1 christos cwp = ((sregs->psr & 0x7) << 4);
108 1.1 christos if ((reg > 0) && (reg < 8)) {
109 1.1 christos sregs->g[reg] = rval;
110 1.1 christos } else if ((reg >= 8) && (reg < 32)) {
111 1.1 christos sregs->r[(cwp + reg) & 0x7f] = rval;
112 1.1 christos } else if ((reg >= 32) && (reg < 64)) {
113 1.1 christos sregs->fsi[reg - 32] = rval;
114 1.1 christos } else {
115 1.1 christos switch (reg) {
116 1.1 christos case 64:
117 1.1 christos sregs->y = rval;
118 1.1 christos break;
119 1.1 christos case 65:
120 1.1 christos sregs->psr = rval;
121 1.1 christos break;
122 1.1 christos case 66:
123 1.1 christos sregs->wim = rval;
124 1.1 christos break;
125 1.1 christos case 67:
126 1.1 christos sregs->tbr = rval;
127 1.1 christos break;
128 1.1 christos case 68:
129 1.1 christos sregs->pc = rval;
130 1.1 christos break;
131 1.1 christos case 69:
132 1.1 christos sregs->npc = rval;
133 1.1 christos break;
134 1.1 christos case 70:
135 1.1 christos sregs->fsr = rval;
136 1.1 christos set_fsr(rval);
137 1.1 christos break;
138 1.1 christos default:break;
139 1.1 christos }
140 1.1 christos }
141 1.1 christos }
142 1.1 christos
143 1.1 christos void
144 1.1 christos get_regi(struct pstate * sregs, int32 reg, char *buf)
145 1.1 christos {
146 1.1 christos uint32 cwp;
147 1.1 christos uint32 rval = 0;
148 1.1 christos
149 1.1 christos cwp = ((sregs->psr & 0x7) << 4);
150 1.1 christos if ((reg >= 0) && (reg < 8)) {
151 1.1 christos rval = sregs->g[reg];
152 1.1 christos } else if ((reg >= 8) && (reg < 32)) {
153 1.1 christos rval = sregs->r[(cwp + reg) & 0x7f];
154 1.1 christos } else if ((reg >= 32) && (reg < 64)) {
155 1.1 christos rval = sregs->fsi[reg - 32];
156 1.1 christos } else {
157 1.1 christos switch (reg) {
158 1.1 christos case 64:
159 1.1 christos rval = sregs->y;
160 1.1 christos break;
161 1.1 christos case 65:
162 1.1 christos rval = sregs->psr;
163 1.1 christos break;
164 1.1 christos case 66:
165 1.1 christos rval = sregs->wim;
166 1.1 christos break;
167 1.1 christos case 67:
168 1.1 christos rval = sregs->tbr;
169 1.1 christos break;
170 1.1 christos case 68:
171 1.1 christos rval = sregs->pc;
172 1.1 christos break;
173 1.1 christos case 69:
174 1.1 christos rval = sregs->npc;
175 1.1 christos break;
176 1.1 christos case 70:
177 1.1 christos rval = sregs->fsr;
178 1.1 christos break;
179 1.1 christos default:break;
180 1.1 christos }
181 1.1 christos }
182 1.5 christos buf[0] = (rval >> 24) & 0x0ff;
183 1.5 christos buf[1] = (rval >> 16) & 0x0ff;
184 1.5 christos buf[2] = (rval >> 8) & 0x0ff;
185 1.5 christos buf[3] = rval & 0x0ff;
186 1.1 christos }
187 1.1 christos
188 1.1 christos
189 1.1 christos static void
190 1.1 christos set_rega(sregs, reg, rval)
191 1.1 christos struct pstate *sregs;
192 1.1 christos char *reg;
193 1.1 christos uint32 rval;
194 1.1 christos {
195 1.1 christos uint32 cwp;
196 1.1 christos int32 err = 0;
197 1.1 christos
198 1.1 christos cwp = ((sregs->psr & 0x7) << 4);
199 1.1 christos if (strcmp(reg, "psr") == 0)
200 1.1 christos sregs->psr = (rval = (rval & 0x00f03fff));
201 1.1 christos else if (strcmp(reg, "tbr") == 0)
202 1.1 christos sregs->tbr = (rval = (rval & 0xfffffff0));
203 1.1 christos else if (strcmp(reg, "wim") == 0)
204 1.1 christos sregs->wim = (rval = (rval & 0x0ff));
205 1.1 christos else if (strcmp(reg, "y") == 0)
206 1.1 christos sregs->y = rval;
207 1.1 christos else if (strcmp(reg, "pc") == 0)
208 1.1 christos sregs->pc = rval;
209 1.1 christos else if (strcmp(reg, "npc") == 0)
210 1.1 christos sregs->npc = rval;
211 1.1 christos else if (strcmp(reg, "fsr") == 0) {
212 1.1 christos sregs->fsr = rval;
213 1.1 christos set_fsr(rval);
214 1.1 christos } else if (strcmp(reg, "g0") == 0)
215 1.1 christos err = 2;
216 1.1 christos else if (strcmp(reg, "g1") == 0)
217 1.1 christos sregs->g[1] = rval;
218 1.1 christos else if (strcmp(reg, "g2") == 0)
219 1.1 christos sregs->g[2] = rval;
220 1.1 christos else if (strcmp(reg, "g3") == 0)
221 1.1 christos sregs->g[3] = rval;
222 1.1 christos else if (strcmp(reg, "g4") == 0)
223 1.1 christos sregs->g[4] = rval;
224 1.1 christos else if (strcmp(reg, "g5") == 0)
225 1.1 christos sregs->g[5] = rval;
226 1.1 christos else if (strcmp(reg, "g6") == 0)
227 1.1 christos sregs->g[6] = rval;
228 1.1 christos else if (strcmp(reg, "g7") == 0)
229 1.1 christos sregs->g[7] = rval;
230 1.1 christos else if (strcmp(reg, "o0") == 0)
231 1.1 christos sregs->r[(cwp + 8) & 0x7f] = rval;
232 1.1 christos else if (strcmp(reg, "o1") == 0)
233 1.1 christos sregs->r[(cwp + 9) & 0x7f] = rval;
234 1.1 christos else if (strcmp(reg, "o2") == 0)
235 1.1 christos sregs->r[(cwp + 10) & 0x7f] = rval;
236 1.1 christos else if (strcmp(reg, "o3") == 0)
237 1.1 christos sregs->r[(cwp + 11) & 0x7f] = rval;
238 1.1 christos else if (strcmp(reg, "o4") == 0)
239 1.1 christos sregs->r[(cwp + 12) & 0x7f] = rval;
240 1.1 christos else if (strcmp(reg, "o5") == 0)
241 1.1 christos sregs->r[(cwp + 13) & 0x7f] = rval;
242 1.1 christos else if (strcmp(reg, "o6") == 0)
243 1.1 christos sregs->r[(cwp + 14) & 0x7f] = rval;
244 1.1 christos else if (strcmp(reg, "o7") == 0)
245 1.1 christos sregs->r[(cwp + 15) & 0x7f] = rval;
246 1.1 christos else if (strcmp(reg, "l0") == 0)
247 1.1 christos sregs->r[(cwp + 16) & 0x7f] = rval;
248 1.1 christos else if (strcmp(reg, "l1") == 0)
249 1.1 christos sregs->r[(cwp + 17) & 0x7f] = rval;
250 1.1 christos else if (strcmp(reg, "l2") == 0)
251 1.1 christos sregs->r[(cwp + 18) & 0x7f] = rval;
252 1.1 christos else if (strcmp(reg, "l3") == 0)
253 1.1 christos sregs->r[(cwp + 19) & 0x7f] = rval;
254 1.1 christos else if (strcmp(reg, "l4") == 0)
255 1.1 christos sregs->r[(cwp + 20) & 0x7f] = rval;
256 1.1 christos else if (strcmp(reg, "l5") == 0)
257 1.1 christos sregs->r[(cwp + 21) & 0x7f] = rval;
258 1.1 christos else if (strcmp(reg, "l6") == 0)
259 1.1 christos sregs->r[(cwp + 22) & 0x7f] = rval;
260 1.1 christos else if (strcmp(reg, "l7") == 0)
261 1.1 christos sregs->r[(cwp + 23) & 0x7f] = rval;
262 1.1 christos else if (strcmp(reg, "i0") == 0)
263 1.1 christos sregs->r[(cwp + 24) & 0x7f] = rval;
264 1.1 christos else if (strcmp(reg, "i1") == 0)
265 1.1 christos sregs->r[(cwp + 25) & 0x7f] = rval;
266 1.1 christos else if (strcmp(reg, "i2") == 0)
267 1.1 christos sregs->r[(cwp + 26) & 0x7f] = rval;
268 1.1 christos else if (strcmp(reg, "i3") == 0)
269 1.1 christos sregs->r[(cwp + 27) & 0x7f] = rval;
270 1.1 christos else if (strcmp(reg, "i4") == 0)
271 1.1 christos sregs->r[(cwp + 28) & 0x7f] = rval;
272 1.1 christos else if (strcmp(reg, "i5") == 0)
273 1.1 christos sregs->r[(cwp + 29) & 0x7f] = rval;
274 1.1 christos else if (strcmp(reg, "i6") == 0)
275 1.1 christos sregs->r[(cwp + 30) & 0x7f] = rval;
276 1.1 christos else if (strcmp(reg, "i7") == 0)
277 1.1 christos sregs->r[(cwp + 31) & 0x7f] = rval;
278 1.1 christos else
279 1.1 christos err = 1;
280 1.1 christos switch (err) {
281 1.1 christos case 0:
282 1.1 christos printf("%s = %d (0x%08x)\n", reg, rval, rval);
283 1.1 christos break;
284 1.1 christos case 1:
285 1.1 christos printf("no such regiser: %s\n", reg);
286 1.1 christos break;
287 1.1 christos case 2:
288 1.1 christos printf("cannot set g0\n");
289 1.1 christos break;
290 1.1 christos default:
291 1.1 christos break;
292 1.1 christos }
293 1.1 christos
294 1.1 christos }
295 1.1 christos
296 1.1 christos static void
297 1.1 christos disp_reg(sregs, reg)
298 1.1 christos struct pstate *sregs;
299 1.1 christos char *reg;
300 1.1 christos {
301 1.1 christos if (strncmp(reg, "w",1) == 0)
302 1.1 christos disp_regs(sregs, VAL(®[1]));
303 1.1 christos }
304 1.1 christos
305 1.1 christos #ifdef ERRINJ
306 1.1 christos
307 1.1 christos void
308 1.1 christos errinj()
309 1.1 christos {
310 1.1 christos int err;
311 1.1 christos
312 1.1 christos switch (err = (random() % 12)) {
313 1.1 christos case 0: errtt = 0x61; break;
314 1.1 christos case 1: errtt = 0x62; break;
315 1.1 christos case 2: errtt = 0x63; break;
316 1.1 christos case 3: errtt = 0x64; break;
317 1.1 christos case 4: errtt = 0x65; break;
318 1.1 christos case 5:
319 1.1 christos case 6:
320 1.1 christos case 7: errftt = err;
321 1.1 christos break;
322 1.1 christos case 8: errmec = 1; break;
323 1.1 christos case 9: errmec = 2; break;
324 1.1 christos case 10: errmec = 5; break;
325 1.1 christos case 11: errmec = 6; break;
326 1.1 christos }
327 1.1 christos errcnt++;
328 1.1 christos if (errper) event(errinj, 0, (random()%errper));
329 1.1 christos }
330 1.1 christos
331 1.1 christos void
332 1.1 christos errinjstart()
333 1.1 christos {
334 1.1 christos if (errper) event(errinj, 0, (random()%errper));
335 1.1 christos }
336 1.1 christos
337 1.1 christos #endif
338 1.1 christos
339 1.1 christos static uint32
340 1.1 christos limcalc (freq)
341 1.1 christos float32 freq;
342 1.1 christos {
343 1.1 christos uint32 unit, lim;
344 1.1 christos double flim;
345 1.1 christos char *cmd1, *cmd2;
346 1.1 christos
347 1.1 christos unit = 1;
348 1.1 christos lim = -1;
349 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
350 1.1 christos lim = VAL(cmd1);
351 1.1 christos if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
352 1.1 christos if (strcmp(cmd2,"us")==0) unit = 1;
353 1.1 christos if (strcmp(cmd2,"ms")==0) unit = 1000;
354 1.1 christos if (strcmp(cmd2,"s")==0) unit = 1000000;
355 1.1 christos }
356 1.1 christos flim = (double) lim * (double) unit * (double) freq +
357 1.1 christos (double) ebase.simtime;
358 1.1 christos if ((flim > ebase.simtime) && (flim < 4294967296.0)) {
359 1.1 christos lim = (uint32) flim;
360 1.1 christos } else {
361 1.1 christos printf("error in expression\n");
362 1.1 christos lim = -1;
363 1.1 christos }
364 1.1 christos }
365 1.5 christos return lim;
366 1.1 christos }
367 1.5 christos
368 1.1 christos int
369 1.5 christos exec_cmd(struct pstate *sregs, const char *cmd)
370 1.1 christos {
371 1.1 christos char *cmd1, *cmd2;
372 1.1 christos int32 stat;
373 1.1 christos uint32 len, i, clen, j;
374 1.1 christos static uint32 daddr = 0;
375 1.5 christos char *cmdsave, *cmdsave2 = NULL;
376 1.1 christos
377 1.1 christos stat = OK;
378 1.1 christos cmdsave = strdup(cmd);
379 1.5 christos cmdsave2 = strdup (cmd);
380 1.5 christos if ((cmd1 = strtok (cmdsave2, " \t")) != NULL) {
381 1.1 christos clen = strlen(cmd1);
382 1.1 christos if (strncmp(cmd1, "bp", clen) == 0) {
383 1.1 christos for (i = 0; i < sregs->bptnum; i++) {
384 1.1 christos printf(" %d : 0x%08x\n", i + 1, sregs->bpts[i]);
385 1.1 christos }
386 1.1 christos } else if (strncmp(cmd1, "+bp", clen) == 0) {
387 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
388 1.1 christos sregs->bpts[sregs->bptnum] = VAL(cmd1) & ~0x3;
389 1.1 christos printf("added breakpoint %d at 0x%08x\n",
390 1.1 christos sregs->bptnum + 1, sregs->bpts[sregs->bptnum]);
391 1.1 christos sregs->bptnum += 1;
392 1.1 christos }
393 1.1 christos } else if (strncmp(cmd1, "-bp", clen) == 0) {
394 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
395 1.1 christos i = VAL(cmd1) - 1;
396 1.1 christos if ((i >= 0) && (i < sregs->bptnum)) {
397 1.1 christos printf("deleted breakpoint %d at 0x%08x\n", i + 1,
398 1.1 christos sregs->bpts[i]);
399 1.1 christos for (; i < sregs->bptnum - 1; i++) {
400 1.1 christos sregs->bpts[i] = sregs->bpts[i + 1];
401 1.1 christos }
402 1.1 christos sregs->bptnum -= 1;
403 1.1 christos }
404 1.1 christos }
405 1.1 christos } else if (strncmp(cmd1, "batch", clen) == 0) {
406 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
407 1.1 christos printf("no file specified\n");
408 1.1 christos } else {
409 1.1 christos batch(sregs, cmd1);
410 1.1 christos }
411 1.1 christos } else if (strncmp(cmd1, "cont", clen) == 0) {
412 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
413 1.1 christos stat = run_sim(sregs, UINT64_MAX, 0);
414 1.1 christos } else {
415 1.1 christos stat = run_sim(sregs, VAL(cmd1), 0);
416 1.1 christos }
417 1.1 christos daddr = sregs->pc;
418 1.1 christos sim_halt();
419 1.1 christos } else if (strncmp(cmd1, "debug", clen) == 0) {
420 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
421 1.1 christos sis_verbose = VAL(cmd1);
422 1.1 christos }
423 1.1 christos printf("Debug level = %d\n",sis_verbose);
424 1.1 christos } else if (strncmp(cmd1, "dis", clen) == 0) {
425 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
426 1.1 christos daddr = VAL(cmd1);
427 1.1 christos }
428 1.1 christos if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
429 1.1 christos len = VAL(cmd2);
430 1.1 christos } else
431 1.1 christos len = 16;
432 1.1 christos printf("\n");
433 1.1 christos dis_mem(daddr, len, &dinfo);
434 1.1 christos printf("\n");
435 1.1 christos daddr += len * 4;
436 1.1 christos } else if (strncmp(cmd1, "echo", clen) == 0) {
437 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
438 1.1 christos printf("%s\n", (&cmdsave[clen+1]));
439 1.1 christos }
440 1.1 christos #ifdef ERRINJ
441 1.1 christos } else if (strncmp(cmd1, "error", clen) == 0) {
442 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
443 1.1 christos errper = VAL(cmd1);
444 1.1 christos if (errper) {
445 1.1 christos event(errinj, 0, (len = (random()%errper)));
446 1.1 christos printf("Error injection started with period %d\n",len);
447 1.1 christos }
448 1.1 christos } else printf("Injected errors: %d\n",errcnt);
449 1.1 christos #endif
450 1.1 christos } else if (strncmp(cmd1, "float", clen) == 0) {
451 1.1 christos stat = disp_fpu(sregs);
452 1.1 christos } else if (strncmp(cmd1, "go", clen) == 0) {
453 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
454 1.1 christos len = last_load_addr;
455 1.1 christos } else {
456 1.1 christos len = VAL(cmd1);
457 1.1 christos }
458 1.1 christos sregs->pc = len & ~3;
459 1.1 christos sregs->npc = sregs->pc + 4;
460 1.5 christos if ((sregs->pc != 0) && (ebase.simtime == 0))
461 1.5 christos boot_init();
462 1.1 christos printf("resuming at 0x%08x\n",sregs->pc);
463 1.1 christos if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
464 1.1 christos stat = run_sim(sregs, VAL(cmd2), 0);
465 1.1 christos } else {
466 1.1 christos stat = run_sim(sregs, UINT64_MAX, 0);
467 1.1 christos }
468 1.1 christos daddr = sregs->pc;
469 1.1 christos sim_halt();
470 1.1 christos } else if (strncmp(cmd1, "help", clen) == 0) {
471 1.1 christos gen_help();
472 1.1 christos } else if (strncmp(cmd1, "history", clen) == 0) {
473 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
474 1.1 christos sregs->histlen = VAL(cmd1);
475 1.1 christos if (sregs->histbuf != NULL)
476 1.1 christos free(sregs->histbuf);
477 1.1 christos sregs->histbuf = (struct histype *) calloc(sregs->histlen, sizeof(struct histype));
478 1.1 christos printf("trace history length = %d\n\r", sregs->histlen);
479 1.1 christos sregs->histind = 0;
480 1.1 christos
481 1.1 christos } else {
482 1.1 christos j = sregs->histind;
483 1.1 christos for (i = 0; i < sregs->histlen; i++) {
484 1.1 christos if (j >= sregs->histlen)
485 1.1 christos j = 0;
486 1.1 christos printf(" %8d ", sregs->histbuf[j].time);
487 1.1 christos dis_mem(sregs->histbuf[j].addr, 1, &dinfo);
488 1.1 christos j++;
489 1.1 christos }
490 1.1 christos }
491 1.1 christos
492 1.1 christos } else if (strncmp(cmd1, "load", clen) == 0) {
493 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
494 1.1 christos last_load_addr = bfd_load(cmd1);
495 1.1 christos while ((cmd1 = strtok(NULL, " \t\n\r")) != NULL)
496 1.1 christos last_load_addr = bfd_load(cmd1);
497 1.1 christos } else {
498 1.1 christos printf("load: no file specified\n");
499 1.1 christos }
500 1.1 christos } else if (strncmp(cmd1, "mem", clen) == 0) {
501 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL)
502 1.1 christos daddr = VAL(cmd1);
503 1.1 christos if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL)
504 1.1 christos len = VAL(cmd2);
505 1.1 christos else
506 1.1 christos len = 64;
507 1.1 christos disp_mem(daddr, len);
508 1.1 christos daddr += len;
509 1.1 christos } else if (strncmp(cmd1, "perf", clen) == 0) {
510 1.1 christos cmd1 = strtok(NULL, " \t\n\r");
511 1.1 christos if ((cmd1 != NULL) &&
512 1.1 christos (strncmp(cmd1, "reset", strlen(cmd1)) == 0)) {
513 1.1 christos reset_stat(sregs);
514 1.1 christos } else
515 1.1 christos show_stat(sregs);
516 1.1 christos } else if (strncmp(cmd1, "quit", clen) == 0) {
517 1.1 christos exit(0);
518 1.1 christos } else if (strncmp(cmd1, "reg", clen) == 0) {
519 1.1 christos cmd1 = strtok(NULL, " \t\n\r");
520 1.1 christos cmd2 = strtok(NULL, " \t\n\r");
521 1.1 christos if (cmd2 != NULL)
522 1.1 christos set_rega(sregs, cmd1, VAL(cmd2));
523 1.1 christos else if (cmd1 != NULL)
524 1.1 christos disp_reg(sregs, cmd1);
525 1.1 christos else {
526 1.1 christos disp_regs(sregs,sregs->psr);
527 1.1 christos disp_ctrl(sregs);
528 1.1 christos }
529 1.1 christos } else if (strncmp(cmd1, "reset", clen) == 0) {
530 1.1 christos ebase.simtime = 0;
531 1.1 christos reset_all();
532 1.1 christos reset_stat(sregs);
533 1.1 christos } else if (strncmp(cmd1, "run", clen) == 0) {
534 1.1 christos ebase.simtime = 0;
535 1.1 christos reset_all();
536 1.1 christos reset_stat(sregs);
537 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
538 1.1 christos stat = run_sim(sregs, UINT64_MAX, 0);
539 1.1 christos } else {
540 1.1 christos stat = run_sim(sregs, VAL(cmd1), 0);
541 1.1 christos }
542 1.1 christos daddr = sregs->pc;
543 1.1 christos sim_halt();
544 1.1 christos } else if (strncmp(cmd1, "shell", clen) == 0) {
545 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
546 1.5 christos if (system(&cmdsave[clen])) {
547 1.5 christos /* Silence unused return value warning. */
548 1.5 christos }
549 1.1 christos }
550 1.1 christos } else if (strncmp(cmd1, "step", clen) == 0) {
551 1.1 christos stat = run_sim(sregs, 1, 1);
552 1.1 christos daddr = sregs->pc;
553 1.1 christos sim_halt();
554 1.1 christos } else if (strncmp(cmd1, "tcont", clen) == 0) {
555 1.1 christos sregs->tlimit = limcalc(sregs->freq);
556 1.1 christos stat = run_sim(sregs, UINT64_MAX, 0);
557 1.1 christos daddr = sregs->pc;
558 1.1 christos sim_halt();
559 1.1 christos } else if (strncmp(cmd1, "tgo", clen) == 0) {
560 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
561 1.1 christos len = last_load_addr;
562 1.1 christos } else {
563 1.1 christos len = VAL(cmd1);
564 1.1 christos sregs->tlimit = limcalc(sregs->freq);
565 1.1 christos }
566 1.1 christos sregs->pc = len & ~3;
567 1.1 christos sregs->npc = sregs->pc + 4;
568 1.1 christos printf("resuming at 0x%08x\n",sregs->pc);
569 1.1 christos stat = run_sim(sregs, UINT64_MAX, 0);
570 1.1 christos daddr = sregs->pc;
571 1.1 christos sim_halt();
572 1.1 christos } else if (strncmp(cmd1, "tlimit", clen) == 0) {
573 1.1 christos sregs->tlimit = limcalc(sregs->freq);
574 1.1 christos if (sregs->tlimit != (uint32) -1)
575 1.1 christos printf("simulation limit = %u (%.3f ms)\n",(uint32) sregs->tlimit,
576 1.1 christos sregs->tlimit / sregs->freq / 1000);
577 1.1 christos } else if (strncmp(cmd1, "tra", clen) == 0) {
578 1.1 christos if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
579 1.1 christos stat = run_sim(sregs, UINT64_MAX, 1);
580 1.1 christos } else {
581 1.1 christos stat = run_sim(sregs, VAL(cmd1), 1);
582 1.1 christos }
583 1.1 christos printf("\n");
584 1.1 christos daddr = sregs->pc;
585 1.1 christos sim_halt();
586 1.1 christos } else if (strncmp(cmd1, "trun", clen) == 0) {
587 1.1 christos ebase.simtime = 0;
588 1.1 christos reset_all();
589 1.1 christos reset_stat(sregs);
590 1.1 christos sregs->tlimit = limcalc(sregs->freq);
591 1.1 christos stat = run_sim(sregs, UINT64_MAX, 0);
592 1.1 christos daddr = sregs->pc;
593 1.1 christos sim_halt();
594 1.1 christos } else
595 1.1 christos printf("syntax error\n");
596 1.1 christos }
597 1.5 christos if (cmdsave2 != NULL)
598 1.5 christos free(cmdsave2);
599 1.1 christos if (cmdsave != NULL)
600 1.1 christos free(cmdsave);
601 1.5 christos return stat;
602 1.1 christos }
603 1.1 christos
604 1.1 christos
605 1.1 christos void
606 1.1 christos reset_stat(sregs)
607 1.1 christos struct pstate *sregs;
608 1.1 christos {
609 1.5 christos sregs->tottime = 0.0;
610 1.1 christos sregs->pwdtime = 0;
611 1.1 christos sregs->ninst = 0;
612 1.1 christos sregs->fholdt = 0;
613 1.1 christos sregs->holdt = 0;
614 1.1 christos sregs->icntt = 0;
615 1.1 christos sregs->finst = 0;
616 1.1 christos sregs->nstore = 0;
617 1.1 christos sregs->nload = 0;
618 1.1 christos sregs->nbranch = 0;
619 1.1 christos sregs->simstart = ebase.simtime;
620 1.1 christos
621 1.1 christos }
622 1.1 christos
623 1.1 christos void
624 1.1 christos show_stat(sregs)
625 1.1 christos struct pstate *sregs;
626 1.1 christos {
627 1.1 christos uint32 iinst;
628 1.5 christos uint32 stime;
629 1.1 christos
630 1.5 christos if (sregs->tottime == 0.0)
631 1.5 christos sregs->tottime += 1E-6;
632 1.1 christos stime = ebase.simtime - sregs->simstart; /* Total simulated time */
633 1.1 christos #ifdef STAT
634 1.1 christos
635 1.1 christos iinst = sregs->ninst - sregs->finst - sregs->nload - sregs->nstore -
636 1.1 christos sregs->nbranch;
637 1.1 christos #endif
638 1.1 christos
639 1.5 christos printf("\n Cycles : %9" PRIu64 "\n\r", ebase.simtime - sregs->simstart);
640 1.5 christos printf(" Instructions : %9" PRIu64 "\n", sregs->ninst);
641 1.1 christos
642 1.1 christos #ifdef STAT
643 1.1 christos printf(" integer : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst);
644 1.1 christos printf(" load : %9.2f %%\n",
645 1.1 christos 100.0 * (float) sregs->nload / (float) sregs->ninst);
646 1.1 christos printf(" store : %9.2f %%\n",
647 1.1 christos 100.0 * (float) sregs->nstore / (float) sregs->ninst);
648 1.1 christos printf(" branch : %9.2f %%\n",
649 1.1 christos 100.0 * (float) sregs->nbranch / (float) sregs->ninst);
650 1.1 christos printf(" float : %9.2f %%\n",
651 1.1 christos 100.0 * (float) sregs->finst / (float) sregs->ninst);
652 1.1 christos printf(" Integer CPI : %9.2f\n",
653 1.1 christos ((float) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst))
654 1.1 christos /
655 1.1 christos (float) (sregs->ninst - sregs->finst));
656 1.1 christos printf(" Float CPI : %9.2f\n",
657 1.1 christos ((float) sregs->fholdt / (float) sregs->finst) + 1.0);
658 1.1 christos #endif
659 1.1 christos printf(" Overall CPI : %9.2f\n",
660 1.1 christos (float) (stime - sregs->pwdtime) / (float) sregs->ninst);
661 1.1 christos printf("\n ERC32 performance (%4.1f MHz): %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n",
662 1.1 christos sregs->freq, sregs->freq * (float) sregs->ninst / (float) (stime - sregs->pwdtime),
663 1.1 christos sregs->freq * (float) (sregs->ninst - sregs->finst) /
664 1.1 christos (float) (stime - sregs->pwdtime),
665 1.1 christos sregs->freq * (float) sregs->finst / (float) (stime - sregs->pwdtime));
666 1.5 christos printf(" Simulated ERC32 time : %.2f s\n",
667 1.5 christos (float) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq);
668 1.5 christos printf(" Processor utilisation : %.2f %%\n",
669 1.5 christos 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime)));
670 1.5 christos printf(" Real-time performance : %.2f %%\n",
671 1.5 christos 100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6))));
672 1.5 christos printf(" Simulator performance : %.2f MIPS\n",
673 1.5 christos (double)(sregs->ninst) / sregs->tottime / 1E6);
674 1.5 christos printf(" Used time (sys + user) : %.2f s\n\n", sregs->tottime);
675 1.1 christos }
676 1.1 christos
677 1.1 christos
678 1.1 christos
679 1.1 christos void
680 1.1 christos init_bpt(sregs)
681 1.1 christos struct pstate *sregs;
682 1.1 christos {
683 1.1 christos sregs->bptnum = 0;
684 1.1 christos sregs->histlen = 0;
685 1.1 christos sregs->histind = 0;
686 1.1 christos sregs->histbuf = NULL;
687 1.1 christos sregs->tlimit = -1;
688 1.1 christos }
689 1.1 christos
690 1.1 christos static void
691 1.1 christos int_handler(sig)
692 1.1 christos int32 sig;
693 1.1 christos {
694 1.1 christos if (sig != 2)
695 1.1 christos printf("\n\n Signal handler error (%d)\n\n", sig);
696 1.1 christos ctrl_c = 1;
697 1.1 christos }
698 1.1 christos
699 1.1 christos void
700 1.1 christos init_signals()
701 1.1 christos {
702 1.1 christos typedef void (*PFI) ();
703 1.1 christos static PFI int_tab[2];
704 1.1 christos
705 1.1 christos int_tab[0] = signal(SIGTERM, int_handler);
706 1.1 christos int_tab[1] = signal(SIGINT, int_handler);
707 1.1 christos }
708 1.1 christos
709 1.1 christos
710 1.1 christos extern struct disassemble_info dinfo;
711 1.1 christos
712 1.1 christos struct estate ebase;
713 1.1 christos struct evcell evbuf[EVENT_MAX];
714 1.1 christos struct irqcell irqarr[16];
715 1.1 christos
716 1.1 christos static int
717 1.1 christos disp_fpu(sregs)
718 1.1 christos struct pstate *sregs;
719 1.1 christos {
720 1.1 christos
721 1.1 christos int i;
722 1.1 christos float t;
723 1.1 christos
724 1.1 christos printf("\n fsr: %08X\n\n", sregs->fsr);
725 1.1 christos
726 1.5 christos #ifdef HOST_LITTLE_ENDIAN
727 1.1 christos for (i = 0; i < 32; i++)
728 1.1 christos sregs->fdp[i ^ 1] = sregs->fs[i];
729 1.1 christos #endif
730 1.1 christos
731 1.1 christos for (i = 0; i < 32; i++) {
732 1.1 christos t = sregs->fs[i];
733 1.1 christos printf(" f%02d %08x %14e ", i, sregs->fsi[i], sregs->fs[i]);
734 1.1 christos if (!(i & 1))
735 1.1 christos printf("%14e\n", sregs->fd[i >> 1]);
736 1.1 christos else
737 1.1 christos printf("\n");
738 1.1 christos }
739 1.1 christos printf("\n");
740 1.5 christos return OK;
741 1.1 christos }
742 1.1 christos
743 1.1 christos static void
744 1.1 christos disp_regs(sregs,cwp)
745 1.1 christos struct pstate *sregs;
746 1.1 christos int cwp;
747 1.1 christos {
748 1.1 christos
749 1.1 christos int i;
750 1.1 christos
751 1.1 christos cwp = ((cwp & 0x7) << 4);
752 1.1 christos printf("\n\t INS LOCALS OUTS GLOBALS\n");
753 1.1 christos for (i = 0; i < 8; i++) {
754 1.1 christos printf(" %d: %08X %08X %08X %08X\n", i,
755 1.1 christos sregs->r[(cwp + i + 24) & 0x7f],
756 1.1 christos sregs->r[(cwp + i + 16) & 0x7f], sregs->r[(cwp + i + 8) & 0x7f],
757 1.1 christos sregs->g[i]);
758 1.1 christos }
759 1.1 christos }
760 1.1 christos
761 1.5 christos static void print_insn_sparc_sis(uint32 addr, struct disassemble_info *info)
762 1.5 christos {
763 1.5 christos unsigned char i[4];
764 1.5 christos
765 1.5 christos sis_memory_read(addr, i, 4);
766 1.5 christos dinfo.buffer_vma = addr;
767 1.5 christos dinfo.buffer_length = 4;
768 1.5 christos dinfo.buffer = i;
769 1.5 christos print_insn_sparc(addr, info);
770 1.5 christos }
771 1.5 christos
772 1.1 christos static void
773 1.1 christos disp_ctrl(sregs)
774 1.1 christos struct pstate *sregs;
775 1.1 christos {
776 1.1 christos
777 1.5 christos uint32 i;
778 1.1 christos
779 1.1 christos printf("\n psr: %08X wim: %08X tbr: %08X y: %08X\n",
780 1.1 christos sregs->psr, sregs->wim, sregs->tbr, sregs->y);
781 1.5 christos sis_memory_read (sregs->pc, (char *) &i, 4);
782 1.5 christos printf ("\n pc: %08X = %08X ", sregs->pc, i);
783 1.5 christos print_insn_sparc_sis(sregs->pc, &dinfo);
784 1.5 christos sis_memory_read (sregs->npc, (char *) &i, 4);
785 1.5 christos printf ("\n npc: %08X = %08X ", sregs->npc, i);
786 1.5 christos print_insn_sparc_sis(sregs->npc, &dinfo);
787 1.1 christos if (sregs->err_mode)
788 1.1 christos printf("\n IU in error mode");
789 1.1 christos printf("\n\n");
790 1.1 christos }
791 1.1 christos
792 1.1 christos static void
793 1.1 christos disp_mem(addr, len)
794 1.1 christos uint32 addr;
795 1.1 christos uint32 len;
796 1.1 christos {
797 1.1 christos
798 1.1 christos uint32 i;
799 1.5 christos union {
800 1.5 christos unsigned char u8[4];
801 1.5 christos uint32 u32;
802 1.5 christos } data;
803 1.1 christos uint32 mem[4], j;
804 1.1 christos char *p;
805 1.1 christos
806 1.1 christos for (i = addr & ~3; i < ((addr + len) & ~3); i += 16) {
807 1.1 christos printf("\n %8X ", i);
808 1.1 christos for (j = 0; j < 4; j++) {
809 1.5 christos sis_memory_read ((i + (j * 4)), data.u8, 4);
810 1.5 christos printf ("%08x ", data.u32);
811 1.5 christos mem[j] = data.u32;
812 1.1 christos }
813 1.1 christos printf(" ");
814 1.1 christos p = (char *) mem;
815 1.1 christos for (j = 0; j < 16; j++) {
816 1.5 christos if (isprint (p[j ^ EBT]))
817 1.5 christos putchar (p[j ^ EBT]);
818 1.1 christos else
819 1.1 christos putchar('.');
820 1.1 christos }
821 1.1 christos }
822 1.1 christos printf("\n\n");
823 1.1 christos }
824 1.1 christos
825 1.1 christos void
826 1.1 christos dis_mem(addr, len, info)
827 1.1 christos uint32 addr;
828 1.1 christos uint32 len;
829 1.1 christos struct disassemble_info *info;
830 1.1 christos {
831 1.1 christos uint32 i;
832 1.5 christos union {
833 1.5 christos unsigned char u8[4];
834 1.5 christos uint32 u32;
835 1.5 christos } data;
836 1.1 christos
837 1.1 christos for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) {
838 1.5 christos sis_memory_read (i, data.u8, 4);
839 1.5 christos printf (" %08x %08x ", i, data.u32);
840 1.5 christos print_insn_sparc_sis(i, info);
841 1.1 christos if (i >= 0xfffffffc) break;
842 1.1 christos printf("\n");
843 1.1 christos }
844 1.1 christos }
845 1.1 christos
846 1.1 christos /* Add event to event queue */
847 1.1 christos
848 1.1 christos void
849 1.1 christos event(cfunc, arg, delta)
850 1.1 christos void (*cfunc) ();
851 1.1 christos int32 arg;
852 1.1 christos uint64 delta;
853 1.1 christos {
854 1.1 christos struct evcell *ev1, *evins;
855 1.1 christos
856 1.1 christos if (ebase.freeq == NULL) {
857 1.1 christos printf("Error, too many events in event queue\n");
858 1.1 christos return;
859 1.1 christos }
860 1.1 christos ev1 = &ebase.eq;
861 1.1 christos delta += ebase.simtime;
862 1.1 christos while ((ev1->nxt != NULL) && (ev1->nxt->time <= delta)) {
863 1.1 christos ev1 = ev1->nxt;
864 1.1 christos }
865 1.1 christos if (ev1->nxt == NULL) {
866 1.1 christos ev1->nxt = ebase.freeq;
867 1.1 christos ebase.freeq = ebase.freeq->nxt;
868 1.1 christos ev1->nxt->nxt = NULL;
869 1.1 christos } else {
870 1.1 christos evins = ebase.freeq;
871 1.1 christos ebase.freeq = ebase.freeq->nxt;
872 1.1 christos evins->nxt = ev1->nxt;
873 1.1 christos ev1->nxt = evins;
874 1.1 christos }
875 1.1 christos ev1->nxt->time = delta;
876 1.1 christos ev1->nxt->cfunc = cfunc;
877 1.1 christos ev1->nxt->arg = arg;
878 1.1 christos }
879 1.1 christos
880 1.1 christos #if 0 /* apparently not used */
881 1.1 christos void
882 1.1 christos stop_event()
883 1.1 christos {
884 1.1 christos }
885 1.1 christos #endif
886 1.1 christos
887 1.1 christos void
888 1.1 christos init_event()
889 1.1 christos {
890 1.1 christos int32 i;
891 1.1 christos
892 1.1 christos ebase.eq.nxt = NULL;
893 1.1 christos ebase.freeq = evbuf;
894 1.1 christos for (i = 0; i < EVENT_MAX; i++) {
895 1.1 christos evbuf[i].nxt = &evbuf[i + 1];
896 1.1 christos }
897 1.1 christos evbuf[EVENT_MAX - 1].nxt = NULL;
898 1.1 christos }
899 1.1 christos
900 1.1 christos void
901 1.1 christos set_int(level, callback, arg)
902 1.1 christos int32 level;
903 1.1 christos void (*callback) ();
904 1.1 christos int32 arg;
905 1.1 christos {
906 1.1 christos irqarr[level & 0x0f].callback = callback;
907 1.1 christos irqarr[level & 0x0f].arg = arg;
908 1.1 christos }
909 1.1 christos
910 1.1 christos /* Advance simulator time */
911 1.1 christos
912 1.1 christos void
913 1.1 christos advance_time(sregs)
914 1.1 christos struct pstate *sregs;
915 1.1 christos {
916 1.1 christos
917 1.1 christos struct evcell *evrem;
918 1.1 christos void (*cfunc) ();
919 1.1 christos uint32 arg;
920 1.1 christos uint64 endtime;
921 1.1 christos
922 1.1 christos #ifdef STAT
923 1.1 christos sregs->fholdt += sregs->fhold;
924 1.1 christos sregs->holdt += sregs->hold;
925 1.1 christos sregs->icntt += sregs->icnt;
926 1.1 christos #endif
927 1.1 christos
928 1.1 christos endtime = ebase.simtime + sregs->icnt + sregs->hold + sregs->fhold;
929 1.1 christos
930 1.1 christos while ((ebase.eq.nxt->time <= (endtime)) && (ebase.eq.nxt != NULL)) {
931 1.1 christos ebase.simtime = ebase.eq.nxt->time;
932 1.1 christos cfunc = ebase.eq.nxt->cfunc;
933 1.1 christos arg = ebase.eq.nxt->arg;
934 1.1 christos evrem = ebase.eq.nxt;
935 1.1 christos ebase.eq.nxt = ebase.eq.nxt->nxt;
936 1.1 christos evrem->nxt = ebase.freeq;
937 1.1 christos ebase.freeq = evrem;
938 1.1 christos cfunc(arg);
939 1.1 christos }
940 1.1 christos ebase.simtime = endtime;
941 1.1 christos
942 1.1 christos }
943 1.1 christos
944 1.1 christos uint32
945 1.1 christos now()
946 1.1 christos {
947 1.5 christos return ebase.simtime;
948 1.1 christos }
949 1.1 christos
950 1.1 christos
951 1.1 christos /* Advance time until an external interrupt is seen */
952 1.1 christos
953 1.1 christos int
954 1.1 christos wait_for_irq()
955 1.1 christos {
956 1.1 christos struct evcell *evrem;
957 1.1 christos void (*cfunc) ();
958 1.1 christos int32 arg;
959 1.1 christos uint64 endtime;
960 1.1 christos
961 1.1 christos if (ebase.eq.nxt == NULL)
962 1.1 christos printf("Warning: event queue empty - power-down mode not entered\n");
963 1.1 christos endtime = ebase.simtime;
964 1.1 christos while (!ext_irl && (ebase.eq.nxt != NULL)) {
965 1.1 christos ebase.simtime = ebase.eq.nxt->time;
966 1.1 christos cfunc = ebase.eq.nxt->cfunc;
967 1.1 christos arg = ebase.eq.nxt->arg;
968 1.1 christos evrem = ebase.eq.nxt;
969 1.1 christos ebase.eq.nxt = ebase.eq.nxt->nxt;
970 1.1 christos evrem->nxt = ebase.freeq;
971 1.1 christos ebase.freeq = evrem;
972 1.1 christos cfunc(arg);
973 1.1 christos if (ctrl_c) {
974 1.1 christos printf("\bwarning: power-down mode interrupted\n");
975 1.1 christos break;
976 1.1 christos }
977 1.1 christos }
978 1.1 christos sregs.pwdtime += ebase.simtime - endtime;
979 1.5 christos return ebase.simtime - endtime;
980 1.1 christos }
981 1.1 christos
982 1.1 christos int
983 1.1 christos check_bpt(sregs)
984 1.1 christos struct pstate *sregs;
985 1.1 christos {
986 1.1 christos int32 i;
987 1.1 christos
988 1.1 christos if ((sregs->bphit) || (sregs->annul))
989 1.5 christos return 0;
990 1.1 christos for (i = 0; i < (int32) sregs->bptnum; i++) {
991 1.1 christos if (sregs->pc == sregs->bpts[i])
992 1.5 christos return BPT_HIT;
993 1.1 christos }
994 1.5 christos return 0;
995 1.1 christos }
996 1.1 christos
997 1.1 christos void
998 1.1 christos reset_all()
999 1.1 christos {
1000 1.1 christos init_event(); /* Clear event queue */
1001 1.1 christos init_regs(&sregs);
1002 1.1 christos reset();
1003 1.1 christos #ifdef ERRINJ
1004 1.1 christos errinjstart();
1005 1.1 christos #endif
1006 1.1 christos }
1007 1.1 christos
1008 1.1 christos void
1009 1.1 christos sys_reset()
1010 1.1 christos {
1011 1.1 christos reset_all();
1012 1.1 christos sregs.trap = 256; /* Force fake reset trap */
1013 1.1 christos }
1014 1.1 christos
1015 1.1 christos void
1016 1.1 christos sys_halt()
1017 1.1 christos {
1018 1.1 christos sregs.trap = 257; /* Force fake halt trap */
1019 1.1 christos }
1020 1.1 christos
1021 1.1 christos #include "ansidecl.h"
1022 1.1 christos
1023 1.1 christos #include <stdarg.h>
1024 1.1 christos
1025 1.1 christos #include "libiberty.h"
1026 1.1 christos #include "bfd.h"
1027 1.1 christos
1028 1.1 christos #define min(A, B) (((A) < (B)) ? (A) : (B))
1029 1.1 christos #define LOAD_ADDRESS 0
1030 1.1 christos
1031 1.1 christos int
1032 1.5 christos bfd_load (const char *fname)
1033 1.1 christos {
1034 1.1 christos asection *section;
1035 1.1 christos bfd *pbfd;
1036 1.1 christos const bfd_arch_info_type *arch;
1037 1.5 christos int i;
1038 1.1 christos
1039 1.1 christos pbfd = bfd_openr(fname, 0);
1040 1.1 christos
1041 1.1 christos if (pbfd == NULL) {
1042 1.1 christos printf("open of %s failed\n", fname);
1043 1.5 christos return -1;
1044 1.1 christos }
1045 1.1 christos if (!bfd_check_format(pbfd, bfd_object)) {
1046 1.1 christos printf("file %s doesn't seem to be an object file\n", fname);
1047 1.5 christos return -1;
1048 1.1 christos }
1049 1.1 christos
1050 1.1 christos arch = bfd_get_arch_info (pbfd);
1051 1.1 christos if (sis_verbose)
1052 1.1 christos printf("loading %s:", fname);
1053 1.1 christos for (section = pbfd->sections; section; section = section->next) {
1054 1.9 christos if (bfd_section_flags (section) & SEC_ALLOC) {
1055 1.1 christos bfd_vma section_address;
1056 1.1 christos unsigned long section_size;
1057 1.1 christos const char *section_name;
1058 1.1 christos
1059 1.9 christos section_name = bfd_section_name (section);
1060 1.1 christos
1061 1.9 christos section_address = bfd_section_vma (section);
1062 1.1 christos /*
1063 1.1 christos * Adjust sections from a.out files, since they don't carry their
1064 1.1 christos * addresses with.
1065 1.1 christos */
1066 1.1 christos if (bfd_get_flavour(pbfd) == bfd_target_aout_flavour) {
1067 1.1 christos if (strcmp (section_name, ".text") == 0)
1068 1.1 christos section_address = bfd_get_start_address (pbfd);
1069 1.1 christos else if (strcmp (section_name, ".data") == 0) {
1070 1.1 christos /* Read the first 8 bytes of the data section.
1071 1.1 christos There should be the string 'DaTa' followed by
1072 1.1 christos a word containing the actual section address. */
1073 1.1 christos struct data_marker
1074 1.1 christos {
1075 1.1 christos char signature[4]; /* 'DaTa' */
1076 1.1 christos unsigned char sdata[4]; /* &sdata */
1077 1.1 christos } marker;
1078 1.1 christos bfd_get_section_contents (pbfd, section, &marker, 0,
1079 1.1 christos sizeof (marker));
1080 1.1 christos if (strncmp (marker.signature, "DaTa", 4) == 0)
1081 1.1 christos {
1082 1.5 christos section_address = bfd_getb32 (marker.sdata);
1083 1.1 christos }
1084 1.1 christos }
1085 1.1 christos }
1086 1.1 christos
1087 1.9 christos section_size = bfd_section_size (section);
1088 1.1 christos
1089 1.1 christos if (sis_verbose)
1090 1.1 christos printf("\nsection %s at 0x%08lx (0x%lx bytes)",
1091 1.1 christos section_name, section_address, section_size);
1092 1.1 christos
1093 1.1 christos /* Text, data or lit */
1094 1.9 christos if (bfd_section_flags (section) & SEC_LOAD) {
1095 1.1 christos file_ptr fptr;
1096 1.1 christos
1097 1.1 christos fptr = 0;
1098 1.1 christos
1099 1.1 christos while (section_size > 0) {
1100 1.1 christos char buffer[1024];
1101 1.1 christos int count;
1102 1.1 christos
1103 1.1 christos count = min(section_size, 1024);
1104 1.1 christos
1105 1.1 christos bfd_get_section_contents(pbfd, section, buffer, fptr, count);
1106 1.1 christos
1107 1.5 christos for (i = 0; i < count; i++)
1108 1.5 christos sis_memory_write ((section_address + i) ^ EBT, &buffer[i], 1);
1109 1.1 christos
1110 1.1 christos section_address += count;
1111 1.1 christos fptr += count;
1112 1.1 christos section_size -= count;
1113 1.1 christos }
1114 1.1 christos } else /* BSS */
1115 1.1 christos if (sis_verbose)
1116 1.1 christos printf("(not loaded)");
1117 1.1 christos }
1118 1.1 christos }
1119 1.1 christos if (sis_verbose)
1120 1.1 christos printf("\n");
1121 1.1 christos
1122 1.5 christos return bfd_get_start_address (pbfd);
1123 1.5 christos }
1124 1.5 christos
1125 1.5 christos double get_time (void)
1126 1.5 christos {
1127 1.5 christos double usec;
1128 1.5 christos
1129 1.5 christos struct timeval tm;
1130 1.5 christos
1131 1.5 christos gettimeofday (&tm, NULL);
1132 1.5 christos usec = ((double) tm.tv_sec) * 1E6 + ((double) tm.tv_usec);
1133 1.5 christos return usec / 1E6;
1134 1.1 christos }
1135