diff options
-rw-r--r-- | sim/erc32/ChangeLog | 34 | ||||
-rw-r--r-- | sim/erc32/func.c | 415 | ||||
-rw-r--r-- | sim/erc32/interf.c | 114 |
3 files changed, 395 insertions, 168 deletions
diff --git a/sim/erc32/ChangeLog b/sim/erc32/ChangeLog index 04a3642..fddec3a 100644 --- a/sim/erc32/ChangeLog +++ b/sim/erc32/ChangeLog @@ -1,3 +1,37 @@ +Tue Jun 2 15:20:35 1998 Mark Alexander <marka@cygnus.com> + + * interf.c (sim_open): Use revamped memory_read, which makes + byte-swapping unnecessary. Add -sparclite-board option for + emulating RAM found on typical SPARClite boards. Print + error message for unrecognized option. + * erc32.c: Change RAM address and size from constants to variables, + to allow emulation of SPARClite board RAM. + (fetch_bytes, store_bytes): New helper functions for revamped + mememory_read and memory_write. + (memory_read, memory_write): Rewrite to store bytes in target + byte order instead of storing words in host byte order; this + greatly simplifies support of little-endian programs. + (get_mem_ptr): Remove unnecessary byte parameter. + (sis_memory_write, sis_memory_read): Store words in target + byte order instead of host byte order. + (byte_swap_words): Remove, no longer needed. + * sis.h ((byte_swap_words): Remove declaration, no longer needed. + (memory_read): Add new sz parameter. + * sis.c (run_sim): Use revamped memory_read, which makes + byte-swapping unnecessary. + * exec.c (dispatch_instruction): Use revamped memory_read, which + makes byte-swapping and double-word fetching unnecessary. + * func.c (sparclite_board): Declare new variable. + (get_regi): Handle little-endian data. + (bfd_load): Recognize little-endian SPARClite as having + little-endian data. + +Fri May 22 14:23:16 1998 Mark Alexander <marka@cygnus.com> + + * erc32.c (port_init): Print messages only if sis_verbose is true. + * func.c (bfd_load): Ditto. + * interf.c (sim_open): Ditto. + Thu May 14 23:10:48 1998 Mark Alexander <marka@cygnus.com> * sis.h (uint64, int64): Define. diff --git a/sim/erc32/func.c b/sim/erc32/func.c index 2cd9bf2..d2427b7 100644 --- a/sim/erc32/func.c +++ b/sim/erc32/func.c @@ -23,33 +23,58 @@ #include <signal.h> #include <string.h> #include <stdio.h> +#include <stdlib.h> +#include <ctype.h> #include "sis.h" #include "end.h" #include <dis-asm.h> +#include "sim-config.h" -#define VAL(x) strtol(x,(char *)NULL,0) - -extern char *readline(char *prompt); /* GNU readline function */ +#define VAL(x) strtoul(x,(char **)NULL,0) +extern int current_target_byte_order; 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 PARAMS ((struct pstate *sregs, char *fname)); +static void set_rega PARAMS ((struct pstate *sregs, char *reg, uint32 rval)); +static void disp_reg PARAMS ((struct pstate *sregs, char *reg)); +static uint32 limcalc PARAMS ((float32 freq)); +static void int_handler PARAMS ((int32 sig)); +static void init_event PARAMS ((void)); +static int disp_fpu PARAMS ((struct pstate *sregs)); +static void disp_regs PARAMS ((struct pstate *sregs, int cwp)); +static void disp_ctrl PARAMS ((struct pstate *sregs)); +static void disp_mem PARAMS ((uint32 addr, uint32 len)); + +static int batch(sregs, fname) struct pstate *sregs; char *fname; @@ -73,13 +98,13 @@ batch(sregs, fname) 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 +137,7 @@ set_regi(sregs, reg, rval) sregs->fsr = rval; set_fsr(rval); break; - defualt:break; + default:break; } } } @@ -153,16 +178,25 @@ get_regi(struct pstate * sregs, int32 reg, char *buf) case 70: rval = sregs->fsr; break; - defualt:break; + default:break; } } - buf[0] = (rval >> 24) & 0x0ff; - buf[1] = (rval >> 16) & 0x0ff; - buf[2] = (rval >> 8) & 0x0ff; - buf[3] = rval & 0x0ff; + if (current_target_byte_order == BIG_ENDIAN) { + buf[0] = (rval >> 24) & 0x0ff; + buf[1] = (rval >> 16) & 0x0ff; + buf[2] = (rval >> 8) & 0x0ff; + buf[3] = rval & 0x0ff; + } + else { + buf[3] = (rval >> 24) & 0x0ff; + buf[2] = (rval >> 16) & 0x0ff; + buf[1] = (rval >> 8) & 0x0ff; + buf[0] = rval & 0x0ff; + } } +static void set_rega(sregs, reg, rval) struct pstate *sregs; char *reg; @@ -269,6 +303,7 @@ set_rega(sregs, reg, rval) } +static void disp_reg(sregs, reg) struct pstate *sregs; char *reg; @@ -277,14 +312,78 @@ disp_reg(sregs, reg) disp_regs(sregs, VAL(®[1])); } +#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(sregs, cmd) char *cmd; struct pstate *sregs; { char *cmd1, *cmd2; - int32 ws, stat; - int32 len, i, clen, j; - static daddr = 0; + int32 stat; + uint32 len, i, clen, j; + static uint32 daddr = 0; char *cmdsave; stat = OK; @@ -322,12 +421,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, -1, 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 +448,34 @@ 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 <address> [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; + 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, -1, 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 +500,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,29 +544,60 @@ 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, -1, 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]); } } 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, -1, 0); + daddr = sregs->pc; + 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, -1, 0); daddr = sregs->pc; - sim_stop(); + 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, -1, 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, -1, 0); + daddr = sregs->pc; + sim_halt(); } else printf("syntax error\n"); } @@ -459,6 +607,7 @@ exec_cmd(sregs, cmd) } +void reset_stat(sregs) struct pstate *sregs; { @@ -476,13 +625,14 @@ reset_stat(sregs) } +void show_stat(sregs) struct pstate *sregs; { - int32 simperf = 0; uint32 iinst; - uint32 stime; + uint32 stime, tottime; + if (sregs->tottime == 0) tottime = 1; else tottime = sregs->tottime; stime = ebase.simtime - sregs->simstart; /* Total simulated time */ #ifdef STAT @@ -519,13 +669,15 @@ show_stat(sregs) 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", + printf(" Real-time / simulator-time : 1/%.2f \n", ((float) sregs->tottime) / ((float) (stime) / (sregs->freq * 1.0E6))); + printf(" Simulator performance : %d KIPS\n",sregs->ninst/tottime/1000); printf(" Used time (sys + user) : %3d s\n\n", sregs->tottime); } +void init_bpt(sregs) struct pstate *sregs; { @@ -533,10 +685,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 +697,7 @@ int_handler(sig) ctrl_c = 1; } +void init_signals() { typedef void (*PFI) (); @@ -560,21 +713,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]; - } + for (i = 0; i < 32; i++) + sregs->fdp[i ^ 1] = sregs->fs[i]; #endif for (i = 0; i < 32; i++) { @@ -589,6 +741,7 @@ disp_fpu(sregs) return (OK); } +static void disp_regs(sregs,cwp) struct pstate *sregs; int cwp; @@ -606,40 +759,43 @@ disp_regs(sregs,cwp) } } +static void disp_ctrl(sregs) struct pstate *sregs; { - uint32 i; + unsigned char i[4]; 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); + sis_memory_read(sregs->pc, i, 4); + printf("\n pc: %08X = %02X%02X%02X%02X ", sregs->pc,i[0],i[1],i[2],i[3]); print_insn_sparc(sregs->pc, &dinfo); - sis_memory_read(sregs->npc, &i, 4); - printf("\n npc: %08X = %08X ", sregs->npc, i); + sis_memory_read(sregs->npc, i, 4); + printf("\n npc: %08X = %02X%02X%02X%02X ",sregs->npc,i[0],i[1],i[2],i[3]); print_insn_sparc(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; + unsigned char data[4]; + 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, 4); + printf("%02x%02x%02x%02x ", data[0],data[1],data[2],data[3]); + mem[j] = *((int *) &data); } printf(" "); p = (char *) mem; @@ -652,20 +808,23 @@ disp_mem(addr, len) } printf("\n\n"); } + +void dis_mem(addr, len, info) uint32 addr; uint32 len; struct disassemble_info *info; { - int32 i, data, ws; + uint32 i; + unsigned char data[4]; for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) { - sis_memory_read(i, &data, 4); - printf(" %08x %08x ", i, data); + sis_memory_read(i, data, 4); + printf(" %08x %02x%02x%02x%02x ", i, data[0],data[1],data[2],data[3]); print_insn_sparc(i, info); + if (i >= 0xfffffffc) break; printf("\n"); } - return (OK); } int @@ -688,7 +847,7 @@ perror_memory(status, addr, info) struct disassemble_info *info; { - printf("Could not read address 0x%08x\n", addr); + printf("Could not read address 0x%08x\n", (unsigned int) addr); } void @@ -697,11 +856,23 @@ generic_print_address(addr, info) struct disassemble_info *info; { - printf("0x%x", addr); + printf("0x%x", (unsigned int) addr); } +/* Just return the given address. */ + +int +generic_symbol_at_address (addr, info) + bfd_vma addr; + struct disassemble_info * info; +{ + return 1; +} + + /* Add event to event queue */ +void event(cfunc, arg, delta) void (*cfunc) (); int32 arg; @@ -711,7 +882,7 @@ event(cfunc, arg, delta) if (ebase.freeq == NULL) { printf("Error, too many events in event queue\n"); - return (0); + return; } ev1 = &ebase.eq; delta += ebase.simtime; @@ -733,10 +904,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 +924,7 @@ init_event() evbuf[EVENT_MAX - 1].nxt = NULL; } +void set_int(level, callback, arg) int32 level; void (*callback) (); @@ -756,39 +932,18 @@ 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, endtime; #ifdef STAT sregs->fholdt += sregs->fhold; @@ -796,8 +951,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 +967,13 @@ advance_time(sregs) } +uint32 +now() +{ + return(ebase.simtime); +} + + /* Advance time until an external interrupt is seen */ int @@ -849,26 +1012,37 @@ check_bpt(sregs) if ((sregs->bphit) || (sregs->annul)) return (0); - for (i = 0; i < sregs->bptnum; i++) { + for (i = 0; i < (int32) sregs->bptnum; i++) { if (sregs->pc == sregs->bpts[i]) return (BPT_HIT); } 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 @@ -887,23 +1061,31 @@ int bfd_load(fname) char *fname; { - int cc, c; - unsigned char buf[10]; asection *section; bfd *pbfd; - unsigned long entry; + const bfd_arch_info_type *arch; 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 (bfd_little_endian (pbfd) || arch->mach == bfd_mach_sparc_sparclite_le) + current_target_byte_order = LITTLE_ENDIAN; + else + current_target_byte_order = BIG_ENDIAN; + if (sis_verbose) + printf("file %s is little-endian.\n", fname); + + if (sis_verbose) + printf("loading %s:", fname); for (section = pbfd->sections; section; section = section->next) { if (bfd_get_section_flags(pbfd, section) & SEC_ALLOC) { bfd_vma section_address; @@ -921,8 +1103,9 @@ bfd_load(fname) section_address += bfd_get_start_address (pbfd); section_size = bfd_section_size(pbfd, section); - printf("\nsection %s at 0x%08lx (%ld bytes)", - section_name, section_address, section_size); + if (sis_verbose) + printf("\nsection %s at 0x%08lx (%ld bytes)", + section_name, section_address, section_size); /* Text, data or lit */ if (bfd_get_section_flags(pbfd, section) & SEC_LOAD) { @@ -945,24 +1128,12 @@ bfd_load(fname) 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); - */ - - return (1); -} - -void -sim_set_callbacks (ptr) -struct host_callback_struct *ptr; -{ + if (sis_verbose) + printf("\n"); + return(bfd_get_start_address (pbfd)); } - diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c index 4ea62cf..d4a84c3 100644 --- a/sim/erc32/interf.c +++ b/sim/erc32/interf.c @@ -23,10 +23,13 @@ #include <signal.h> #include <string.h> #include <stdio.h> +#include <stdlib.h> +#include <time.h> #include <sys/fcntl.h> #include "sis.h" #include "bfd.h" #include <dis-asm.h> +#include "sim-config.h" #include "remote-sim.h" @@ -34,7 +37,9 @@ extern fprintf(); #endif -#define VAL(x) strtol(x,(char *)NULL,0) +#define PSR_CWP 0x7 + +#define VAL(x) strtol(x,(char **)NULL,0) extern char **buildargv(char *input); @@ -42,11 +47,13 @@ extern struct disassemble_info dinfo; extern struct pstate sregs; extern struct estate ebase; +extern int current_target_byte_order; extern int ctrl_c; extern int nfp; extern int ift; extern int rom8; extern int wrp; +extern int uben; extern int sis_verbose; extern char *sis_version; extern struct estate ebase; @@ -54,6 +61,7 @@ extern struct evcell evbuf[]; extern struct irqcell irqarr[]; extern int irqpend, ext_irl; extern int sparclite; +extern int sparclite_board; extern int termsave; extern char uart_dev1[], uart_dev2[]; @@ -61,25 +69,24 @@ int sis_gdb_break = 1; host_callback *sim_callback; -run_sim(sregs, go, icount, dis) +int +run_sim(sregs, icount, dis) struct pstate *sregs; - int go; unsigned int icount; int dis; { - int mexc, ws; + int mexc; if (sis_verbose) (*sim_callback->printf_filtered) (sim_callback, "resuming at %x\n", sregs->pc); init_stdio(); sregs->starttime = time(NULL); - while ((!sregs->err_mode & (go || (icount > 0))) && - ((sregs->bptnum == 0) || !(sregs->bphit = check_bpt(sregs)))) { + while (!sregs->err_mode & (icount > 0)) { sregs->fhold = 0; sregs->hold = 0; - sregs->icnt = 0; + sregs->icnt = 1; check_interrupts(sregs); if (sregs->trap) { @@ -90,7 +97,13 @@ run_sim(sregs, go, icount, dis) else sregs->asi = 9; - mexc = memory_read(sregs->asi, sregs->pc, &sregs->inst, &sregs->hold); +#if 0 /* DELETE ME! for debugging purposes only */ + printf("pc = %08x, npc = %08x\n", sregs->pc, sregs->npc); + if (sregs->pc == 0 || sregs->npc == 0) + printf ("bogus pc or npc\n"); +#endif + mexc = memory_read(sregs->asi, sregs->pc, &sregs->inst, + 2, &sregs->hold); if (sregs->annul) { sregs->annul = 0; sregs->icnt = 1; @@ -100,22 +113,11 @@ run_sim(sregs, go, icount, dis) if (mexc) { sregs->trap = I_ACC_EXC; } else { - if (sregs->histlen) { - sregs->histbuf[sregs->histind].addr = sregs->pc; - sregs->histbuf[sregs->histind].time = ebase.simtime; - sregs->histind++; - if (sregs->histind >= sregs->histlen) - sregs->histind = 0; - } - if (dis) { - printf(" %8d ", ebase.simtime); - dis_mem(sregs->pc, 1, &dinfo); - } if ((sis_gdb_break) && (sregs->inst == 0x91d02001)) { if (sis_verbose) (*sim_callback->printf_filtered) (sim_callback, "SW BP hit at %x\n", sregs->pc); - sim_halt(); + sim_halt(); restore_stdio(); clearerr(stdin); return (BPT_HIT); @@ -130,7 +132,7 @@ run_sim(sregs, go, icount, dis) } advance_time(sregs); if (ctrl_c) { - go = icount = 0; + icount = 0; } } sim_halt(); @@ -176,15 +178,11 @@ sim_open (kind, callback, abfd, argv) { int argc = 0; - int cont = 1; int stat = 1; - int grdl = 0; - int freq = 15; + int freq = 0; sim_callback = callback; - (*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version); - (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n"); while (argv[argc]) argc++; while (stat < argc) { @@ -193,22 +191,26 @@ sim_open (kind, callback, abfd, argv) sis_verbose = 1; } else if (strcmp(argv[stat], "-nfp") == 0) { - (*sim_callback->printf_filtered) (sim_callback, "no FPU\n"); nfp = 1; } else if (strcmp(argv[stat], "-ift") == 0) { ift = 1; } else if (strcmp(argv[stat], "-sparclite") == 0) { - (*sim_callback->printf_filtered) (sim_callback, "simulating Sparclite\n"); sparclite = 1; } else + if (strcmp(argv[stat], "-sparclite-board") == 0) { + sparclite_board = 1; + } else if (strcmp(argv[stat], "-wrp") == 0) { wrp = 1; } else if (strcmp(argv[stat], "-rom8") == 0) { rom8 = 1; } else + if (strcmp(argv[stat], "-uben") == 0) { + uben = 1; + } else if (strcmp(argv[stat], "-uart1") == 0) { if ((stat + 1) < argc) strcpy(uart_dev1, argv[++stat]); @@ -218,23 +220,39 @@ sim_open (kind, callback, abfd, argv) strcpy(uart_dev2, argv[++stat]); } else if (strcmp(argv[stat], "-nogdb") == 0) { - (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n"); sis_gdb_break = 0; } else - if (strcmp(argv[stat], "-freq") == 0) + if (strcmp(argv[stat], "-freq") == 0) { if ((stat + 1) < argc) { freq = VAL(argv[++stat]); - (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq); } + } else { + (*sim_callback->printf_filtered) (sim_callback, + "unknown option %s\n", + argv[stat]); + } } else bfd_load(argv[stat]); stat++; } - sregs.freq = freq; + + if (sis_verbose) { + (*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version); + (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n"); + if (nfp) + (*sim_callback->printf_filtered) (sim_callback, "no FPU\n"); + if (sparclite) + (*sim_callback->printf_filtered) (sim_callback, "simulating Sparclite\n"); + if (sis_gdb_break == 0) + (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n"); + if (freq) + (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq); + } + + sregs.freq = freq ? freq : 15; termsave = fcntl(0, F_GETFL, 0); INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf); dinfo.endian = BFD_ENDIAN_BIG; - init_signals(); reset_all(); ebase.simtime = 0; init_sim(); @@ -256,9 +274,6 @@ sim_close(sd, quitting) }; -/* For communication from sim_load to sim_create_inferior. */ -static bfd_vma start_address; - SIM_RC sim_load(sd, prog, abfd, from_tty) SIM_DESC sd; @@ -266,16 +281,21 @@ sim_load(sd, prog, abfd, from_tty) bfd *abfd; int from_tty; { - start_address = bfd_load (prog); - return (0); + bfd_load (prog); + return SIM_RC_OK; } SIM_RC -sim_create_inferior(sd, argv, env) +sim_create_inferior(sd, abfd, argv, env) SIM_DESC sd; + struct _bfd *abfd; char **argv; char **env; { + bfd_vma start_address = 0; + if (abfd != NULL) + start_address = bfd_get_start_address (abfd); + ebase.simtime = 0; reset_all(); reset_stat(&sregs); @@ -284,25 +304,29 @@ sim_create_inferior(sd, argv, env) return SIM_RC_OK; } -void -sim_store_register(sd, regno, value) +int +sim_store_register(sd, regno, value, length) SIM_DESC sd; int regno; unsigned char *value; + int length; { /* FIXME: Review the computation of regval. */ int regval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]; set_regi(&sregs, regno, regval); + return -1; } -void -sim_fetch_register(sd, regno, buf) +int +sim_fetch_register(sd, regno, buf, length) SIM_DESC sd; int regno; unsigned char *buf; + int length; { get_regi(&sregs, regno, buf); + return -1; } int @@ -375,8 +399,6 @@ sim_stop_reason(sd, reason, sigrc) handlers. */ -#define PSR_CWP 0x7 - static void flush_windows () { @@ -418,7 +440,7 @@ flush_windows () void sim_resume(SIM_DESC sd, int step, int siggnal) { - simstat = run_sim(&sregs, 1, 0, 0); + simstat = run_sim(&sregs, -1, 0); if (sis_gdb_break) flush_windows (); } |