1212397c6Schristos /* This file is part of SIS (SPARC instruction simulator) 2212397c6Schristos 3*1f4e7eb9Schristos Copyright (C) 1995-2024 Free Software Foundation, Inc. 4212397c6Schristos Contributed by Jiri Gaisler, European Space Agency 5212397c6Schristos 6212397c6Schristos This program is free software; you can redistribute it and/or modify 7212397c6Schristos it under the terms of the GNU General Public License as published by 8212397c6Schristos the Free Software Foundation; either version 3 of the License, or 9212397c6Schristos (at your option) any later version. 10212397c6Schristos 11212397c6Schristos This program is distributed in the hope that it will be useful, 12212397c6Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 13212397c6Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14212397c6Schristos GNU General Public License for more details. 15212397c6Schristos 16212397c6Schristos You should have received a copy of the GNU General Public License 17212397c6Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 184e98e3e1Schristos 194b169a6bSchristos /* This must come before any other includes. */ 204b169a6bSchristos #include "defs.h" 214b169a6bSchristos 224e98e3e1Schristos #include <signal.h> 234e98e3e1Schristos #include <string.h> 244e98e3e1Schristos #include <stdio.h> 254e98e3e1Schristos #include <stdlib.h> 264e98e3e1Schristos #include <ctype.h> 274e98e3e1Schristos #include "sis.h" 284e98e3e1Schristos #include <dis-asm.h> 294e98e3e1Schristos #include "sim-config.h" 30212397c6Schristos #include <inttypes.h> 314b169a6bSchristos #include <sys/time.h> 324e98e3e1Schristos 334e98e3e1Schristos #define VAL(x) strtoul(x,(char **)NULL,0) 344e98e3e1Schristos 354e98e3e1Schristos struct disassemble_info dinfo; 364e98e3e1Schristos struct pstate sregs; 374e98e3e1Schristos extern struct estate ebase; 384e98e3e1Schristos int ctrl_c = 0; 394e98e3e1Schristos int sis_verbose = 0; 404e98e3e1Schristos char *sis_version = "2.7.5"; 414e98e3e1Schristos int nfp = 0; 424e98e3e1Schristos int ift = 0; 434e98e3e1Schristos int wrp = 0; 444e98e3e1Schristos int rom8 = 0; 454e98e3e1Schristos int uben = 0; 464e98e3e1Schristos int termsave; 474e98e3e1Schristos int sparclite = 0; /* emulating SPARClite instructions? */ 484e98e3e1Schristos int sparclite_board = 0; /* emulating SPARClite board RAM? */ 494e98e3e1Schristos char uart_dev1[128] = ""; 504e98e3e1Schristos char uart_dev2[128] = ""; 514e98e3e1Schristos extern int ext_irl; 524b169a6bSchristos uint32_t last_load_addr = 0; 534e98e3e1Schristos 544e98e3e1Schristos #ifdef ERRINJ 554b169a6bSchristos uint32_t errcnt = 0; 564b169a6bSchristos uint32_t errper = 0; 574b169a6bSchristos uint32_t errtt = 0; 584b169a6bSchristos uint32_t errftt = 0; 594b169a6bSchristos uint32_t errmec = 0; 604e98e3e1Schristos #endif 614e98e3e1Schristos 624e98e3e1Schristos /* Forward declarations */ 634e98e3e1Schristos 6403467a24Schristos static int batch (struct pstate *sregs, char *fname); 654b169a6bSchristos static void set_rega (struct pstate *sregs, char *reg, uint32_t rval); 6603467a24Schristos static void disp_reg (struct pstate *sregs, char *reg); 674b169a6bSchristos static uint32_t limcalc (float32 freq); 684b169a6bSchristos static void int_handler (int32_t sig); 6903467a24Schristos static void init_event (void); 7003467a24Schristos static int disp_fpu (struct pstate *sregs); 7103467a24Schristos static void disp_regs (struct pstate *sregs, int cwp); 7203467a24Schristos static void disp_ctrl (struct pstate *sregs); 734b169a6bSchristos static void disp_mem (uint32_t addr, uint32_t len); 744e98e3e1Schristos 754e98e3e1Schristos static int 764b169a6bSchristos batch(struct pstate *sregs, char *fname) 774e98e3e1Schristos { 784e98e3e1Schristos FILE *fp; 79212397c6Schristos char *lbuf = NULL; 80212397c6Schristos size_t len = 0; 81212397c6Schristos size_t slen; 824e98e3e1Schristos 834e98e3e1Schristos if ((fp = fopen(fname, "r")) == NULL) { 844e98e3e1Schristos fprintf(stderr, "couldn't open batch file %s\n", fname); 85212397c6Schristos return 0; 864e98e3e1Schristos } 87212397c6Schristos while (getline(&lbuf, &len, fp) > -1) { 88212397c6Schristos slen = strlen(lbuf); 89212397c6Schristos if (slen && (lbuf[slen - 1] == '\n')) { 90212397c6Schristos lbuf[slen - 1] = 0; 914e98e3e1Schristos printf("sis> %s\n", lbuf); 924e98e3e1Schristos exec_cmd(sregs, lbuf); 934e98e3e1Schristos } 94212397c6Schristos } 95212397c6Schristos free(lbuf); 964e98e3e1Schristos fclose(fp); 97212397c6Schristos return 1; 984e98e3e1Schristos } 994e98e3e1Schristos 1004e98e3e1Schristos void 1014b169a6bSchristos set_regi(struct pstate *sregs, int32_t reg, uint32_t rval) 1024e98e3e1Schristos { 1034b169a6bSchristos uint32_t cwp; 1044e98e3e1Schristos 1054e98e3e1Schristos cwp = ((sregs->psr & 0x7) << 4); 1064e98e3e1Schristos if ((reg > 0) && (reg < 8)) { 1074e98e3e1Schristos sregs->g[reg] = rval; 1084e98e3e1Schristos } else if ((reg >= 8) && (reg < 32)) { 1094e98e3e1Schristos sregs->r[(cwp + reg) & 0x7f] = rval; 1104e98e3e1Schristos } else if ((reg >= 32) && (reg < 64)) { 1114e98e3e1Schristos sregs->fsi[reg - 32] = rval; 1124e98e3e1Schristos } else { 1134e98e3e1Schristos switch (reg) { 1144e98e3e1Schristos case 64: 1154e98e3e1Schristos sregs->y = rval; 1164e98e3e1Schristos break; 1174e98e3e1Schristos case 65: 1184e98e3e1Schristos sregs->psr = rval; 1194e98e3e1Schristos break; 1204e98e3e1Schristos case 66: 1214e98e3e1Schristos sregs->wim = rval; 1224e98e3e1Schristos break; 1234e98e3e1Schristos case 67: 1244e98e3e1Schristos sregs->tbr = rval; 1254e98e3e1Schristos break; 1264e98e3e1Schristos case 68: 1274e98e3e1Schristos sregs->pc = rval; 1284e98e3e1Schristos break; 1294e98e3e1Schristos case 69: 1304e98e3e1Schristos sregs->npc = rval; 1314e98e3e1Schristos break; 1324e98e3e1Schristos case 70: 1334e98e3e1Schristos sregs->fsr = rval; 1344e98e3e1Schristos set_fsr(rval); 1354e98e3e1Schristos break; 1364e98e3e1Schristos default:break; 1374e98e3e1Schristos } 1384e98e3e1Schristos } 1394e98e3e1Schristos } 1404e98e3e1Schristos 1414e98e3e1Schristos void 1424b169a6bSchristos get_regi(struct pstate * sregs, int32_t reg, unsigned char *buf) 1434e98e3e1Schristos { 1444b169a6bSchristos uint32_t cwp; 1454b169a6bSchristos uint32_t rval = 0; 1464e98e3e1Schristos 1474e98e3e1Schristos cwp = ((sregs->psr & 0x7) << 4); 1484e98e3e1Schristos if ((reg >= 0) && (reg < 8)) { 1494e98e3e1Schristos rval = sregs->g[reg]; 1504e98e3e1Schristos } else if ((reg >= 8) && (reg < 32)) { 1514e98e3e1Schristos rval = sregs->r[(cwp + reg) & 0x7f]; 1524e98e3e1Schristos } else if ((reg >= 32) && (reg < 64)) { 1534e98e3e1Schristos rval = sregs->fsi[reg - 32]; 1544e98e3e1Schristos } else { 1554e98e3e1Schristos switch (reg) { 1564e98e3e1Schristos case 64: 1574e98e3e1Schristos rval = sregs->y; 1584e98e3e1Schristos break; 1594e98e3e1Schristos case 65: 1604e98e3e1Schristos rval = sregs->psr; 1614e98e3e1Schristos break; 1624e98e3e1Schristos case 66: 1634e98e3e1Schristos rval = sregs->wim; 1644e98e3e1Schristos break; 1654e98e3e1Schristos case 67: 1664e98e3e1Schristos rval = sregs->tbr; 1674e98e3e1Schristos break; 1684e98e3e1Schristos case 68: 1694e98e3e1Schristos rval = sregs->pc; 1704e98e3e1Schristos break; 1714e98e3e1Schristos case 69: 1724e98e3e1Schristos rval = sregs->npc; 1734e98e3e1Schristos break; 1744e98e3e1Schristos case 70: 1754e98e3e1Schristos rval = sregs->fsr; 1764e98e3e1Schristos break; 1774e98e3e1Schristos default:break; 1784e98e3e1Schristos } 1794e98e3e1Schristos } 1804e98e3e1Schristos buf[0] = (rval >> 24) & 0x0ff; 1814e98e3e1Schristos buf[1] = (rval >> 16) & 0x0ff; 1824e98e3e1Schristos buf[2] = (rval >> 8) & 0x0ff; 1834e98e3e1Schristos buf[3] = rval & 0x0ff; 1844e98e3e1Schristos } 1854e98e3e1Schristos 1864e98e3e1Schristos 1874e98e3e1Schristos static void 1884b169a6bSchristos set_rega(struct pstate *sregs, char *reg, uint32_t rval) 1894e98e3e1Schristos { 1904b169a6bSchristos uint32_t cwp; 1914b169a6bSchristos int32_t err = 0; 1924e98e3e1Schristos 1934e98e3e1Schristos cwp = ((sregs->psr & 0x7) << 4); 1944e98e3e1Schristos if (strcmp(reg, "psr") == 0) 1954e98e3e1Schristos sregs->psr = (rval = (rval & 0x00f03fff)); 1964e98e3e1Schristos else if (strcmp(reg, "tbr") == 0) 1974e98e3e1Schristos sregs->tbr = (rval = (rval & 0xfffffff0)); 1984e98e3e1Schristos else if (strcmp(reg, "wim") == 0) 1994e98e3e1Schristos sregs->wim = (rval = (rval & 0x0ff)); 2004e98e3e1Schristos else if (strcmp(reg, "y") == 0) 2014e98e3e1Schristos sregs->y = rval; 2024e98e3e1Schristos else if (strcmp(reg, "pc") == 0) 2034e98e3e1Schristos sregs->pc = rval; 2044e98e3e1Schristos else if (strcmp(reg, "npc") == 0) 2054e98e3e1Schristos sregs->npc = rval; 2064e98e3e1Schristos else if (strcmp(reg, "fsr") == 0) { 2074e98e3e1Schristos sregs->fsr = rval; 2084e98e3e1Schristos set_fsr(rval); 2094e98e3e1Schristos } else if (strcmp(reg, "g0") == 0) 2104e98e3e1Schristos err = 2; 2114e98e3e1Schristos else if (strcmp(reg, "g1") == 0) 2124e98e3e1Schristos sregs->g[1] = rval; 2134e98e3e1Schristos else if (strcmp(reg, "g2") == 0) 2144e98e3e1Schristos sregs->g[2] = rval; 2154e98e3e1Schristos else if (strcmp(reg, "g3") == 0) 2164e98e3e1Schristos sregs->g[3] = rval; 2174e98e3e1Schristos else if (strcmp(reg, "g4") == 0) 2184e98e3e1Schristos sregs->g[4] = rval; 2194e98e3e1Schristos else if (strcmp(reg, "g5") == 0) 2204e98e3e1Schristos sregs->g[5] = rval; 2214e98e3e1Schristos else if (strcmp(reg, "g6") == 0) 2224e98e3e1Schristos sregs->g[6] = rval; 2234e98e3e1Schristos else if (strcmp(reg, "g7") == 0) 2244e98e3e1Schristos sregs->g[7] = rval; 2254e98e3e1Schristos else if (strcmp(reg, "o0") == 0) 2264e98e3e1Schristos sregs->r[(cwp + 8) & 0x7f] = rval; 2274e98e3e1Schristos else if (strcmp(reg, "o1") == 0) 2284e98e3e1Schristos sregs->r[(cwp + 9) & 0x7f] = rval; 2294e98e3e1Schristos else if (strcmp(reg, "o2") == 0) 2304e98e3e1Schristos sregs->r[(cwp + 10) & 0x7f] = rval; 2314e98e3e1Schristos else if (strcmp(reg, "o3") == 0) 2324e98e3e1Schristos sregs->r[(cwp + 11) & 0x7f] = rval; 2334e98e3e1Schristos else if (strcmp(reg, "o4") == 0) 2344e98e3e1Schristos sregs->r[(cwp + 12) & 0x7f] = rval; 2354e98e3e1Schristos else if (strcmp(reg, "o5") == 0) 2364e98e3e1Schristos sregs->r[(cwp + 13) & 0x7f] = rval; 2374e98e3e1Schristos else if (strcmp(reg, "o6") == 0) 2384e98e3e1Schristos sregs->r[(cwp + 14) & 0x7f] = rval; 2394e98e3e1Schristos else if (strcmp(reg, "o7") == 0) 2404e98e3e1Schristos sregs->r[(cwp + 15) & 0x7f] = rval; 2414e98e3e1Schristos else if (strcmp(reg, "l0") == 0) 2424e98e3e1Schristos sregs->r[(cwp + 16) & 0x7f] = rval; 2434e98e3e1Schristos else if (strcmp(reg, "l1") == 0) 2444e98e3e1Schristos sregs->r[(cwp + 17) & 0x7f] = rval; 2454e98e3e1Schristos else if (strcmp(reg, "l2") == 0) 2464e98e3e1Schristos sregs->r[(cwp + 18) & 0x7f] = rval; 2474e98e3e1Schristos else if (strcmp(reg, "l3") == 0) 2484e98e3e1Schristos sregs->r[(cwp + 19) & 0x7f] = rval; 2494e98e3e1Schristos else if (strcmp(reg, "l4") == 0) 2504e98e3e1Schristos sregs->r[(cwp + 20) & 0x7f] = rval; 2514e98e3e1Schristos else if (strcmp(reg, "l5") == 0) 2524e98e3e1Schristos sregs->r[(cwp + 21) & 0x7f] = rval; 2534e98e3e1Schristos else if (strcmp(reg, "l6") == 0) 2544e98e3e1Schristos sregs->r[(cwp + 22) & 0x7f] = rval; 2554e98e3e1Schristos else if (strcmp(reg, "l7") == 0) 2564e98e3e1Schristos sregs->r[(cwp + 23) & 0x7f] = rval; 2574e98e3e1Schristos else if (strcmp(reg, "i0") == 0) 2584e98e3e1Schristos sregs->r[(cwp + 24) & 0x7f] = rval; 2594e98e3e1Schristos else if (strcmp(reg, "i1") == 0) 2604e98e3e1Schristos sregs->r[(cwp + 25) & 0x7f] = rval; 2614e98e3e1Schristos else if (strcmp(reg, "i2") == 0) 2624e98e3e1Schristos sregs->r[(cwp + 26) & 0x7f] = rval; 2634e98e3e1Schristos else if (strcmp(reg, "i3") == 0) 2644e98e3e1Schristos sregs->r[(cwp + 27) & 0x7f] = rval; 2654e98e3e1Schristos else if (strcmp(reg, "i4") == 0) 2664e98e3e1Schristos sregs->r[(cwp + 28) & 0x7f] = rval; 2674e98e3e1Schristos else if (strcmp(reg, "i5") == 0) 2684e98e3e1Schristos sregs->r[(cwp + 29) & 0x7f] = rval; 2694e98e3e1Schristos else if (strcmp(reg, "i6") == 0) 2704e98e3e1Schristos sregs->r[(cwp + 30) & 0x7f] = rval; 2714e98e3e1Schristos else if (strcmp(reg, "i7") == 0) 2724e98e3e1Schristos sregs->r[(cwp + 31) & 0x7f] = rval; 2734e98e3e1Schristos else 2744e98e3e1Schristos err = 1; 2754e98e3e1Schristos switch (err) { 2764e98e3e1Schristos case 0: 2774e98e3e1Schristos printf("%s = %d (0x%08x)\n", reg, rval, rval); 2784e98e3e1Schristos break; 2794e98e3e1Schristos case 1: 2804e98e3e1Schristos printf("no such regiser: %s\n", reg); 2814e98e3e1Schristos break; 2824e98e3e1Schristos case 2: 2834e98e3e1Schristos printf("cannot set g0\n"); 2844e98e3e1Schristos break; 2854e98e3e1Schristos default: 2864e98e3e1Schristos break; 2874e98e3e1Schristos } 2884e98e3e1Schristos 2894e98e3e1Schristos } 2904e98e3e1Schristos 2914e98e3e1Schristos static void 2924b169a6bSchristos disp_reg(struct pstate *sregs, char *reg) 2934e98e3e1Schristos { 2944e98e3e1Schristos if (strncmp(reg, "w",1) == 0) 2954e98e3e1Schristos disp_regs(sregs, VAL(®[1])); 2964e98e3e1Schristos } 2974e98e3e1Schristos 2984e98e3e1Schristos #ifdef ERRINJ 2994e98e3e1Schristos 3004e98e3e1Schristos void 3014b169a6bSchristos errinj (int32_t arg ATTRIBUTE_UNUSED) 3024e98e3e1Schristos { 3034e98e3e1Schristos int err; 3044e98e3e1Schristos 3054e98e3e1Schristos switch (err = (random() % 12)) { 3064e98e3e1Schristos case 0: errtt = 0x61; break; 3074e98e3e1Schristos case 1: errtt = 0x62; break; 3084e98e3e1Schristos case 2: errtt = 0x63; break; 3094e98e3e1Schristos case 3: errtt = 0x64; break; 3104e98e3e1Schristos case 4: errtt = 0x65; break; 3114e98e3e1Schristos case 5: 3124e98e3e1Schristos case 6: 3134e98e3e1Schristos case 7: errftt = err; 3144e98e3e1Schristos break; 3154e98e3e1Schristos case 8: errmec = 1; break; 3164e98e3e1Schristos case 9: errmec = 2; break; 3174e98e3e1Schristos case 10: errmec = 5; break; 3184e98e3e1Schristos case 11: errmec = 6; break; 3194e98e3e1Schristos } 3204e98e3e1Schristos errcnt++; 3214e98e3e1Schristos if (errper) event(errinj, 0, (random()%errper)); 3224e98e3e1Schristos } 3234e98e3e1Schristos 3244e98e3e1Schristos void 3254b169a6bSchristos errinjstart (void) 3264e98e3e1Schristos { 3274e98e3e1Schristos if (errper) event(errinj, 0, (random()%errper)); 3284e98e3e1Schristos } 3294e98e3e1Schristos 3304e98e3e1Schristos #endif 3314e98e3e1Schristos 3324b169a6bSchristos static uint32_t 3334b169a6bSchristos limcalc (float32 freq) 3344e98e3e1Schristos { 3354b169a6bSchristos uint32_t unit, lim; 3364e98e3e1Schristos double flim; 3374e98e3e1Schristos char *cmd1, *cmd2; 3384e98e3e1Schristos 3394e98e3e1Schristos unit = 1; 3404e98e3e1Schristos lim = -1; 3414e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { 3424e98e3e1Schristos lim = VAL(cmd1); 3434e98e3e1Schristos if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) { 3444e98e3e1Schristos if (strcmp(cmd2,"us")==0) unit = 1; 3454e98e3e1Schristos if (strcmp(cmd2,"ms")==0) unit = 1000; 3464e98e3e1Schristos if (strcmp(cmd2,"s")==0) unit = 1000000; 3474e98e3e1Schristos } 3484e98e3e1Schristos flim = (double) lim * (double) unit * (double) freq + 3494e98e3e1Schristos (double) ebase.simtime; 3504e98e3e1Schristos if ((flim > ebase.simtime) && (flim < 4294967296.0)) { 3514b169a6bSchristos lim = (uint32_t) flim; 3524e98e3e1Schristos } else { 3534e98e3e1Schristos printf("error in expression\n"); 3544e98e3e1Schristos lim = -1; 3554e98e3e1Schristos } 3564e98e3e1Schristos } 357212397c6Schristos return lim; 3584e98e3e1Schristos } 3594e98e3e1Schristos 3604e98e3e1Schristos int 361212397c6Schristos exec_cmd(struct pstate *sregs, const char *cmd) 3624e98e3e1Schristos { 3634e98e3e1Schristos char *cmd1, *cmd2; 3644b169a6bSchristos int32_t stat; 3654b169a6bSchristos uint32_t len, i, clen, j; 3664b169a6bSchristos static uint32_t daddr = 0; 367212397c6Schristos char *cmdsave, *cmdsave2 = NULL; 3684e98e3e1Schristos 3694e98e3e1Schristos stat = OK; 3704e98e3e1Schristos cmdsave = strdup(cmd); 371212397c6Schristos cmdsave2 = strdup (cmd); 372212397c6Schristos if ((cmd1 = strtok (cmdsave2, " \t")) != NULL) { 3734e98e3e1Schristos clen = strlen(cmd1); 3744e98e3e1Schristos if (strncmp(cmd1, "bp", clen) == 0) { 3754e98e3e1Schristos for (i = 0; i < sregs->bptnum; i++) { 3764e98e3e1Schristos printf(" %d : 0x%08x\n", i + 1, sregs->bpts[i]); 3774e98e3e1Schristos } 3784e98e3e1Schristos } else if (strncmp(cmd1, "+bp", clen) == 0) { 3794e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { 3804e98e3e1Schristos sregs->bpts[sregs->bptnum] = VAL(cmd1) & ~0x3; 3814e98e3e1Schristos printf("added breakpoint %d at 0x%08x\n", 3824e98e3e1Schristos sregs->bptnum + 1, sregs->bpts[sregs->bptnum]); 3834e98e3e1Schristos sregs->bptnum += 1; 3844e98e3e1Schristos } 3854e98e3e1Schristos } else if (strncmp(cmd1, "-bp", clen) == 0) { 3864e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { 3874e98e3e1Schristos i = VAL(cmd1) - 1; 3884e98e3e1Schristos if ((i >= 0) && (i < sregs->bptnum)) { 3894e98e3e1Schristos printf("deleted breakpoint %d at 0x%08x\n", i + 1, 3904e98e3e1Schristos sregs->bpts[i]); 3914e98e3e1Schristos for (; i < sregs->bptnum - 1; i++) { 3924e98e3e1Schristos sregs->bpts[i] = sregs->bpts[i + 1]; 3934e98e3e1Schristos } 3944e98e3e1Schristos sregs->bptnum -= 1; 3954e98e3e1Schristos } 3964e98e3e1Schristos } 3974e98e3e1Schristos } else if (strncmp(cmd1, "batch", clen) == 0) { 3984e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { 3994e98e3e1Schristos printf("no file specified\n"); 4004e98e3e1Schristos } else { 4014e98e3e1Schristos batch(sregs, cmd1); 4024e98e3e1Schristos } 4034e98e3e1Schristos } else if (strncmp(cmd1, "cont", clen) == 0) { 4044e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { 4054e98e3e1Schristos stat = run_sim(sregs, UINT64_MAX, 0); 4064e98e3e1Schristos } else { 4074e98e3e1Schristos stat = run_sim(sregs, VAL(cmd1), 0); 4084e98e3e1Schristos } 4094e98e3e1Schristos daddr = sregs->pc; 4104e98e3e1Schristos sim_halt(); 4114e98e3e1Schristos } else if (strncmp(cmd1, "debug", clen) == 0) { 4124e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { 4134e98e3e1Schristos sis_verbose = VAL(cmd1); 4144e98e3e1Schristos } 4154e98e3e1Schristos printf("Debug level = %d\n",sis_verbose); 4164e98e3e1Schristos } else if (strncmp(cmd1, "dis", clen) == 0) { 4174e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { 4184e98e3e1Schristos daddr = VAL(cmd1); 4194e98e3e1Schristos } 4204e98e3e1Schristos if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) { 4214e98e3e1Schristos len = VAL(cmd2); 4224e98e3e1Schristos } else 4234e98e3e1Schristos len = 16; 4244e98e3e1Schristos printf("\n"); 4254e98e3e1Schristos dis_mem(daddr, len, &dinfo); 4264e98e3e1Schristos printf("\n"); 4274e98e3e1Schristos daddr += len * 4; 4284e98e3e1Schristos } else if (strncmp(cmd1, "echo", clen) == 0) { 4294e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { 4304e98e3e1Schristos printf("%s\n", (&cmdsave[clen+1])); 4314e98e3e1Schristos } 4324e98e3e1Schristos #ifdef ERRINJ 4334e98e3e1Schristos } else if (strncmp(cmd1, "error", clen) == 0) { 4344e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { 4354e98e3e1Schristos errper = VAL(cmd1); 4364e98e3e1Schristos if (errper) { 4374e98e3e1Schristos event(errinj, 0, (len = (random()%errper))); 4384e98e3e1Schristos printf("Error injection started with period %d\n",len); 4394e98e3e1Schristos } 4404e98e3e1Schristos } else printf("Injected errors: %d\n",errcnt); 4414e98e3e1Schristos #endif 4424e98e3e1Schristos } else if (strncmp(cmd1, "float", clen) == 0) { 4434e98e3e1Schristos stat = disp_fpu(sregs); 4444e98e3e1Schristos } else if (strncmp(cmd1, "go", clen) == 0) { 4454e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { 4464e98e3e1Schristos len = last_load_addr; 4474e98e3e1Schristos } else { 4484e98e3e1Schristos len = VAL(cmd1); 4494e98e3e1Schristos } 4504e98e3e1Schristos sregs->pc = len & ~3; 4514e98e3e1Schristos sregs->npc = sregs->pc + 4; 452212397c6Schristos if ((sregs->pc != 0) && (ebase.simtime == 0)) 453212397c6Schristos boot_init(); 4544e98e3e1Schristos printf("resuming at 0x%08x\n",sregs->pc); 4554e98e3e1Schristos if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) { 4564e98e3e1Schristos stat = run_sim(sregs, VAL(cmd2), 0); 4574e98e3e1Schristos } else { 4584e98e3e1Schristos stat = run_sim(sregs, UINT64_MAX, 0); 4594e98e3e1Schristos } 4604e98e3e1Schristos daddr = sregs->pc; 4614e98e3e1Schristos sim_halt(); 4624e98e3e1Schristos } else if (strncmp(cmd1, "help", clen) == 0) { 4634e98e3e1Schristos gen_help(); 4644e98e3e1Schristos } else if (strncmp(cmd1, "history", clen) == 0) { 4654e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { 4664e98e3e1Schristos sregs->histlen = VAL(cmd1); 4674e98e3e1Schristos if (sregs->histbuf != NULL) 4684e98e3e1Schristos free(sregs->histbuf); 4694e98e3e1Schristos sregs->histbuf = (struct histype *) calloc(sregs->histlen, sizeof(struct histype)); 4704e98e3e1Schristos printf("trace history length = %d\n\r", sregs->histlen); 4714e98e3e1Schristos sregs->histind = 0; 4724e98e3e1Schristos 4734e98e3e1Schristos } else { 4744e98e3e1Schristos j = sregs->histind; 4754e98e3e1Schristos for (i = 0; i < sregs->histlen; i++) { 4764e98e3e1Schristos if (j >= sregs->histlen) 4774e98e3e1Schristos j = 0; 4784e98e3e1Schristos printf(" %8d ", sregs->histbuf[j].time); 4794e98e3e1Schristos dis_mem(sregs->histbuf[j].addr, 1, &dinfo); 4804e98e3e1Schristos j++; 4814e98e3e1Schristos } 4824e98e3e1Schristos } 4834e98e3e1Schristos 4844e98e3e1Schristos } else if (strncmp(cmd1, "load", clen) == 0) { 4854e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { 4864e98e3e1Schristos last_load_addr = bfd_load(cmd1); 4874e98e3e1Schristos while ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) 4884e98e3e1Schristos last_load_addr = bfd_load(cmd1); 4894e98e3e1Schristos } else { 4904e98e3e1Schristos printf("load: no file specified\n"); 4914e98e3e1Schristos } 4924e98e3e1Schristos } else if (strncmp(cmd1, "mem", clen) == 0) { 4934e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) 4944e98e3e1Schristos daddr = VAL(cmd1); 4954e98e3e1Schristos if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) 4964e98e3e1Schristos len = VAL(cmd2); 4974e98e3e1Schristos else 4984e98e3e1Schristos len = 64; 4994e98e3e1Schristos disp_mem(daddr, len); 5004e98e3e1Schristos daddr += len; 5014e98e3e1Schristos } else if (strncmp(cmd1, "perf", clen) == 0) { 5024e98e3e1Schristos cmd1 = strtok(NULL, " \t\n\r"); 5034e98e3e1Schristos if ((cmd1 != NULL) && 5044e98e3e1Schristos (strncmp(cmd1, "reset", strlen(cmd1)) == 0)) { 5054e98e3e1Schristos reset_stat(sregs); 5064e98e3e1Schristos } else 5074e98e3e1Schristos show_stat(sregs); 5084e98e3e1Schristos } else if (strncmp(cmd1, "quit", clen) == 0) { 5094e98e3e1Schristos exit(0); 5104e98e3e1Schristos } else if (strncmp(cmd1, "reg", clen) == 0) { 5114e98e3e1Schristos cmd1 = strtok(NULL, " \t\n\r"); 5124e98e3e1Schristos cmd2 = strtok(NULL, " \t\n\r"); 5134e98e3e1Schristos if (cmd2 != NULL) 5144e98e3e1Schristos set_rega(sregs, cmd1, VAL(cmd2)); 5154e98e3e1Schristos else if (cmd1 != NULL) 5164e98e3e1Schristos disp_reg(sregs, cmd1); 5174e98e3e1Schristos else { 5184e98e3e1Schristos disp_regs(sregs,sregs->psr); 5194e98e3e1Schristos disp_ctrl(sregs); 5204e98e3e1Schristos } 5214e98e3e1Schristos } else if (strncmp(cmd1, "reset", clen) == 0) { 5224e98e3e1Schristos ebase.simtime = 0; 5234e98e3e1Schristos reset_all(); 5244e98e3e1Schristos reset_stat(sregs); 5254e98e3e1Schristos } else if (strncmp(cmd1, "run", clen) == 0) { 5264e98e3e1Schristos ebase.simtime = 0; 5274e98e3e1Schristos reset_all(); 5284e98e3e1Schristos reset_stat(sregs); 5294e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { 5304e98e3e1Schristos stat = run_sim(sregs, UINT64_MAX, 0); 5314e98e3e1Schristos } else { 5324e98e3e1Schristos stat = run_sim(sregs, VAL(cmd1), 0); 5334e98e3e1Schristos } 5344e98e3e1Schristos daddr = sregs->pc; 5354e98e3e1Schristos sim_halt(); 5364e98e3e1Schristos } else if (strncmp(cmd1, "shell", clen) == 0) { 5374e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { 538212397c6Schristos if (system(&cmdsave[clen])) { 539212397c6Schristos /* Silence unused return value warning. */ 540212397c6Schristos } 5414e98e3e1Schristos } 5424e98e3e1Schristos } else if (strncmp(cmd1, "step", clen) == 0) { 5434e98e3e1Schristos stat = run_sim(sregs, 1, 1); 5444e98e3e1Schristos daddr = sregs->pc; 5454e98e3e1Schristos sim_halt(); 5464e98e3e1Schristos } else if (strncmp(cmd1, "tcont", clen) == 0) { 5474e98e3e1Schristos sregs->tlimit = limcalc(sregs->freq); 5484e98e3e1Schristos stat = run_sim(sregs, UINT64_MAX, 0); 5494e98e3e1Schristos daddr = sregs->pc; 5504e98e3e1Schristos sim_halt(); 5514e98e3e1Schristos } else if (strncmp(cmd1, "tgo", clen) == 0) { 5524e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { 5534e98e3e1Schristos len = last_load_addr; 5544e98e3e1Schristos } else { 5554e98e3e1Schristos len = VAL(cmd1); 5564e98e3e1Schristos sregs->tlimit = limcalc(sregs->freq); 5574e98e3e1Schristos } 5584e98e3e1Schristos sregs->pc = len & ~3; 5594e98e3e1Schristos sregs->npc = sregs->pc + 4; 5604e98e3e1Schristos printf("resuming at 0x%08x\n",sregs->pc); 5614e98e3e1Schristos stat = run_sim(sregs, UINT64_MAX, 0); 5624e98e3e1Schristos daddr = sregs->pc; 5634e98e3e1Schristos sim_halt(); 5644e98e3e1Schristos } else if (strncmp(cmd1, "tlimit", clen) == 0) { 5654e98e3e1Schristos sregs->tlimit = limcalc(sregs->freq); 5664b169a6bSchristos if (sregs->tlimit != (uint32_t) -1) 5674b169a6bSchristos printf("simulation limit = %u (%.3f ms)\n",(uint32_t) sregs->tlimit, 5684e98e3e1Schristos sregs->tlimit / sregs->freq / 1000); 5694e98e3e1Schristos } else if (strncmp(cmd1, "tra", clen) == 0) { 5704e98e3e1Schristos if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { 5714e98e3e1Schristos stat = run_sim(sregs, UINT64_MAX, 1); 5724e98e3e1Schristos } else { 5734e98e3e1Schristos stat = run_sim(sregs, VAL(cmd1), 1); 5744e98e3e1Schristos } 5754e98e3e1Schristos printf("\n"); 5764e98e3e1Schristos daddr = sregs->pc; 5774e98e3e1Schristos sim_halt(); 5784e98e3e1Schristos } else if (strncmp(cmd1, "trun", clen) == 0) { 5794e98e3e1Schristos ebase.simtime = 0; 5804e98e3e1Schristos reset_all(); 5814e98e3e1Schristos reset_stat(sregs); 5824e98e3e1Schristos sregs->tlimit = limcalc(sregs->freq); 5834e98e3e1Schristos stat = run_sim(sregs, UINT64_MAX, 0); 5844e98e3e1Schristos daddr = sregs->pc; 5854e98e3e1Schristos sim_halt(); 5864e98e3e1Schristos } else 5874e98e3e1Schristos printf("syntax error\n"); 5884e98e3e1Schristos } 589212397c6Schristos if (cmdsave2 != NULL) 590212397c6Schristos free(cmdsave2); 5914e98e3e1Schristos if (cmdsave != NULL) 5924e98e3e1Schristos free(cmdsave); 593212397c6Schristos return stat; 5944e98e3e1Schristos } 5954e98e3e1Schristos 5964e98e3e1Schristos 5974e98e3e1Schristos void 5984b169a6bSchristos reset_stat(struct pstate *sregs) 5994e98e3e1Schristos { 600212397c6Schristos sregs->tottime = 0.0; 6014e98e3e1Schristos sregs->pwdtime = 0; 6024e98e3e1Schristos sregs->ninst = 0; 6034e98e3e1Schristos sregs->fholdt = 0; 6044e98e3e1Schristos sregs->holdt = 0; 6054e98e3e1Schristos sregs->icntt = 0; 6064e98e3e1Schristos sregs->finst = 0; 6074e98e3e1Schristos sregs->nstore = 0; 6084e98e3e1Schristos sregs->nload = 0; 6094e98e3e1Schristos sregs->nbranch = 0; 6104e98e3e1Schristos sregs->simstart = ebase.simtime; 6114e98e3e1Schristos 6124e98e3e1Schristos } 6134e98e3e1Schristos 6144e98e3e1Schristos void 6154b169a6bSchristos show_stat(struct pstate *sregs) 6164e98e3e1Schristos { 617*1f4e7eb9Schristos #ifdef STAT 6184b169a6bSchristos uint32_t iinst; 619*1f4e7eb9Schristos #endif 6204b169a6bSchristos uint32_t stime; 6214e98e3e1Schristos 622212397c6Schristos if (sregs->tottime == 0.0) 623212397c6Schristos sregs->tottime += 1E-6; 6244e98e3e1Schristos stime = ebase.simtime - sregs->simstart; /* Total simulated time */ 6254e98e3e1Schristos #ifdef STAT 6264e98e3e1Schristos 6274e98e3e1Schristos iinst = sregs->ninst - sregs->finst - sregs->nload - sregs->nstore - 6284e98e3e1Schristos sregs->nbranch; 6294e98e3e1Schristos #endif 6304e98e3e1Schristos 631212397c6Schristos printf("\n Cycles : %9" PRIu64 "\n\r", ebase.simtime - sregs->simstart); 632212397c6Schristos printf(" Instructions : %9" PRIu64 "\n", sregs->ninst); 6334e98e3e1Schristos 6344e98e3e1Schristos #ifdef STAT 6354e98e3e1Schristos printf(" integer : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst); 6364e98e3e1Schristos printf(" load : %9.2f %%\n", 6374e98e3e1Schristos 100.0 * (float) sregs->nload / (float) sregs->ninst); 6384e98e3e1Schristos printf(" store : %9.2f %%\n", 6394e98e3e1Schristos 100.0 * (float) sregs->nstore / (float) sregs->ninst); 6404e98e3e1Schristos printf(" branch : %9.2f %%\n", 6414e98e3e1Schristos 100.0 * (float) sregs->nbranch / (float) sregs->ninst); 6424e98e3e1Schristos printf(" float : %9.2f %%\n", 6434e98e3e1Schristos 100.0 * (float) sregs->finst / (float) sregs->ninst); 6444e98e3e1Schristos printf(" Integer CPI : %9.2f\n", 6454e98e3e1Schristos ((float) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst)) 6464e98e3e1Schristos / 6474e98e3e1Schristos (float) (sregs->ninst - sregs->finst)); 6484e98e3e1Schristos printf(" Float CPI : %9.2f\n", 6494e98e3e1Schristos ((float) sregs->fholdt / (float) sregs->finst) + 1.0); 6504e98e3e1Schristos #endif 6514e98e3e1Schristos printf(" Overall CPI : %9.2f\n", 6524e98e3e1Schristos (float) (stime - sregs->pwdtime) / (float) sregs->ninst); 6534e98e3e1Schristos printf("\n ERC32 performance (%4.1f MHz): %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n", 6544e98e3e1Schristos sregs->freq, sregs->freq * (float) sregs->ninst / (float) (stime - sregs->pwdtime), 6554e98e3e1Schristos sregs->freq * (float) (sregs->ninst - sregs->finst) / 6564e98e3e1Schristos (float) (stime - sregs->pwdtime), 6574e98e3e1Schristos sregs->freq * (float) sregs->finst / (float) (stime - sregs->pwdtime)); 658212397c6Schristos printf(" Simulated ERC32 time : %.2f s\n", 659212397c6Schristos (float) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq); 660212397c6Schristos printf(" Processor utilisation : %.2f %%\n", 661212397c6Schristos 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime))); 662212397c6Schristos printf(" Real-time performance : %.2f %%\n", 663212397c6Schristos 100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6)))); 664212397c6Schristos printf(" Simulator performance : %.2f MIPS\n", 665212397c6Schristos (double)(sregs->ninst) / sregs->tottime / 1E6); 666212397c6Schristos printf(" Used time (sys + user) : %.2f s\n\n", sregs->tottime); 6674e98e3e1Schristos } 6684e98e3e1Schristos 6694e98e3e1Schristos 6704e98e3e1Schristos 6714e98e3e1Schristos void 6724b169a6bSchristos init_bpt(struct pstate *sregs) 6734e98e3e1Schristos { 6744e98e3e1Schristos sregs->bptnum = 0; 6754e98e3e1Schristos sregs->histlen = 0; 6764e98e3e1Schristos sregs->histind = 0; 6774e98e3e1Schristos sregs->histbuf = NULL; 6784e98e3e1Schristos sregs->tlimit = -1; 6794e98e3e1Schristos } 6804e98e3e1Schristos 6814e98e3e1Schristos static void 6824b169a6bSchristos int_handler(int32_t sig) 6834e98e3e1Schristos { 6844e98e3e1Schristos if (sig != 2) 6854e98e3e1Schristos printf("\n\n Signal handler error (%d)\n\n", sig); 6864e98e3e1Schristos ctrl_c = 1; 6874e98e3e1Schristos } 6884e98e3e1Schristos 6894e98e3e1Schristos void 6904b169a6bSchristos init_signals(void) 6914e98e3e1Schristos { 692*1f4e7eb9Schristos signal(SIGTERM, int_handler); 693*1f4e7eb9Schristos signal(SIGINT, int_handler); 6944e98e3e1Schristos } 6954e98e3e1Schristos 6964e98e3e1Schristos 6974e98e3e1Schristos extern struct disassemble_info dinfo; 6984e98e3e1Schristos 6994e98e3e1Schristos struct estate ebase; 700*1f4e7eb9Schristos struct evcell evbuf[MAX_EVENTS]; 7014e98e3e1Schristos struct irqcell irqarr[16]; 7024e98e3e1Schristos 7034e98e3e1Schristos static int 7044b169a6bSchristos disp_fpu(struct pstate *sregs) 7054e98e3e1Schristos { 7064e98e3e1Schristos 7074e98e3e1Schristos int i; 7084e98e3e1Schristos 7094e98e3e1Schristos printf("\n fsr: %08X\n\n", sregs->fsr); 7104e98e3e1Schristos 711212397c6Schristos #ifdef HOST_LITTLE_ENDIAN 7124e98e3e1Schristos for (i = 0; i < 32; i++) 7134e98e3e1Schristos sregs->fdp[i ^ 1] = sregs->fs[i]; 7144e98e3e1Schristos #endif 7154e98e3e1Schristos 7164e98e3e1Schristos for (i = 0; i < 32; i++) { 7174e98e3e1Schristos printf(" f%02d %08x %14e ", i, sregs->fsi[i], sregs->fs[i]); 7184e98e3e1Schristos if (!(i & 1)) 7194e98e3e1Schristos printf("%14e\n", sregs->fd[i >> 1]); 7204e98e3e1Schristos else 7214e98e3e1Schristos printf("\n"); 7224e98e3e1Schristos } 7234e98e3e1Schristos printf("\n"); 724212397c6Schristos return OK; 7254e98e3e1Schristos } 7264e98e3e1Schristos 7274e98e3e1Schristos static void 7284b169a6bSchristos disp_regs(struct pstate *sregs, int cwp) 7294e98e3e1Schristos { 7304e98e3e1Schristos 7314e98e3e1Schristos int i; 7324e98e3e1Schristos 7334e98e3e1Schristos cwp = ((cwp & 0x7) << 4); 7344e98e3e1Schristos printf("\n\t INS LOCALS OUTS GLOBALS\n"); 7354e98e3e1Schristos for (i = 0; i < 8; i++) { 7364e98e3e1Schristos printf(" %d: %08X %08X %08X %08X\n", i, 7374e98e3e1Schristos sregs->r[(cwp + i + 24) & 0x7f], 7384e98e3e1Schristos sregs->r[(cwp + i + 16) & 0x7f], sregs->r[(cwp + i + 8) & 0x7f], 7394e98e3e1Schristos sregs->g[i]); 7404e98e3e1Schristos } 7414e98e3e1Schristos } 7424e98e3e1Schristos 7434b169a6bSchristos static void print_insn_sparc_sis(uint32_t addr, struct disassemble_info *info) 744212397c6Schristos { 745212397c6Schristos unsigned char i[4]; 746212397c6Schristos 747212397c6Schristos sis_memory_read(addr, i, 4); 748212397c6Schristos dinfo.buffer_vma = addr; 749212397c6Schristos dinfo.buffer_length = 4; 750212397c6Schristos dinfo.buffer = i; 751212397c6Schristos print_insn_sparc(addr, info); 752212397c6Schristos } 753212397c6Schristos 7544e98e3e1Schristos static void 7554b169a6bSchristos disp_ctrl(struct pstate *sregs) 7564e98e3e1Schristos { 7574e98e3e1Schristos 7584b169a6bSchristos uint32_t i; 7594e98e3e1Schristos 7604e98e3e1Schristos printf("\n psr: %08X wim: %08X tbr: %08X y: %08X\n", 7614e98e3e1Schristos sregs->psr, sregs->wim, sregs->tbr, sregs->y); 762212397c6Schristos sis_memory_read (sregs->pc, (char *) &i, 4); 763212397c6Schristos printf ("\n pc: %08X = %08X ", sregs->pc, i); 764212397c6Schristos print_insn_sparc_sis(sregs->pc, &dinfo); 765212397c6Schristos sis_memory_read (sregs->npc, (char *) &i, 4); 766212397c6Schristos printf ("\n npc: %08X = %08X ", sregs->npc, i); 767212397c6Schristos print_insn_sparc_sis(sregs->npc, &dinfo); 7684e98e3e1Schristos if (sregs->err_mode) 7694e98e3e1Schristos printf("\n IU in error mode"); 7704e98e3e1Schristos printf("\n\n"); 7714e98e3e1Schristos } 7724e98e3e1Schristos 7734e98e3e1Schristos static void 7744b169a6bSchristos disp_mem(uint32_t addr, uint32_t len) 7754e98e3e1Schristos { 7764e98e3e1Schristos 7774b169a6bSchristos uint32_t i; 778212397c6Schristos union { 779212397c6Schristos unsigned char u8[4]; 7804b169a6bSchristos uint32_t u32; 781212397c6Schristos } data; 7824b169a6bSchristos uint32_t mem[4], j; 7834e98e3e1Schristos char *p; 7844e98e3e1Schristos 7854e98e3e1Schristos for (i = addr & ~3; i < ((addr + len) & ~3); i += 16) { 7864e98e3e1Schristos printf("\n %8X ", i); 7874e98e3e1Schristos for (j = 0; j < 4; j++) { 788212397c6Schristos sis_memory_read ((i + (j * 4)), data.u8, 4); 789212397c6Schristos printf ("%08x ", data.u32); 790212397c6Schristos mem[j] = data.u32; 7914e98e3e1Schristos } 7924e98e3e1Schristos printf(" "); 7934e98e3e1Schristos p = (char *) mem; 7944e98e3e1Schristos for (j = 0; j < 16; j++) { 795212397c6Schristos if (isprint (p[j ^ EBT])) 796212397c6Schristos putchar (p[j ^ EBT]); 7974e98e3e1Schristos else 7984e98e3e1Schristos putchar('.'); 7994e98e3e1Schristos } 8004e98e3e1Schristos } 8014e98e3e1Schristos printf("\n\n"); 8024e98e3e1Schristos } 8034e98e3e1Schristos 8044e98e3e1Schristos void 8054b169a6bSchristos dis_mem(uint32_t addr, uint32_t len, struct disassemble_info *info) 8064e98e3e1Schristos { 8074b169a6bSchristos uint32_t i; 808212397c6Schristos union { 809212397c6Schristos unsigned char u8[4]; 8104b169a6bSchristos uint32_t u32; 811212397c6Schristos } data; 8124e98e3e1Schristos 8134e98e3e1Schristos for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) { 814212397c6Schristos sis_memory_read (i, data.u8, 4); 815212397c6Schristos printf (" %08x %08x ", i, data.u32); 816212397c6Schristos print_insn_sparc_sis(i, info); 8174e98e3e1Schristos if (i >= 0xfffffffc) break; 8184e98e3e1Schristos printf("\n"); 8194e98e3e1Schristos } 8204e98e3e1Schristos } 8214e98e3e1Schristos 8224e98e3e1Schristos /* Add event to event queue */ 8234e98e3e1Schristos 8244e98e3e1Schristos void 8254b169a6bSchristos event(void (*cfunc) (int32_t), int32_t arg, uint64_t delta) 8264e98e3e1Schristos { 8274e98e3e1Schristos struct evcell *ev1, *evins; 8284e98e3e1Schristos 8294e98e3e1Schristos if (ebase.freeq == NULL) { 8304e98e3e1Schristos printf("Error, too many events in event queue\n"); 8314e98e3e1Schristos return; 8324e98e3e1Schristos } 8334e98e3e1Schristos ev1 = &ebase.eq; 8344e98e3e1Schristos delta += ebase.simtime; 8354e98e3e1Schristos while ((ev1->nxt != NULL) && (ev1->nxt->time <= delta)) { 8364e98e3e1Schristos ev1 = ev1->nxt; 8374e98e3e1Schristos } 8384e98e3e1Schristos if (ev1->nxt == NULL) { 8394e98e3e1Schristos ev1->nxt = ebase.freeq; 8404e98e3e1Schristos ebase.freeq = ebase.freeq->nxt; 8414e98e3e1Schristos ev1->nxt->nxt = NULL; 8424e98e3e1Schristos } else { 8434e98e3e1Schristos evins = ebase.freeq; 8444e98e3e1Schristos ebase.freeq = ebase.freeq->nxt; 8454e98e3e1Schristos evins->nxt = ev1->nxt; 8464e98e3e1Schristos ev1->nxt = evins; 8474e98e3e1Schristos } 8484e98e3e1Schristos ev1->nxt->time = delta; 8494e98e3e1Schristos ev1->nxt->cfunc = cfunc; 8504e98e3e1Schristos ev1->nxt->arg = arg; 8514e98e3e1Schristos } 8524e98e3e1Schristos 8534e98e3e1Schristos #if 0 /* apparently not used */ 8544e98e3e1Schristos void 8554b169a6bSchristos stop_event(void) 8564e98e3e1Schristos { 8574e98e3e1Schristos } 8584e98e3e1Schristos #endif 8594e98e3e1Schristos 8604e98e3e1Schristos void 8614b169a6bSchristos init_event(void) 8624e98e3e1Schristos { 8634b169a6bSchristos int32_t i; 8644e98e3e1Schristos 8654e98e3e1Schristos ebase.eq.nxt = NULL; 8664e98e3e1Schristos ebase.freeq = evbuf; 867*1f4e7eb9Schristos for (i = 0; i < MAX_EVENTS; i++) { 8684e98e3e1Schristos evbuf[i].nxt = &evbuf[i + 1]; 8694e98e3e1Schristos } 870*1f4e7eb9Schristos evbuf[MAX_EVENTS - 1].nxt = NULL; 8714e98e3e1Schristos } 8724e98e3e1Schristos 8734e98e3e1Schristos void 8744b169a6bSchristos set_int(int32_t level, void (*callback) (int32_t), int32_t arg) 8754e98e3e1Schristos { 8764e98e3e1Schristos irqarr[level & 0x0f].callback = callback; 8774e98e3e1Schristos irqarr[level & 0x0f].arg = arg; 8784e98e3e1Schristos } 8794e98e3e1Schristos 8804e98e3e1Schristos /* Advance simulator time */ 8814e98e3e1Schristos 8824e98e3e1Schristos void 8834b169a6bSchristos advance_time(struct pstate *sregs) 8844e98e3e1Schristos { 8854e98e3e1Schristos 8864e98e3e1Schristos struct evcell *evrem; 8874b169a6bSchristos void (*cfunc) (int32_t); 8884b169a6bSchristos int32_t arg; 8894b169a6bSchristos uint64_t endtime; 8904e98e3e1Schristos 8914e98e3e1Schristos #ifdef STAT 8924e98e3e1Schristos sregs->fholdt += sregs->fhold; 8934e98e3e1Schristos sregs->holdt += sregs->hold; 8944e98e3e1Schristos sregs->icntt += sregs->icnt; 8954e98e3e1Schristos #endif 8964e98e3e1Schristos 8974e98e3e1Schristos endtime = ebase.simtime + sregs->icnt + sregs->hold + sregs->fhold; 8984e98e3e1Schristos 8994e98e3e1Schristos while ((ebase.eq.nxt->time <= (endtime)) && (ebase.eq.nxt != NULL)) { 9004e98e3e1Schristos ebase.simtime = ebase.eq.nxt->time; 9014e98e3e1Schristos cfunc = ebase.eq.nxt->cfunc; 9024e98e3e1Schristos arg = ebase.eq.nxt->arg; 9034e98e3e1Schristos evrem = ebase.eq.nxt; 9044e98e3e1Schristos ebase.eq.nxt = ebase.eq.nxt->nxt; 9054e98e3e1Schristos evrem->nxt = ebase.freeq; 9064e98e3e1Schristos ebase.freeq = evrem; 9074e98e3e1Schristos cfunc(arg); 9084e98e3e1Schristos } 9094e98e3e1Schristos ebase.simtime = endtime; 9104e98e3e1Schristos 9114e98e3e1Schristos } 9124e98e3e1Schristos 9134b169a6bSchristos uint32_t 9144b169a6bSchristos now(void) 9154e98e3e1Schristos { 916212397c6Schristos return ebase.simtime; 9174e98e3e1Schristos } 9184e98e3e1Schristos 9194e98e3e1Schristos 9204e98e3e1Schristos /* Advance time until an external interrupt is seen */ 9214e98e3e1Schristos 9224e98e3e1Schristos int 9234b169a6bSchristos wait_for_irq(void) 9244e98e3e1Schristos { 9254e98e3e1Schristos struct evcell *evrem; 9264b169a6bSchristos void (*cfunc) (int32_t); 9274b169a6bSchristos int32_t arg; 9284b169a6bSchristos uint64_t endtime; 9294e98e3e1Schristos 9304e98e3e1Schristos if (ebase.eq.nxt == NULL) 9314e98e3e1Schristos printf("Warning: event queue empty - power-down mode not entered\n"); 9324e98e3e1Schristos endtime = ebase.simtime; 9334e98e3e1Schristos while (!ext_irl && (ebase.eq.nxt != NULL)) { 9344e98e3e1Schristos ebase.simtime = ebase.eq.nxt->time; 9354e98e3e1Schristos cfunc = ebase.eq.nxt->cfunc; 9364e98e3e1Schristos arg = ebase.eq.nxt->arg; 9374e98e3e1Schristos evrem = ebase.eq.nxt; 9384e98e3e1Schristos ebase.eq.nxt = ebase.eq.nxt->nxt; 9394e98e3e1Schristos evrem->nxt = ebase.freeq; 9404e98e3e1Schristos ebase.freeq = evrem; 9414e98e3e1Schristos cfunc(arg); 9424e98e3e1Schristos if (ctrl_c) { 9434e98e3e1Schristos printf("\bwarning: power-down mode interrupted\n"); 9444e98e3e1Schristos break; 9454e98e3e1Schristos } 9464e98e3e1Schristos } 9474e98e3e1Schristos sregs.pwdtime += ebase.simtime - endtime; 948212397c6Schristos return ebase.simtime - endtime; 9494e98e3e1Schristos } 9504e98e3e1Schristos 9514e98e3e1Schristos int 9524b169a6bSchristos check_bpt(struct pstate *sregs) 9534e98e3e1Schristos { 9544b169a6bSchristos int32_t i; 9554e98e3e1Schristos 9564e98e3e1Schristos if ((sregs->bphit) || (sregs->annul)) 957212397c6Schristos return 0; 9584b169a6bSchristos for (i = 0; i < (int32_t) sregs->bptnum; i++) { 9594e98e3e1Schristos if (sregs->pc == sregs->bpts[i]) 960212397c6Schristos return BPT_HIT; 9614e98e3e1Schristos } 962212397c6Schristos return 0; 9634e98e3e1Schristos } 9644e98e3e1Schristos 9654e98e3e1Schristos void 9664b169a6bSchristos reset_all(void) 9674e98e3e1Schristos { 9684e98e3e1Schristos init_event(); /* Clear event queue */ 9694e98e3e1Schristos init_regs(&sregs); 9704e98e3e1Schristos reset(); 9714e98e3e1Schristos #ifdef ERRINJ 9724e98e3e1Schristos errinjstart(); 9734e98e3e1Schristos #endif 9744e98e3e1Schristos } 9754e98e3e1Schristos 9764e98e3e1Schristos void 9774b169a6bSchristos sys_reset(void) 9784e98e3e1Schristos { 9794e98e3e1Schristos reset_all(); 9804e98e3e1Schristos sregs.trap = 256; /* Force fake reset trap */ 9814e98e3e1Schristos } 9824e98e3e1Schristos 9834e98e3e1Schristos void 9844b169a6bSchristos sys_halt(void) 9854e98e3e1Schristos { 9864e98e3e1Schristos sregs.trap = 257; /* Force fake halt trap */ 9874e98e3e1Schristos } 9884e98e3e1Schristos 9894e98e3e1Schristos #include "ansidecl.h" 9904e98e3e1Schristos 9914e98e3e1Schristos #include <stdarg.h> 9924e98e3e1Schristos 9934e98e3e1Schristos #include "libiberty.h" 9944e98e3e1Schristos #include "bfd.h" 9954e98e3e1Schristos 9964b169a6bSchristos #ifndef min 9974e98e3e1Schristos #define min(A, B) (((A) < (B)) ? (A) : (B)) 9984b169a6bSchristos #endif 9994e98e3e1Schristos #define LOAD_ADDRESS 0 10004e98e3e1Schristos 10014e98e3e1Schristos int 1002212397c6Schristos bfd_load (const char *fname) 10034e98e3e1Schristos { 10044e98e3e1Schristos asection *section; 10054e98e3e1Schristos bfd *pbfd; 1006212397c6Schristos int i; 10074e98e3e1Schristos 10084e98e3e1Schristos pbfd = bfd_openr(fname, 0); 10094e98e3e1Schristos 10104e98e3e1Schristos if (pbfd == NULL) { 10114e98e3e1Schristos printf("open of %s failed\n", fname); 1012212397c6Schristos return -1; 10134e98e3e1Schristos } 10144e98e3e1Schristos if (!bfd_check_format(pbfd, bfd_object)) { 10154e98e3e1Schristos printf("file %s doesn't seem to be an object file\n", fname); 1016212397c6Schristos return -1; 10174e98e3e1Schristos } 10184e98e3e1Schristos 10194e98e3e1Schristos if (sis_verbose) 10204e98e3e1Schristos printf("loading %s:", fname); 10214e98e3e1Schristos for (section = pbfd->sections; section; section = section->next) { 10228dffb485Schristos if (bfd_section_flags (section) & SEC_ALLOC) { 10234e98e3e1Schristos bfd_vma section_address; 10244e98e3e1Schristos unsigned long section_size; 10254e98e3e1Schristos const char *section_name; 10264e98e3e1Schristos 10278dffb485Schristos section_name = bfd_section_name (section); 10284e98e3e1Schristos 10298dffb485Schristos section_address = bfd_section_vma (section); 10304e98e3e1Schristos /* 10314e98e3e1Schristos * Adjust sections from a.out files, since they don't carry their 10324e98e3e1Schristos * addresses with. 10334e98e3e1Schristos */ 10344e98e3e1Schristos if (bfd_get_flavour(pbfd) == bfd_target_aout_flavour) { 10354e98e3e1Schristos if (strcmp (section_name, ".text") == 0) 10364e98e3e1Schristos section_address = bfd_get_start_address (pbfd); 10374e98e3e1Schristos else if (strcmp (section_name, ".data") == 0) { 10384e98e3e1Schristos /* Read the first 8 bytes of the data section. 10394e98e3e1Schristos There should be the string 'DaTa' followed by 10404e98e3e1Schristos a word containing the actual section address. */ 10414e98e3e1Schristos struct data_marker 10424e98e3e1Schristos { 10434e98e3e1Schristos char signature[4]; /* 'DaTa' */ 10444e98e3e1Schristos unsigned char sdata[4]; /* &sdata */ 10454e98e3e1Schristos } marker; 10464e98e3e1Schristos bfd_get_section_contents (pbfd, section, &marker, 0, 10474e98e3e1Schristos sizeof (marker)); 10484e98e3e1Schristos if (strncmp (marker.signature, "DaTa", 4) == 0) 10494e98e3e1Schristos { 10504e98e3e1Schristos section_address = bfd_getb32 (marker.sdata); 10514e98e3e1Schristos } 10524e98e3e1Schristos } 10534e98e3e1Schristos } 10544e98e3e1Schristos 10558dffb485Schristos section_size = bfd_section_size (section); 10564e98e3e1Schristos 10574e98e3e1Schristos if (sis_verbose) 10584b169a6bSchristos printf("\nsection %s at 0x%08" PRIx64 " (0x%lx bytes)", 10594b169a6bSchristos section_name, (uint64_t) section_address, section_size); 10604e98e3e1Schristos 10614e98e3e1Schristos /* Text, data or lit */ 10628dffb485Schristos if (bfd_section_flags (section) & SEC_LOAD) { 10634e98e3e1Schristos file_ptr fptr; 10644e98e3e1Schristos 10654e98e3e1Schristos fptr = 0; 10664e98e3e1Schristos 10674e98e3e1Schristos while (section_size > 0) { 10684e98e3e1Schristos char buffer[1024]; 10694e98e3e1Schristos int count; 10704e98e3e1Schristos 10714e98e3e1Schristos count = min(section_size, 1024); 10724e98e3e1Schristos 10734e98e3e1Schristos bfd_get_section_contents(pbfd, section, buffer, fptr, count); 10744e98e3e1Schristos 1075212397c6Schristos for (i = 0; i < count; i++) 1076212397c6Schristos sis_memory_write ((section_address + i) ^ EBT, &buffer[i], 1); 10774e98e3e1Schristos 10784e98e3e1Schristos section_address += count; 10794e98e3e1Schristos fptr += count; 10804e98e3e1Schristos section_size -= count; 10814e98e3e1Schristos } 10824e98e3e1Schristos } else /* BSS */ 10834e98e3e1Schristos if (sis_verbose) 10844e98e3e1Schristos printf("(not loaded)"); 10854e98e3e1Schristos } 10864e98e3e1Schristos } 10874e98e3e1Schristos if (sis_verbose) 10884e98e3e1Schristos printf("\n"); 10894e98e3e1Schristos 1090212397c6Schristos return bfd_get_start_address (pbfd); 1091212397c6Schristos } 1092212397c6Schristos 1093212397c6Schristos double get_time (void) 1094212397c6Schristos { 1095212397c6Schristos double usec; 1096212397c6Schristos 1097212397c6Schristos struct timeval tm; 1098212397c6Schristos 1099212397c6Schristos gettimeofday (&tm, NULL); 1100212397c6Schristos usec = ((double) tm.tv_sec) * 1E6 + ((double) tm.tv_usec); 1101212397c6Schristos return usec / 1E6; 11024e98e3e1Schristos } 1103