func.c 28 KB

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