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