X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Ferc32%2Ffunc.c;h=4743aadf04c676cca919596d130da79ddc68c330;hb=3922b302645fda04da42a5279399578ae2f6206c;hp=2cd9bf2feb0cbc9588485857364e6cb040d25b18;hpb=fa803dc60f0bf01297674c41d001798e18ade4dc;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/erc32/func.c b/sim/erc32/func.c index 2cd9bf2feb..4743aadf04 100644 --- a/sim/erc32/func.c +++ b/sim/erc32/func.c @@ -1,85 +1,108 @@ -/* - * func.c, misc simulator functions. This file is part of SIS. - * - * SIS, SPARC instruction simulator V1.8 Copyright (C) 1995 Jiri Gaisler, - * European Space Agency - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 675 - * Mass Ave, Cambridge, MA 02139, USA. - * - */ +/* This file is part of SIS (SPARC instruction simulator) + Copyright (C) 1995-2020 Free Software Foundation, Inc. + Contributed by Jiri Gaisler, European Space Agency + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "config.h" #include #include #include +#include +#include #include "sis.h" -#include "end.h" #include +#include "sim-config.h" +#include - -#define VAL(x) strtol(x,(char *)NULL,0) - -extern char *readline(char *prompt); /* GNU readline function */ +#define VAL(x) strtoul(x,(char **)NULL,0) struct disassemble_info dinfo; struct pstate sregs; extern struct estate ebase; int ctrl_c = 0; int sis_verbose = 0; -char *sis_version = "2.1"; +char *sis_version = "2.7.5"; int nfp = 0; -char uart_dev1[128] = "/dev/ptypc"; -char uart_dev2[128] = "/dev/ptypd"; - -#ifdef IUREV0 -int iurev0 = 0; -#endif -#ifdef MECREV0 -int mecrev0 = 0; +int ift = 0; +int wrp = 0; +int rom8 = 0; +int uben = 0; +int termsave; +int sparclite = 0; /* emulating SPARClite instructions? */ +int sparclite_board = 0; /* emulating SPARClite board RAM? */ +char uart_dev1[128] = ""; +char uart_dev2[128] = ""; +extern int ext_irl; +uint32 last_load_addr = 0; + +#ifdef ERRINJ +uint32 errcnt = 0; +uint32 errper = 0; +uint32 errtt = 0; +uint32 errftt = 0; +uint32 errmec = 0; #endif -int +/* Forward declarations */ + +static int batch (struct pstate *sregs, char *fname); +static void set_rega (struct pstate *sregs, char *reg, uint32 rval); +static void disp_reg (struct pstate *sregs, char *reg); +static uint32 limcalc (float32 freq); +static void int_handler (int32 sig); +static void init_event (void); +static int disp_fpu (struct pstate *sregs); +static void disp_regs (struct pstate *sregs, int cwp); +static void disp_ctrl (struct pstate *sregs); +static void disp_mem (uint32 addr, uint32 len); + +static int batch(sregs, fname) struct pstate *sregs; char *fname; { FILE *fp; - char lbuf[1024]; + char *lbuf = NULL; + size_t len = 0; + size_t slen; if ((fp = fopen(fname, "r")) == NULL) { fprintf(stderr, "couldn't open batch file %s\n", fname); - return (0); + return 0; } - while (!feof(fp)) { - lbuf[0] = 0; - fgets(lbuf, 1023, fp); - if ((strlen(lbuf) > 0) && (lbuf[strlen(lbuf) - 1] == '\n')) - lbuf[strlen(lbuf) - 1] = 0; - printf("sis> %s\n", lbuf); - exec_cmd(sregs, lbuf); + while (getline(&lbuf, &len, fp) > -1) { + slen = strlen(lbuf); + if (slen && (lbuf[slen - 1] == '\n')) { + lbuf[slen - 1] = 0; + printf("sis> %s\n", lbuf); + exec_cmd(sregs, lbuf); + } } + free(lbuf); fclose(fp); - return (1); + return 1; } +void set_regi(sregs, reg, rval) struct pstate *sregs; int32 reg; uint32 rval; { uint32 cwp; - int32 err = 0; cwp = ((sregs->psr & 0x7) << 4); if ((reg > 0) && (reg < 8)) { @@ -112,7 +135,7 @@ set_regi(sregs, reg, rval) sregs->fsr = rval; set_fsr(rval); break; - defualt:break; + default:break; } } } @@ -153,7 +176,7 @@ get_regi(struct pstate * sregs, int32 reg, char *buf) case 70: rval = sregs->fsr; break; - defualt:break; + default:break; } } buf[0] = (rval >> 24) & 0x0ff; @@ -163,6 +186,7 @@ get_regi(struct pstate * sregs, int32 reg, char *buf) } +static void set_rega(sregs, reg, rval) struct pstate *sregs; char *reg; @@ -269,6 +293,7 @@ set_rega(sregs, reg, rval) } +static void disp_reg(sregs, reg) struct pstate *sregs; char *reg; @@ -277,19 +302,82 @@ disp_reg(sregs, reg) disp_regs(sregs, VAL(®[1])); } -exec_cmd(sregs, cmd) - char *cmd; - struct pstate *sregs; +#ifdef ERRINJ + +void +errinj() +{ + int err; + + switch (err = (random() % 12)) { + case 0: errtt = 0x61; break; + case 1: errtt = 0x62; break; + case 2: errtt = 0x63; break; + case 3: errtt = 0x64; break; + case 4: errtt = 0x65; break; + case 5: + case 6: + case 7: errftt = err; + break; + case 8: errmec = 1; break; + case 9: errmec = 2; break; + case 10: errmec = 5; break; + case 11: errmec = 6; break; + } + errcnt++; + if (errper) event(errinj, 0, (random()%errper)); +} + +void +errinjstart() +{ + if (errper) event(errinj, 0, (random()%errper)); +} + +#endif + +static uint32 +limcalc (freq) + float32 freq; +{ + uint32 unit, lim; + double flim; + char *cmd1, *cmd2; + + unit = 1; + lim = -1; + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + lim = VAL(cmd1); + if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) { + if (strcmp(cmd2,"us")==0) unit = 1; + if (strcmp(cmd2,"ms")==0) unit = 1000; + if (strcmp(cmd2,"s")==0) unit = 1000000; + } + flim = (double) lim * (double) unit * (double) freq + + (double) ebase.simtime; + if ((flim > ebase.simtime) && (flim < 4294967296.0)) { + lim = (uint32) flim; + } else { + printf("error in expression\n"); + lim = -1; + } + } + return lim; +} + +int +exec_cmd(struct pstate *sregs, const char *cmd) { char *cmd1, *cmd2; - int32 ws, stat; - int32 len, i, clen, j; - static daddr = 0; - char *cmdsave; + int32 stat; + uint32 len, i, clen, j; + static uint32 daddr = 0; + char *cmdsave, *cmdsave2 = NULL; stat = OK; cmdsave = strdup(cmd); - if ((cmd1 = strtok(cmd, " \t")) != NULL) { + cmdsave2 = strdup (cmd); + if ((cmd1 = strtok (cmdsave2, " \t")) != NULL) { clen = strlen(cmd1); if (strncmp(cmd1, "bp", clen) == 0) { for (i = 0; i < sregs->bptnum; i++) { @@ -322,12 +410,17 @@ exec_cmd(sregs, cmd) } } else if (strncmp(cmd1, "cont", clen) == 0) { if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { - stat = run_sim(sregs, 1, 0, 0); + stat = run_sim(sregs, UINT64_MAX, 0); } else { - stat = run_sim(sregs, 0, VAL(cmd1), 0); + stat = run_sim(sregs, VAL(cmd1), 0); } daddr = sregs->pc; - sim_stop(); + sim_halt(); + } else if (strncmp(cmd1, "debug", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + sis_verbose = VAL(cmd1); + } + printf("Debug level = %d\n",sis_verbose); } else if (strncmp(cmd1, "dis", clen) == 0) { if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { daddr = VAL(cmd1); @@ -344,23 +437,36 @@ exec_cmd(sregs, cmd) if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { printf("%s\n", (&cmdsave[clen+1])); } +#ifdef ERRINJ + } else if (strncmp(cmd1, "error", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + errper = VAL(cmd1); + if (errper) { + event(errinj, 0, (len = (random()%errper))); + printf("Error injection started with period %d\n",len); + } + } else printf("Injected errors: %d\n",errcnt); +#endif } else if (strncmp(cmd1, "float", clen) == 0) { stat = disp_fpu(sregs); } else if (strncmp(cmd1, "go", clen) == 0) { if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { - printf("wrong syntax: go
[inst_count]\n"); + len = last_load_addr; } else { len = VAL(cmd1); - sregs->pc = len & ~3; - sregs->npc = sregs->pc + 4; - if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) { - stat = run_sim(sregs, 0, VAL(cmd2), 0); - } else { - stat = run_sim(sregs, 1, 0, 0); - } + } + sregs->pc = len & ~3; + sregs->npc = sregs->pc + 4; + if ((sregs->pc != 0) && (ebase.simtime == 0)) + boot_init(); + printf("resuming at 0x%08x\n",sregs->pc); + if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) { + stat = run_sim(sregs, VAL(cmd2), 0); + } else { + stat = run_sim(sregs, UINT64_MAX, 0); } daddr = sregs->pc; - sim_stop(); + sim_halt(); } else if (strncmp(cmd1, "help", clen) == 0) { gen_help(); } else if (strncmp(cmd1, "history", clen) == 0) { @@ -385,7 +491,9 @@ exec_cmd(sregs, cmd) } else if (strncmp(cmd1, "load", clen) == 0) { if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { - bfd_load(cmd1); + last_load_addr = bfd_load(cmd1); + while ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) + last_load_addr = bfd_load(cmd1); } else { printf("load: no file specified\n"); } @@ -427,42 +535,78 @@ exec_cmd(sregs, cmd) reset_all(); reset_stat(sregs); if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { - stat = run_sim(sregs, 1, 0, 0); + stat = run_sim(sregs, UINT64_MAX, 0); } else { - stat = run_sim(sregs, 0, VAL(cmd1), 0); + stat = run_sim(sregs, VAL(cmd1), 0); } daddr = sregs->pc; - sim_stop(); + sim_halt(); } else if (strncmp(cmd1, "shell", clen) == 0) { if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { - system(&cmdsave[clen]); + if (system(&cmdsave[clen])) { + /* Silence unused return value warning. */ + } } } else if (strncmp(cmd1, "step", clen) == 0) { - stat = run_sim(sregs, 0, 1, 1); + stat = run_sim(sregs, 1, 1); + daddr = sregs->pc; + sim_halt(); + } else if (strncmp(cmd1, "tcont", clen) == 0) { + sregs->tlimit = limcalc(sregs->freq); + stat = run_sim(sregs, UINT64_MAX, 0); daddr = sregs->pc; - sim_stop(); + sim_halt(); + } else if (strncmp(cmd1, "tgo", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { + len = last_load_addr; + } else { + len = VAL(cmd1); + sregs->tlimit = limcalc(sregs->freq); + } + sregs->pc = len & ~3; + sregs->npc = sregs->pc + 4; + printf("resuming at 0x%08x\n",sregs->pc); + stat = run_sim(sregs, UINT64_MAX, 0); + daddr = sregs->pc; + sim_halt(); + } else if (strncmp(cmd1, "tlimit", clen) == 0) { + sregs->tlimit = limcalc(sregs->freq); + if (sregs->tlimit != (uint32) -1) + printf("simulation limit = %u (%.3f ms)\n",(uint32) sregs->tlimit, + sregs->tlimit / sregs->freq / 1000); } else if (strncmp(cmd1, "tra", clen) == 0) { if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { - stat = run_sim(sregs, 1, 0, 1); + stat = run_sim(sregs, UINT64_MAX, 1); } else { - stat = run_sim(sregs, 0, VAL(cmd1), 1); + stat = run_sim(sregs, VAL(cmd1), 1); } printf("\n"); daddr = sregs->pc; - sim_stop(); + sim_halt(); + } else if (strncmp(cmd1, "trun", clen) == 0) { + ebase.simtime = 0; + reset_all(); + reset_stat(sregs); + sregs->tlimit = limcalc(sregs->freq); + stat = run_sim(sregs, UINT64_MAX, 0); + daddr = sregs->pc; + sim_halt(); } else printf("syntax error\n"); } + if (cmdsave2 != NULL) + free(cmdsave2); if (cmdsave != NULL) free(cmdsave); - return (stat); + return stat; } +void reset_stat(sregs) struct pstate *sregs; { - sregs->tottime = 0; + sregs->tottime = 0.0; sregs->pwdtime = 0; sregs->ninst = 0; sregs->fholdt = 0; @@ -476,13 +620,15 @@ reset_stat(sregs) } +void show_stat(sregs) struct pstate *sregs; { - int32 simperf = 0; uint32 iinst; uint32 stime; + if (sregs->tottime == 0.0) + sregs->tottime += 1E-6; stime = ebase.simtime - sregs->simstart; /* Total simulated time */ #ifdef STAT @@ -490,8 +636,8 @@ show_stat(sregs) sregs->nbranch; #endif - printf("\n Cycles : %9d\n\r", ebase.simtime - sregs->simstart); - printf(" Instructions : %9d\n", sregs->ninst); + printf("\n Cycles : %9" PRIu64 "\n\r", ebase.simtime - sregs->simstart); + printf(" Instructions : %9" PRIu64 "\n", sregs->ninst); #ifdef STAT printf(" integer : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst); @@ -517,15 +663,20 @@ show_stat(sregs) sregs->freq * (float) (sregs->ninst - sregs->finst) / (float) (stime - sregs->pwdtime), sregs->freq * (float) sregs->finst / (float) (stime - sregs->pwdtime)); - printf(" Simulated ERC32 time : %5.2f ms\n", (float) (ebase.simtime - sregs->simstart) / 1000.0 / sregs->freq); - printf(" Processor utilisation : %5.2f %%\n", 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime))); - printf(" Real-time / simulator-time : %5.2f \n", - ((float) sregs->tottime) / ((float) (stime) / (sregs->freq * 1.0E6))); - printf(" Used time (sys + user) : %3d s\n\n", sregs->tottime); + printf(" Simulated ERC32 time : %.2f s\n", + (float) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq); + printf(" Processor utilisation : %.2f %%\n", + 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime))); + printf(" Real-time performance : %.2f %%\n", + 100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6)))); + printf(" Simulator performance : %.2f MIPS\n", + (double)(sregs->ninst) / sregs->tottime / 1E6); + printf(" Used time (sys + user) : %.2f s\n\n", sregs->tottime); } +void init_bpt(sregs) struct pstate *sregs; { @@ -533,10 +684,10 @@ init_bpt(sregs) sregs->histlen = 0; sregs->histind = 0; sregs->histbuf = NULL; - + sregs->tlimit = -1; } -void +static void int_handler(sig) int32 sig; { @@ -545,6 +696,7 @@ int_handler(sig) ctrl_c = 1; } +void init_signals() { typedef void (*PFI) (); @@ -560,21 +712,20 @@ extern struct disassemble_info dinfo; struct estate ebase; struct evcell evbuf[EVENT_MAX]; struct irqcell irqarr[16]; -int32 irqpend, ext_irl = 0; +static int disp_fpu(sregs) struct pstate *sregs; { - int i, j; + int i; float t; printf("\n fsr: %08X\n\n", sregs->fsr); -#ifdef HOST_LITTLE_ENDIAN_FLOAT - for (i = 0; i < 32; i++) { - sregs->fdp[i ^ 1] = sregs->fs[i]; - } +#ifdef HOST_LITTLE_ENDIAN + for (i = 0; i < 32; i++) + sregs->fdp[i ^ 1] = sregs->fs[i]; #endif for (i = 0; i < 32; i++) { @@ -586,9 +737,10 @@ disp_fpu(sregs) printf("\n"); } printf("\n"); - return (OK); + return OK; } +static void disp_regs(sregs,cwp) struct pstate *sregs; int cwp; @@ -606,6 +758,18 @@ disp_regs(sregs,cwp) } } +static void print_insn_sparc_sis(uint32 addr, struct disassemble_info *info) +{ + unsigned char i[4]; + + sis_memory_read(addr, i, 4); + dinfo.buffer_vma = addr; + dinfo.buffer_length = 4; + dinfo.buffer = i; + print_insn_sparc(addr, info); +} + +static void disp_ctrl(sregs) struct pstate *sregs; { @@ -614,104 +778,84 @@ disp_ctrl(sregs) printf("\n psr: %08X wim: %08X tbr: %08X y: %08X\n", sregs->psr, sregs->wim, sregs->tbr, sregs->y); - sis_memory_read(sregs->pc, &i, 4); - printf("\n pc: %08X = %08X ", sregs->pc, i); - print_insn_sparc(sregs->pc, &dinfo); - sis_memory_read(sregs->npc, &i, 4); - printf("\n npc: %08X = %08X ", sregs->npc, i); - print_insn_sparc(sregs->npc, &dinfo); + sis_memory_read (sregs->pc, (char *) &i, 4); + printf ("\n pc: %08X = %08X ", sregs->pc, i); + print_insn_sparc_sis(sregs->pc, &dinfo); + sis_memory_read (sregs->npc, (char *) &i, 4); + printf ("\n npc: %08X = %08X ", sregs->npc, i); + print_insn_sparc_sis(sregs->npc, &dinfo); if (sregs->err_mode) printf("\n IU in error mode"); printf("\n\n"); } +static void disp_mem(addr, len) uint32 addr; uint32 len; { - int32 i, data, ws; - int32 mem[4], j; + uint32 i; + union { + unsigned char u8[4]; + uint32 u32; + } data; + uint32 mem[4], j; char *p; for (i = addr & ~3; i < ((addr + len) & ~3); i += 16) { printf("\n %8X ", i); for (j = 0; j < 4; j++) { - sis_memory_read((i + (j * 4)), &data, 4); - printf("%08x ", data); - mem[j] = data; + sis_memory_read ((i + (j * 4)), data.u8, 4); + printf ("%08x ", data.u32); + mem[j] = data.u32; } printf(" "); p = (char *) mem; for (j = 0; j < 16; j++) { - if (isprint(p[j])) - putchar(p[j]); + if (isprint (p[j ^ EBT])) + putchar (p[j ^ EBT]); else putchar('.'); } } printf("\n\n"); } + +void dis_mem(addr, len, info) uint32 addr; uint32 len; struct disassemble_info *info; { - int32 i, data, ws; + uint32 i; + union { + unsigned char u8[4]; + uint32 u32; + } data; for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) { - sis_memory_read(i, &data, 4); - printf(" %08x %08x ", i, data); - print_insn_sparc(i, info); + sis_memory_read (i, data.u8, 4); + printf (" %08x %08x ", i, data.u32); + print_insn_sparc_sis(i, info); + if (i >= 0xfffffffc) break; printf("\n"); } - return (OK); -} - -int -buffer_read_memory(addr, buffer, size, info) - bfd_vma addr; - bfd_byte *buffer; - int32 size; - struct disassemble_info *info; -{ - if (size == sis_memory_read(addr, buffer, size)) - return (0); - else - return (1); -} - -void -perror_memory(status, addr, info) - int32 status; - bfd_vma addr; - struct disassemble_info *info; -{ - - printf("Could not read address 0x%08x\n", addr); -} - -void -generic_print_address(addr, info) - bfd_vma addr; - struct disassemble_info *info; -{ - - printf("0x%x", addr); } /* Add event to event queue */ +void event(cfunc, arg, delta) void (*cfunc) (); int32 arg; - uint32 delta; + uint64 delta; { struct evcell *ev1, *evins; if (ebase.freeq == NULL) { printf("Error, too many events in event queue\n"); - return (0); + return; } ev1 = &ebase.eq; delta += ebase.simtime; @@ -733,10 +877,14 @@ event(cfunc, arg, delta) ev1->nxt->arg = arg; } +#if 0 /* apparently not used */ +void stop_event() { } +#endif +void init_event() { int32 i; @@ -749,6 +897,7 @@ init_event() evbuf[EVENT_MAX - 1].nxt = NULL; } +void set_int(level, callback, arg) int32 level; void (*callback) (); @@ -756,39 +905,19 @@ set_int(level, callback, arg) { irqarr[level & 0x0f].callback = callback; irqarr[level & 0x0f].arg = arg; - irqpend |= (1 << level); - if (level > ext_irl) - ext_irl = level; - -} - -clear_int(level) - int32 level; -{ - int32 tmpirq = irqpend; - - irqpend &= ~(1 << level); - ext_irl = 0; - if (irqpend) { - tmpirq >>= 1; - while (tmpirq) { - ext_irl++; - tmpirq >>= 1; - } - } } /* Advance simulator time */ +void advance_time(sregs) struct pstate *sregs; { struct evcell *evrem; void (*cfunc) (); - uint32 arg, endtime, ws; - - ws = sregs->icnt + sregs->hold + sregs->fhold; + uint32 arg; + uint64 endtime; #ifdef STAT sregs->fholdt += sregs->fhold; @@ -796,8 +925,9 @@ advance_time(sregs) sregs->icntt += sregs->icnt; #endif - endtime = ebase.simtime += ws; - while ((ebase.eq.nxt != NULL) && (ebase.eq.nxt->time <= (endtime))) { + endtime = ebase.simtime + sregs->icnt + sregs->hold + sregs->fhold; + + while ((ebase.eq.nxt->time <= (endtime)) && (ebase.eq.nxt != NULL)) { ebase.simtime = ebase.eq.nxt->time; cfunc = ebase.eq.nxt->cfunc; arg = ebase.eq.nxt->arg; @@ -811,6 +941,13 @@ advance_time(sregs) } +uint32 +now() +{ + return ebase.simtime; +} + + /* Advance time until an external interrupt is seen */ int @@ -818,7 +955,8 @@ wait_for_irq() { struct evcell *evrem; void (*cfunc) (); - int32 arg, endtime; + int32 arg; + uint64 endtime; if (ebase.eq.nxt == NULL) printf("Warning: event queue empty - power-down mode not entered\n"); @@ -838,7 +976,7 @@ wait_for_irq() } } sregs.pwdtime += ebase.simtime - endtime; - return (ebase.simtime - endtime); + return ebase.simtime - endtime; } int @@ -848,34 +986,41 @@ check_bpt(sregs) int32 i; if ((sregs->bphit) || (sregs->annul)) - return (0); - for (i = 0; i < sregs->bptnum; i++) { + return 0; + for (i = 0; i < (int32) sregs->bptnum; i++) { if (sregs->pc == sregs->bpts[i]) - return (BPT_HIT); + return BPT_HIT; } - return (0); + return 0; } +void reset_all() { init_event(); /* Clear event queue */ init_regs(&sregs); reset(); +#ifdef ERRINJ + errinjstart(); +#endif } +void sys_reset() { reset_all(); sregs.trap = 256; /* Force fake reset trap */ } +void +sys_halt() +{ + sregs.trap = 257; /* Force fake halt trap */ +} + #include "ansidecl.h" -#ifdef ANSI_PROTOTYPES #include -#else -#include -#endif #include "libiberty.h" #include "bfd.h" @@ -884,48 +1029,69 @@ sys_reset() #define LOAD_ADDRESS 0 int -bfd_load(fname) - char *fname; +bfd_load (const char *fname) { - int cc, c; - unsigned char buf[10]; asection *section; bfd *pbfd; - unsigned long entry; + const bfd_arch_info_type *arch; + int i; pbfd = bfd_openr(fname, 0); if (pbfd == NULL) { printf("open of %s failed\n", fname); - return (0); + return -1; } if (!bfd_check_format(pbfd, bfd_object)) { printf("file %s doesn't seem to be an object file\n", fname); - return (0); + return -1; } - printf("loading %s:", fname); + + arch = bfd_get_arch_info (pbfd); + if (sis_verbose) + printf("loading %s:", fname); for (section = pbfd->sections; section; section = section->next) { - if (bfd_get_section_flags(pbfd, section) & SEC_ALLOC) { + if (bfd_section_flags (section) & SEC_ALLOC) { bfd_vma section_address; unsigned long section_size; const char *section_name; - section_name = bfd_get_section_name(pbfd, section); + section_name = bfd_section_name (section); - section_address = bfd_get_section_vma(pbfd, section); + section_address = bfd_section_vma (section); /* * Adjust sections from a.out files, since they don't carry their * addresses with. */ - if (bfd_get_flavour(pbfd) == bfd_target_aout_flavour) - section_address += bfd_get_start_address (pbfd); - section_size = bfd_section_size(pbfd, section); + if (bfd_get_flavour(pbfd) == bfd_target_aout_flavour) { + if (strcmp (section_name, ".text") == 0) + section_address = bfd_get_start_address (pbfd); + else if (strcmp (section_name, ".data") == 0) { + /* Read the first 8 bytes of the data section. + There should be the string 'DaTa' followed by + a word containing the actual section address. */ + struct data_marker + { + char signature[4]; /* 'DaTa' */ + unsigned char sdata[4]; /* &sdata */ + } marker; + bfd_get_section_contents (pbfd, section, &marker, 0, + sizeof (marker)); + if (strncmp (marker.signature, "DaTa", 4) == 0) + { + section_address = bfd_getb32 (marker.sdata); + } + } + } - printf("\nsection %s at 0x%08lx (%ld bytes)", - section_name, section_address, section_size); + section_size = bfd_section_size (section); + + if (sis_verbose) + printf("\nsection %s at 0x%08lx (0x%lx bytes)", + section_name, section_address, section_size); /* Text, data or lit */ - if (bfd_get_section_flags(pbfd, section) & SEC_LOAD) { + if (bfd_section_flags (section) & SEC_LOAD) { file_ptr fptr; fptr = 0; @@ -938,31 +1104,31 @@ bfd_load(fname) bfd_get_section_contents(pbfd, section, buffer, fptr, count); - sis_memory_write(section_address, buffer, count); + for (i = 0; i < count; i++) + sis_memory_write ((section_address + i) ^ EBT, &buffer[i], 1); section_address += count; fptr += count; section_size -= count; } } else /* BSS */ - printf("(not loaded)"); + if (sis_verbose) + printf("(not loaded)"); } } - printf("\n"); - - /* - * entry = bfd_get_start_address (pbfd); - * - * printf ("[Starting %s at 0x%lx]\n", fname, entry); - */ + if (sis_verbose) + printf("\n"); - return (1); + return bfd_get_start_address (pbfd); } -void -sim_set_callbacks (ptr) -struct host_callback_struct *ptr; +double get_time (void) { + double usec; -} + struct timeval tm; + gettimeofday (&tm, NULL); + usec = ((double) tm.tv_sec) * 1E6 + ((double) tm.tv_usec); + return usec / 1E6; +}