* 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.
This commit is contained in:
parent
e3ace30a61
commit
7d146b765c
@ -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.
|
||||
|
||||
413
sim/erc32/func.c
413
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";
|
||||
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 IUREV0
|
||||
int iurev0 = 0;
|
||||
#endif
|
||||
#ifdef MECREV0
|
||||
int mecrev0 = 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_stop();
|
||||
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_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");
|
||||
if (sis_verbose)
|
||||
printf("\n");
|
||||
|
||||
/*
|
||||
* entry = bfd_get_start_address (pbfd);
|
||||
*
|
||||
* printf ("[Starting %s at 0x%lx]\n", fname, entry);
|
||||
*/
|
||||
|
||||
return (1);
|
||||
return(bfd_get_start_address (pbfd));
|
||||
}
|
||||
|
||||
void
|
||||
sim_set_callbacks (ptr)
|
||||
struct host_callback_struct *ptr;
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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 ();
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user