1 /* This file is part of SIS (SPARC instruction simulator)
3 Copyright (C) 1995-2024 Free Software Foundation, Inc.
4 Contributed by Jiri Gaisler, European Space Agency
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 /* This must come before any other includes. */
29 #include "sim-config.h"
33 #define VAL(x) strtoul(x,(char **)NULL,0)
35 struct disassemble_info dinfo
;
37 extern struct estate ebase
;
40 char *sis_version
= "2.7.5";
47 int sparclite
= 0; /* emulating SPARClite instructions? */
48 int sparclite_board
= 0; /* emulating SPARClite board RAM? */
49 char uart_dev1
[128] = "";
50 char uart_dev2
[128] = "";
52 uint32_t last_load_addr
= 0;
62 /* Forward declarations */
64 static int batch (struct pstate
*sregs
, char *fname
);
65 static void set_rega (struct pstate
*sregs
, char *reg
, uint32_t rval
);
66 static void disp_reg (struct pstate
*sregs
, char *reg
);
67 static uint32_t limcalc (float32 freq
);
68 static void int_handler (int32_t sig
);
69 static void init_event (void);
70 static int disp_fpu (struct pstate
*sregs
);
71 static void disp_regs (struct pstate
*sregs
, int cwp
);
72 static void disp_ctrl (struct pstate
*sregs
);
73 static void disp_mem (uint32_t addr
, uint32_t len
);
76 batch(struct pstate
*sregs
, char *fname
)
83 if ((fp
= fopen(fname
, "r")) == NULL
) {
84 fprintf(stderr
, "couldn't open batch file %s\n", fname
);
87 while (getline(&lbuf
, &len
, fp
) > -1) {
89 if (slen
&& (lbuf
[slen
- 1] == '\n')) {
91 printf("sis> %s\n", lbuf
);
92 exec_cmd(sregs
, lbuf
);
101 set_regi(struct pstate
*sregs
, int32_t reg
, uint32_t rval
)
105 cwp
= ((sregs
->psr
& 0x7) << 4);
106 if ((reg
> 0) && (reg
< 8)) {
107 sregs
->g
[reg
] = rval
;
108 } else if ((reg
>= 8) && (reg
< 32)) {
109 sregs
->r
[(cwp
+ reg
) & 0x7f] = rval
;
110 } else if ((reg
>= 32) && (reg
< 64)) {
111 sregs
->fsi
[reg
- 32] = rval
;
142 get_regi(struct pstate
* sregs
, int32_t reg
, unsigned char *buf
)
147 cwp
= ((sregs
->psr
& 0x7) << 4);
148 if ((reg
>= 0) && (reg
< 8)) {
149 rval
= sregs
->g
[reg
];
150 } else if ((reg
>= 8) && (reg
< 32)) {
151 rval
= sregs
->r
[(cwp
+ reg
) & 0x7f];
152 } else if ((reg
>= 32) && (reg
< 64)) {
153 rval
= sregs
->fsi
[reg
- 32];
180 buf
[0] = (rval
>> 24) & 0x0ff;
181 buf
[1] = (rval
>> 16) & 0x0ff;
182 buf
[2] = (rval
>> 8) & 0x0ff;
183 buf
[3] = rval
& 0x0ff;
188 set_rega(struct pstate
*sregs
, char *reg
, uint32_t rval
)
193 cwp
= ((sregs
->psr
& 0x7) << 4);
194 if (strcmp(reg
, "psr") == 0)
195 sregs
->psr
= (rval
= (rval
& 0x00f03fff));
196 else if (strcmp(reg
, "tbr") == 0)
197 sregs
->tbr
= (rval
= (rval
& 0xfffffff0));
198 else if (strcmp(reg
, "wim") == 0)
199 sregs
->wim
= (rval
= (rval
& 0x0ff));
200 else if (strcmp(reg
, "y") == 0)
202 else if (strcmp(reg
, "pc") == 0)
204 else if (strcmp(reg
, "npc") == 0)
206 else if (strcmp(reg
, "fsr") == 0) {
209 } else if (strcmp(reg
, "g0") == 0)
211 else if (strcmp(reg
, "g1") == 0)
213 else if (strcmp(reg
, "g2") == 0)
215 else if (strcmp(reg
, "g3") == 0)
217 else if (strcmp(reg
, "g4") == 0)
219 else if (strcmp(reg
, "g5") == 0)
221 else if (strcmp(reg
, "g6") == 0)
223 else if (strcmp(reg
, "g7") == 0)
225 else if (strcmp(reg
, "o0") == 0)
226 sregs
->r
[(cwp
+ 8) & 0x7f] = rval
;
227 else if (strcmp(reg
, "o1") == 0)
228 sregs
->r
[(cwp
+ 9) & 0x7f] = rval
;
229 else if (strcmp(reg
, "o2") == 0)
230 sregs
->r
[(cwp
+ 10) & 0x7f] = rval
;
231 else if (strcmp(reg
, "o3") == 0)
232 sregs
->r
[(cwp
+ 11) & 0x7f] = rval
;
233 else if (strcmp(reg
, "o4") == 0)
234 sregs
->r
[(cwp
+ 12) & 0x7f] = rval
;
235 else if (strcmp(reg
, "o5") == 0)
236 sregs
->r
[(cwp
+ 13) & 0x7f] = rval
;
237 else if (strcmp(reg
, "o6") == 0)
238 sregs
->r
[(cwp
+ 14) & 0x7f] = rval
;
239 else if (strcmp(reg
, "o7") == 0)
240 sregs
->r
[(cwp
+ 15) & 0x7f] = rval
;
241 else if (strcmp(reg
, "l0") == 0)
242 sregs
->r
[(cwp
+ 16) & 0x7f] = rval
;
243 else if (strcmp(reg
, "l1") == 0)
244 sregs
->r
[(cwp
+ 17) & 0x7f] = rval
;
245 else if (strcmp(reg
, "l2") == 0)
246 sregs
->r
[(cwp
+ 18) & 0x7f] = rval
;
247 else if (strcmp(reg
, "l3") == 0)
248 sregs
->r
[(cwp
+ 19) & 0x7f] = rval
;
249 else if (strcmp(reg
, "l4") == 0)
250 sregs
->r
[(cwp
+ 20) & 0x7f] = rval
;
251 else if (strcmp(reg
, "l5") == 0)
252 sregs
->r
[(cwp
+ 21) & 0x7f] = rval
;
253 else if (strcmp(reg
, "l6") == 0)
254 sregs
->r
[(cwp
+ 22) & 0x7f] = rval
;
255 else if (strcmp(reg
, "l7") == 0)
256 sregs
->r
[(cwp
+ 23) & 0x7f] = rval
;
257 else if (strcmp(reg
, "i0") == 0)
258 sregs
->r
[(cwp
+ 24) & 0x7f] = rval
;
259 else if (strcmp(reg
, "i1") == 0)
260 sregs
->r
[(cwp
+ 25) & 0x7f] = rval
;
261 else if (strcmp(reg
, "i2") == 0)
262 sregs
->r
[(cwp
+ 26) & 0x7f] = rval
;
263 else if (strcmp(reg
, "i3") == 0)
264 sregs
->r
[(cwp
+ 27) & 0x7f] = rval
;
265 else if (strcmp(reg
, "i4") == 0)
266 sregs
->r
[(cwp
+ 28) & 0x7f] = rval
;
267 else if (strcmp(reg
, "i5") == 0)
268 sregs
->r
[(cwp
+ 29) & 0x7f] = rval
;
269 else if (strcmp(reg
, "i6") == 0)
270 sregs
->r
[(cwp
+ 30) & 0x7f] = rval
;
271 else if (strcmp(reg
, "i7") == 0)
272 sregs
->r
[(cwp
+ 31) & 0x7f] = rval
;
277 printf("%s = %d (0x%08x)\n", reg
, rval
, rval
);
280 printf("no such regiser: %s\n", reg
);
283 printf("cannot set g0\n");
292 disp_reg(struct pstate
*sregs
, char *reg
)
294 if (strncmp(reg
, "w",1) == 0)
295 disp_regs(sregs
, VAL(®
[1]));
301 errinj (int32_t arg ATTRIBUTE_UNUSED
)
305 switch (err
= (random() % 12)) {
306 case 0: errtt
= 0x61; break;
307 case 1: errtt
= 0x62; break;
308 case 2: errtt
= 0x63; break;
309 case 3: errtt
= 0x64; break;
310 case 4: errtt
= 0x65; break;
313 case 7: errftt
= err
;
315 case 8: errmec
= 1; break;
316 case 9: errmec
= 2; break;
317 case 10: errmec
= 5; break;
318 case 11: errmec
= 6; break;
321 if (errper
) event(errinj
, 0, (random()%errper
));
327 if (errper
) event(errinj
, 0, (random()%errper
));
333 limcalc (float32 freq
)
341 if ((cmd1
= strtok(NULL
, " \t\n\r")) != NULL
) {
343 if ((cmd2
= strtok(NULL
, " \t\n\r")) != NULL
) {
344 if (strcmp(cmd2
,"us")==0) unit
= 1;
345 if (strcmp(cmd2
,"ms")==0) unit
= 1000;
346 if (strcmp(cmd2
,"s")==0) unit
= 1000000;
348 flim
= (double) lim
* (double) unit
* (double) freq
+
349 (double) ebase
.simtime
;
350 if ((flim
> ebase
.simtime
) && (flim
< 4294967296.0)) {
351 lim
= (uint32_t) flim
;
353 printf("error in expression\n");
361 exec_cmd(struct pstate
*sregs
, const char *cmd
)
365 uint32_t len
, i
, clen
, j
;
366 static uint32_t daddr
= 0;
367 char *cmdsave
, *cmdsave2
= NULL
;
370 cmdsave
= strdup(cmd
);
371 cmdsave2
= strdup (cmd
);
372 if ((cmd1
= strtok (cmdsave2
, " \t")) != NULL
) {
374 if (strncmp(cmd1
, "bp", clen
) == 0) {
375 for (i
= 0; i
< sregs
->bptnum
; i
++) {
376 printf(" %d : 0x%08x\n", i
+ 1, sregs
->bpts
[i
]);
378 } else if (strncmp(cmd1
, "+bp", clen
) == 0) {
379 if ((cmd1
= strtok(NULL
, " \t\n\r")) != NULL
) {
380 sregs
->bpts
[sregs
->bptnum
] = VAL(cmd1
) & ~0x3;
381 printf("added breakpoint %d at 0x%08x\n",
382 sregs
->bptnum
+ 1, sregs
->bpts
[sregs
->bptnum
]);
385 } else if (strncmp(cmd1
, "-bp", clen
) == 0) {
386 if ((cmd1
= strtok(NULL
, " \t\n\r")) != NULL
) {
388 if ((i
>= 0) && (i
< sregs
->bptnum
)) {
389 printf("deleted breakpoint %d at 0x%08x\n", i
+ 1,
391 for (; i
< sregs
->bptnum
- 1; i
++) {
392 sregs
->bpts
[i
] = sregs
->bpts
[i
+ 1];
397 } else if (strncmp(cmd1
, "batch", clen
) == 0) {
398 if ((cmd1
= strtok(NULL
, " \t\n\r")) == NULL
) {
399 printf("no file specified\n");
403 } else if (strncmp(cmd1
, "cont", clen
) == 0) {
404 if ((cmd1
= strtok(NULL
, " \t\n\r")) == NULL
) {
405 stat
= run_sim(sregs
, UINT64_MAX
, 0);
407 stat
= run_sim(sregs
, VAL(cmd1
), 0);
411 } else if (strncmp(cmd1
, "debug", clen
) == 0) {
412 if ((cmd1
= strtok(NULL
, " \t\n\r")) != NULL
) {
413 sis_verbose
= VAL(cmd1
);
415 printf("Debug level = %d\n",sis_verbose
);
416 } else if (strncmp(cmd1
, "dis", clen
) == 0) {
417 if ((cmd1
= strtok(NULL
, " \t\n\r")) != NULL
) {
420 if ((cmd2
= strtok(NULL
, " \t\n\r")) != NULL
) {
425 dis_mem(daddr
, len
, &dinfo
);
428 } else if (strncmp(cmd1
, "echo", clen
) == 0) {
429 if ((cmd1
= strtok(NULL
, " \t\n\r")) != NULL
) {
430 printf("%s\n", (&cmdsave
[clen
+1]));
433 } else if (strncmp(cmd1
, "error", clen
) == 0) {
434 if ((cmd1
= strtok(NULL
, " \t\n\r")) != NULL
) {
437 event(errinj
, 0, (len
= (random()%errper
)));
438 printf("Error injection started with period %d\n",len
);
440 } else printf("Injected errors: %d\n",errcnt
);
442 } else if (strncmp(cmd1
, "float", clen
) == 0) {
443 stat
= disp_fpu(sregs
);
444 } else if (strncmp(cmd1
, "go", clen
) == 0) {
445 if ((cmd1
= strtok(NULL
, " \t\n\r")) == NULL
) {
446 len
= last_load_addr
;
450 sregs
->pc
= len
& ~3;
451 sregs
->npc
= sregs
->pc
+ 4;
452 if ((sregs
->pc
!= 0) && (ebase
.simtime
== 0))
454 printf("resuming at 0x%08x\n",sregs
->pc
);
455 if ((cmd2
= strtok(NULL
, " \t\n\r")) != NULL
) {
456 stat
= run_sim(sregs
, VAL(cmd2
), 0);
458 stat
= run_sim(sregs
, UINT64_MAX
, 0);
462 } else if (strncmp(cmd1
, "help", clen
) == 0) {
464 } else if (strncmp(cmd1
, "history", clen
) == 0) {
465 if ((cmd1
= strtok(NULL
, " \t\n\r")) != NULL
) {
466 sregs
->histlen
= VAL(cmd1
);
467 if (sregs
->histbuf
!= NULL
)
468 free(sregs
->histbuf
);
469 sregs
->histbuf
= (struct histype
*) calloc(sregs
->histlen
, sizeof(struct histype
));
470 printf("trace history length = %d\n\r", sregs
->histlen
);
475 for (i
= 0; i
< sregs
->histlen
; i
++) {
476 if (j
>= sregs
->histlen
)
478 printf(" %8d ", sregs
->histbuf
[j
].time
);
479 dis_mem(sregs
->histbuf
[j
].addr
, 1, &dinfo
);
484 } else if (strncmp(cmd1
, "load", clen
) == 0) {
485 if ((cmd1
= strtok(NULL
, " \t\n\r")) != NULL
) {
486 last_load_addr
= bfd_load(cmd1
);
487 while ((cmd1
= strtok(NULL
, " \t\n\r")) != NULL
)
488 last_load_addr
= bfd_load(cmd1
);
490 printf("load: no file specified\n");
492 } else if (strncmp(cmd1
, "mem", clen
) == 0) {
493 if ((cmd1
= strtok(NULL
, " \t\n\r")) != NULL
)
495 if ((cmd2
= strtok(NULL
, " \t\n\r")) != NULL
)
499 disp_mem(daddr
, len
);
501 } else if (strncmp(cmd1
, "perf", clen
) == 0) {
502 cmd1
= strtok(NULL
, " \t\n\r");
503 if ((cmd1
!= NULL
) &&
504 (strncmp(cmd1
, "reset", strlen(cmd1
)) == 0)) {
508 } else if (strncmp(cmd1
, "quit", clen
) == 0) {
510 } else if (strncmp(cmd1
, "reg", clen
) == 0) {
511 cmd1
= strtok(NULL
, " \t\n\r");
512 cmd2
= strtok(NULL
, " \t\n\r");
514 set_rega(sregs
, cmd1
, VAL(cmd2
));
515 else if (cmd1
!= NULL
)
516 disp_reg(sregs
, cmd1
);
518 disp_regs(sregs
,sregs
->psr
);
521 } else if (strncmp(cmd1
, "reset", clen
) == 0) {
525 } else if (strncmp(cmd1
, "run", clen
) == 0) {
529 if ((cmd1
= strtok(NULL
, " \t\n\r")) == NULL
) {
530 stat
= run_sim(sregs
, UINT64_MAX
, 0);
532 stat
= run_sim(sregs
, VAL(cmd1
), 0);
536 } else if (strncmp(cmd1
, "shell", clen
) == 0) {
537 if ((cmd1
= strtok(NULL
, " \t\n\r")) != NULL
) {
538 if (system(&cmdsave
[clen
])) {
539 /* Silence unused return value warning. */
542 } else if (strncmp(cmd1
, "step", clen
) == 0) {
543 stat
= run_sim(sregs
, 1, 1);
546 } else if (strncmp(cmd1
, "tcont", clen
) == 0) {
547 sregs
->tlimit
= limcalc(sregs
->freq
);
548 stat
= run_sim(sregs
, UINT64_MAX
, 0);
551 } else if (strncmp(cmd1
, "tgo", clen
) == 0) {
552 if ((cmd1
= strtok(NULL
, " \t\n\r")) == NULL
) {
553 len
= last_load_addr
;
556 sregs
->tlimit
= limcalc(sregs
->freq
);
558 sregs
->pc
= len
& ~3;
559 sregs
->npc
= sregs
->pc
+ 4;
560 printf("resuming at 0x%08x\n",sregs
->pc
);
561 stat
= run_sim(sregs
, UINT64_MAX
, 0);
564 } else if (strncmp(cmd1
, "tlimit", clen
) == 0) {
565 sregs
->tlimit
= limcalc(sregs
->freq
);
566 if (sregs
->tlimit
!= (uint32_t) -1)
567 printf("simulation limit = %u (%.3f ms)\n",(uint32_t) sregs
->tlimit
,
568 sregs
->tlimit
/ sregs
->freq
/ 1000);
569 } else if (strncmp(cmd1
, "tra", clen
) == 0) {
570 if ((cmd1
= strtok(NULL
, " \t\n\r")) == NULL
) {
571 stat
= run_sim(sregs
, UINT64_MAX
, 1);
573 stat
= run_sim(sregs
, VAL(cmd1
), 1);
578 } else if (strncmp(cmd1
, "trun", clen
) == 0) {
582 sregs
->tlimit
= limcalc(sregs
->freq
);
583 stat
= run_sim(sregs
, UINT64_MAX
, 0);
587 printf("syntax error\n");
589 if (cmdsave2
!= NULL
)
598 reset_stat(struct pstate
*sregs
)
600 sregs
->tottime
= 0.0;
610 sregs
->simstart
= ebase
.simtime
;
615 show_stat(struct pstate
*sregs
)
622 if (sregs
->tottime
== 0.0)
623 sregs
->tottime
+= 1E-6;
624 stime
= ebase
.simtime
- sregs
->simstart
; /* Total simulated time */
627 iinst
= sregs
->ninst
- sregs
->finst
- sregs
->nload
- sregs
->nstore
-
631 printf("\n Cycles : %9" PRIu64
"\n\r", ebase
.simtime
- sregs
->simstart
);
632 printf(" Instructions : %9" PRIu64
"\n", sregs
->ninst
);
635 printf(" integer : %9.2f %%\n", 100.0 * (float) iinst
/ (float) sregs
->ninst
);
636 printf(" load : %9.2f %%\n",
637 100.0 * (float) sregs
->nload
/ (float) sregs
->ninst
);
638 printf(" store : %9.2f %%\n",
639 100.0 * (float) sregs
->nstore
/ (float) sregs
->ninst
);
640 printf(" branch : %9.2f %%\n",
641 100.0 * (float) sregs
->nbranch
/ (float) sregs
->ninst
);
642 printf(" float : %9.2f %%\n",
643 100.0 * (float) sregs
->finst
/ (float) sregs
->ninst
);
644 printf(" Integer CPI : %9.2f\n",
645 ((float) (stime
- sregs
->pwdtime
- sregs
->fholdt
- sregs
->finst
))
647 (float) (sregs
->ninst
- sregs
->finst
));
648 printf(" Float CPI : %9.2f\n",
649 ((float) sregs
->fholdt
/ (float) sregs
->finst
) + 1.0);
651 printf(" Overall CPI : %9.2f\n",
652 (float) (stime
- sregs
->pwdtime
) / (float) sregs
->ninst
);
653 printf("\n ERC32 performance (%4.1f MHz): %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n",
654 sregs
->freq
, sregs
->freq
* (float) sregs
->ninst
/ (float) (stime
- sregs
->pwdtime
),
655 sregs
->freq
* (float) (sregs
->ninst
- sregs
->finst
) /
656 (float) (stime
- sregs
->pwdtime
),
657 sregs
->freq
* (float) sregs
->finst
/ (float) (stime
- sregs
->pwdtime
));
658 printf(" Simulated ERC32 time : %.2f s\n",
659 (float) (ebase
.simtime
- sregs
->simstart
) / 1000000.0 / sregs
->freq
);
660 printf(" Processor utilisation : %.2f %%\n",
661 100.0 * (1.0 - ((float) sregs
->pwdtime
/ (float) stime
)));
662 printf(" Real-time performance : %.2f %%\n",
663 100.0 / (sregs
->tottime
/ ((double) (stime
) / (sregs
->freq
* 1.0E6
))));
664 printf(" Simulator performance : %.2f MIPS\n",
665 (double)(sregs
->ninst
) / sregs
->tottime
/ 1E6
);
666 printf(" Used time (sys + user) : %.2f s\n\n", sregs
->tottime
);
672 init_bpt(struct pstate
*sregs
)
677 sregs
->histbuf
= NULL
;
682 int_handler(int32_t sig
)
685 printf("\n\n Signal handler error (%d)\n\n", sig
);
692 signal(SIGTERM
, int_handler
);
693 signal(SIGINT
, int_handler
);
697 extern struct disassemble_info dinfo
;
700 struct evcell evbuf
[MAX_EVENTS
];
701 struct irqcell irqarr
[16];
704 disp_fpu(struct pstate
*sregs
)
709 printf("\n fsr: %08X\n\n", sregs
->fsr
);
711 #ifdef HOST_LITTLE_ENDIAN
712 for (i
= 0; i
< 32; i
++)
713 sregs
->fdp
[i
^ 1] = sregs
->fs
[i
];
716 for (i
= 0; i
< 32; i
++) {
717 printf(" f%02d %08x %14e ", i
, sregs
->fsi
[i
], sregs
->fs
[i
]);
719 printf("%14e\n", sregs
->fd
[i
>> 1]);
728 disp_regs(struct pstate
*sregs
, int cwp
)
733 cwp
= ((cwp
& 0x7) << 4);
734 printf("\n\t INS LOCALS OUTS GLOBALS\n");
735 for (i
= 0; i
< 8; i
++) {
736 printf(" %d: %08X %08X %08X %08X\n", i
,
737 sregs
->r
[(cwp
+ i
+ 24) & 0x7f],
738 sregs
->r
[(cwp
+ i
+ 16) & 0x7f], sregs
->r
[(cwp
+ i
+ 8) & 0x7f],
743 static void print_insn_sparc_sis(uint32_t addr
, struct disassemble_info
*info
)
747 sis_memory_read(addr
, i
, 4);
748 dinfo
.buffer_vma
= addr
;
749 dinfo
.buffer_length
= 4;
751 print_insn_sparc(addr
, info
);
755 disp_ctrl(struct pstate
*sregs
)
760 printf("\n psr: %08X wim: %08X tbr: %08X y: %08X\n",
761 sregs
->psr
, sregs
->wim
, sregs
->tbr
, sregs
->y
);
762 sis_memory_read (sregs
->pc
, (char *) &i
, 4);
763 printf ("\n pc: %08X = %08X ", sregs
->pc
, i
);
764 print_insn_sparc_sis(sregs
->pc
, &dinfo
);
765 sis_memory_read (sregs
->npc
, (char *) &i
, 4);
766 printf ("\n npc: %08X = %08X ", sregs
->npc
, i
);
767 print_insn_sparc_sis(sregs
->npc
, &dinfo
);
769 printf("\n IU in error mode");
774 disp_mem(uint32_t addr
, uint32_t len
)
785 for (i
= addr
& ~3; i
< ((addr
+ len
) & ~3); i
+= 16) {
786 printf("\n %8X ", i
);
787 for (j
= 0; j
< 4; j
++) {
788 sis_memory_read ((i
+ (j
* 4)), data
.u8
, 4);
789 printf ("%08x ", data
.u32
);
794 for (j
= 0; j
< 16; j
++) {
795 if (isprint (p
[j
^ EBT
]))
796 putchar (p
[j
^ EBT
]);
805 dis_mem(uint32_t addr
, uint32_t len
, struct disassemble_info
*info
)
813 for (i
= addr
& -3; i
< ((addr
& -3) + (len
<< 2)); i
+= 4) {
814 sis_memory_read (i
, data
.u8
, 4);
815 printf (" %08x %08x ", i
, data
.u32
);
816 print_insn_sparc_sis(i
, info
);
817 if (i
>= 0xfffffffc) break;
822 /* Add event to event queue */
825 event(void (*cfunc
) (int32_t), int32_t arg
, uint64_t delta
)
827 struct evcell
*ev1
, *evins
;
829 if (ebase
.freeq
== NULL
) {
830 printf("Error, too many events in event queue\n");
834 delta
+= ebase
.simtime
;
835 while ((ev1
->nxt
!= NULL
) && (ev1
->nxt
->time
<= delta
)) {
838 if (ev1
->nxt
== NULL
) {
839 ev1
->nxt
= ebase
.freeq
;
840 ebase
.freeq
= ebase
.freeq
->nxt
;
841 ev1
->nxt
->nxt
= NULL
;
844 ebase
.freeq
= ebase
.freeq
->nxt
;
845 evins
->nxt
= ev1
->nxt
;
848 ev1
->nxt
->time
= delta
;
849 ev1
->nxt
->cfunc
= cfunc
;
853 #if 0 /* apparently not used */
867 for (i
= 0; i
< MAX_EVENTS
; i
++) {
868 evbuf
[i
].nxt
= &evbuf
[i
+ 1];
870 evbuf
[MAX_EVENTS
- 1].nxt
= NULL
;
874 set_int(int32_t level
, void (*callback
) (int32_t), int32_t arg
)
876 irqarr
[level
& 0x0f].callback
= callback
;
877 irqarr
[level
& 0x0f].arg
= arg
;
880 /* Advance simulator time */
883 advance_time(struct pstate
*sregs
)
886 struct evcell
*evrem
;
887 void (*cfunc
) (int32_t);
892 sregs
->fholdt
+= sregs
->fhold
;
893 sregs
->holdt
+= sregs
->hold
;
894 sregs
->icntt
+= sregs
->icnt
;
897 endtime
= ebase
.simtime
+ sregs
->icnt
+ sregs
->hold
+ sregs
->fhold
;
899 while ((ebase
.eq
.nxt
->time
<= (endtime
)) && (ebase
.eq
.nxt
!= NULL
)) {
900 ebase
.simtime
= ebase
.eq
.nxt
->time
;
901 cfunc
= ebase
.eq
.nxt
->cfunc
;
902 arg
= ebase
.eq
.nxt
->arg
;
903 evrem
= ebase
.eq
.nxt
;
904 ebase
.eq
.nxt
= ebase
.eq
.nxt
->nxt
;
905 evrem
->nxt
= ebase
.freeq
;
909 ebase
.simtime
= endtime
;
916 return ebase
.simtime
;
920 /* Advance time until an external interrupt is seen */
925 struct evcell
*evrem
;
926 void (*cfunc
) (int32_t);
930 if (ebase
.eq
.nxt
== NULL
)
931 printf("Warning: event queue empty - power-down mode not entered\n");
932 endtime
= ebase
.simtime
;
933 while (!ext_irl
&& (ebase
.eq
.nxt
!= NULL
)) {
934 ebase
.simtime
= ebase
.eq
.nxt
->time
;
935 cfunc
= ebase
.eq
.nxt
->cfunc
;
936 arg
= ebase
.eq
.nxt
->arg
;
937 evrem
= ebase
.eq
.nxt
;
938 ebase
.eq
.nxt
= ebase
.eq
.nxt
->nxt
;
939 evrem
->nxt
= ebase
.freeq
;
943 printf("\bwarning: power-down mode interrupted\n");
947 sregs
.pwdtime
+= ebase
.simtime
- endtime
;
948 return ebase
.simtime
- endtime
;
952 check_bpt(struct pstate
*sregs
)
956 if ((sregs
->bphit
) || (sregs
->annul
))
958 for (i
= 0; i
< (int32_t) sregs
->bptnum
; i
++) {
959 if (sregs
->pc
== sregs
->bpts
[i
])
968 init_event(); /* Clear event queue */
980 sregs
.trap
= 256; /* Force fake reset trap */
986 sregs
.trap
= 257; /* Force fake halt trap */
989 #include "ansidecl.h"
993 #include "libiberty.h"
997 #define min(A, B) (((A) < (B)) ? (A) : (B))
999 #define LOAD_ADDRESS 0
1002 bfd_load (const char *fname
)
1008 pbfd
= bfd_openr(fname
, 0);
1011 printf("open of %s failed\n", fname
);
1014 if (!bfd_check_format(pbfd
, bfd_object
)) {
1015 printf("file %s doesn't seem to be an object file\n", fname
);
1020 printf("loading %s:", fname
);
1021 for (section
= pbfd
->sections
; section
; section
= section
->next
) {
1022 if (bfd_section_flags (section
) & SEC_ALLOC
) {
1023 bfd_vma section_address
;
1024 unsigned long section_size
;
1025 const char *section_name
;
1027 section_name
= bfd_section_name (section
);
1029 section_address
= bfd_section_vma (section
);
1031 * Adjust sections from a.out files, since they don't carry their
1034 if (bfd_get_flavour(pbfd
) == bfd_target_aout_flavour
) {
1035 if (strcmp (section_name
, ".text") == 0)
1036 section_address
= bfd_get_start_address (pbfd
);
1037 else if (strcmp (section_name
, ".data") == 0) {
1038 /* Read the first 8 bytes of the data section.
1039 There should be the string 'DaTa' followed by
1040 a word containing the actual section address. */
1043 char signature
[4]; /* 'DaTa' */
1044 unsigned char sdata
[4]; /* &sdata */
1046 bfd_get_section_contents (pbfd
, section
, &marker
, 0,
1048 if (strncmp (marker
.signature
, "DaTa", 4) == 0)
1050 section_address
= bfd_getb32 (marker
.sdata
);
1055 section_size
= bfd_section_size (section
);
1058 printf("\nsection %s at 0x%08" PRIx64
" (0x%lx bytes)",
1059 section_name
, (uint64_t) section_address
, section_size
);
1061 /* Text, data or lit */
1062 if (bfd_section_flags (section
) & SEC_LOAD
) {
1067 while (section_size
> 0) {
1071 count
= min(section_size
, 1024);
1073 bfd_get_section_contents(pbfd
, section
, buffer
, fptr
, count
);
1075 for (i
= 0; i
< count
; i
++)
1076 sis_memory_write ((section_address
+ i
) ^ EBT
, &buffer
[i
], 1);
1078 section_address
+= count
;
1080 section_size
-= count
;
1084 printf("(not loaded)");
1090 return bfd_get_start_address (pbfd
);
1093 double get_time (void)
1099 gettimeofday (&tm
, NULL
);
1100 usec
= ((double) tm
.tv_sec
) * 1E6
+ ((double) tm
.tv_usec
);