aboutsummaryrefslogtreecommitdiff
path: root/sim/erc32
diff options
context:
space:
mode:
authorMark Alexander <marka@cygnus>1998-06-02 22:43:46 +0000
committerMark Alexander <marka@cygnus>1998-06-02 22:43:46 +0000
commit7d146b765c7a676552e6a8b7bb8f28b37578a99f (patch)
tree64a4eb74ce8d71bdc38e482c61f23b02374529c1 /sim/erc32
parente3ace30a618618b40870e52e27b728044001619b (diff)
downloadfsf-binutils-gdb-7d146b765c7a676552e6a8b7bb8f28b37578a99f.zip
fsf-binutils-gdb-7d146b765c7a676552e6a8b7bb8f28b37578a99f.tar.gz
fsf-binutils-gdb-7d146b765c7a676552e6a8b7bb8f28b37578a99f.tar.bz2
* 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.
Diffstat (limited to 'sim/erc32')
-rw-r--r--sim/erc32/ChangeLog34
-rw-r--r--sim/erc32/func.c415
-rw-r--r--sim/erc32/interf.c114
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(&reg[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 ();
}