Rewrite sim_monitor (implements read, write, open, et.al. system

calls) and sim_open so that they uses the virtual memory data transfer
functions sim_read & sim_write.  This eliminates all code (other than
in load_memory & store_memory) that makes assumptions about the
implementation of the underlying memory model.
This commit is contained in:
Andrew Cagney 1997-11-05 00:08:14 +00:00
parent a26ecda4ec
commit 525d929e49
3 changed files with 250 additions and 324 deletions

View file

@ -1,3 +1,20 @@
Wed Nov 5 09:35:59 1997 Andrew Cagney <cagney@b1.cygnus.com>
* interp.c (fetch_str): New function.
(sim_monitor): Rewrite using sim_read & sim_write.
(sim_open): Check magic number.
(sim_open): Write monitor vectors into memory using sim_write.
(MONITOR_BASE, MONITOR_SIZE, MEM_SIZE): Define.
(sim_read, sim_write): Simplify - transfer data one byte at a
time.
(load_memory, store_memory): Clarify meaning of parameter RAW.
* sim-main.h (isHOST): Defete definition.
(isTARGET): Mark as depreciated.
(address_translation): Delete parameter HOST.
* interp.c (address_translation): Delete parameter HOST.
start-sanitize-tx49
Wed Oct 29 14:21:32 1997 Gavin Koch <gavin@cygnus.com>

View file

@ -146,11 +146,14 @@ static void mips_size PARAMS((SIM_DESC sd, int n));
#define K0SIZE (0x20000000)
#define K1BASE (0xA0000000)
#define K1SIZE (0x20000000)
#define MONITOR_BASE (0xBFC00000)
#define MONITOR_SIZE (1 << 11)
#define MEM_SIZE (2 << 20)
/* Simple run-time monitor support */
static unsigned char *monitor = NULL;
static ut_reg monitor_base = 0xBFC00000;
static unsigned monitor_size = (1 << 11); /* power-of-2 */
static ut_reg monitor_base = MONITOR_BASE;
static unsigned monitor_size = MONITOR_SIZE; /* power-of-2 */
static char *logfile = NULL; /* logging disabled by default */
static FILE *logfh = NULL;
@ -283,6 +286,8 @@ sim_open (kind, cb, abfd, argv)
SIM_DESC sd = sim_state_alloc (kind, cb);
sim_cpu *cpu = STATE_CPU (sd, 0);
SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
/* FIXME: watchpoints code shouldn't need this */
STATE_WATCHPOINTS (sd)->pc = &(PC);
STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
@ -290,7 +295,7 @@ sim_open (kind, cb, abfd, argv)
/* memory defaults (unless sim_size was here first) */
if (STATE_MEM_SIZE (sd) == 0)
STATE_MEM_SIZE (sd) = (2 << 20);
STATE_MEM_SIZE (sd) = MEM_SIZE;
STATE_MEM_BASE (sd) = K1BASE;
STATE = 0;
@ -440,15 +445,13 @@ sim_open (kind, cb, abfd, argv)
not using machine instructions. To avoid clashing with use of
the MIPS TRAP system, we place our own (simulator specific)
"undefined" instructions into the relevant vector slots. */
for (loop = 0; (loop < monitor_size); loop += 4) {
address_word vaddr = (monitor_base + loop);
address_word paddr;
int cca;
if (AddressTranslation(vaddr, isDATA, isSTORE, &paddr, &cca, isTARGET, isRAW))
StoreMemory(cca, AccessLength_WORD,
(RSVD_INSTRUCTION | (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK) << RSVD_INSTRUCTION_ARG_SHIFT)),
0, paddr, vaddr, isRAW);
}
for (loop = 0; (loop < MONITOR_SIZE); loop += 4)
{
address_word vaddr = (MONITOR_BASE + loop);
unsigned32 insn = (RSVD_INSTRUCTION | (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK) << RSVD_INSTRUCTION_ARG_SHIFT));
H2T (insn);
sim_write (sd, vaddr, (char *)&insn, sizeof (insn));
}
/* The PMON monitor uses the same address space, but rather than
branching into it the address of a routine is loaded. We can
cheat for the moment, and direct the PMON routine to IDT style
@ -457,53 +460,40 @@ sim_open (kind, cb, abfd, argv)
entry points.*/
for (loop = 0; (loop < 24); loop++)
{
address_word vaddr = (monitor_base + 0x500 + (loop * 4));
address_word paddr;
int cca;
unsigned int value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
address_word vaddr = (MONITOR_BASE + 0x500 + (loop * 4));
unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
switch (loop)
{
case 0: /* read */
value = 7;
break;
case 1: /* write */
value = 8;
break;
case 2: /* open */
value = 6;
break;
case 3: /* close */
value = 10;
break;
case 5: /* printf */
value = ((0x500 - 16) / 8); /* not an IDT reason code */
break;
case 8: /* cliexit */
value = 17;
break;
case 11: /* flush_cache */
value = 28;
break;
}
/* FIXME - should monitor_base be SIM_ADDR?? */
value = ((unsigned int)monitor_base + (value * 8));
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW))
StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
else
sim_io_error(sd,"Failed to write to monitor space 0x%s",pr_addr(vaddr));
/* FIXME - should monitor_base be SIM_ADDR?? */
value = ((unsigned int)MONITOR_BASE + (value * 8));
H2T (value);
sim_write (sd, vaddr, (char *)&value, sizeof (value));
/* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
vaddr -= 0x300;
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW))
StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
else
sim_io_error(sd,"Failed to write to monitor space 0x%s",pr_addr(vaddr));
sim_write (sd, vaddr, (char *)&value, sizeof (value));
}
}
@ -565,108 +555,27 @@ sim_write (sd,addr,buffer,size)
unsigned char *buffer;
int size;
{
int index = size;
uword64 vaddr = (uword64)addr;
int index;
/* Return the number of bytes written, or zero if error. */
#ifdef DEBUG
sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
#endif
/* We provide raw read and write routines, since we do not want to
count the GDB memory accesses in our statistics gathering. */
/* We use raw read and write routines, since we do not want to count
the GDB memory accesses in our statistics gathering. */
/* There is a lot of code duplication in the individual blocks
below, but the variables are declared locally to a block to give
the optimiser the best chance of improving the code. We have to
perform slow byte reads from the host memory, to ensure that we
get the data into the correct endianness for the (simulated)
target memory world. */
for (index = 0; index < size; index++)
{
address_word vaddr = (address_word)addr + index;
address_word paddr;
int cca;
if (!AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &cca, isTARGET, isRAW))
break;
StoreMemory (cca, AccessLength_BYTE, buffer[index], 0, paddr, vaddr, isRAW);
}
/* Mask count to get odd byte, odd halfword, and odd word out of the
way. We can then perform doubleword transfers to and from the
simulator memory for optimum performance. */
if (index && (index & 1)) {
address_word paddr;
int cca;
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
uword64 value = ((uword64)(*buffer++));
StoreMemory(cca,AccessLength_BYTE,value,0,paddr,vaddr,isRAW);
}
vaddr++;
index &= ~1; /* logical operations usually quicker than arithmetic on RISC systems */
}
if (index && (index & 2)) {
address_word paddr;
int cca;
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
uword64 value;
/* We need to perform the following magic to ensure that that
bytes are written into same byte positions in the target memory
world, regardless of the endianness of the host. */
if (BigEndianMem) {
value = ((uword64)(*buffer++) << 8);
value |= ((uword64)(*buffer++) << 0);
} else {
value = ((uword64)(*buffer++) << 0);
value |= ((uword64)(*buffer++) << 8);
}
StoreMemory(cca,AccessLength_HALFWORD,value,0,paddr,vaddr,isRAW);
}
vaddr += 2;
index &= ~2;
}
if (index && (index & 4)) {
address_word paddr;
int cca;
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
uword64 value;
if (BigEndianMem) {
value = ((uword64)(*buffer++) << 24);
value |= ((uword64)(*buffer++) << 16);
value |= ((uword64)(*buffer++) << 8);
value |= ((uword64)(*buffer++) << 0);
} else {
value = ((uword64)(*buffer++) << 0);
value |= ((uword64)(*buffer++) << 8);
value |= ((uword64)(*buffer++) << 16);
value |= ((uword64)(*buffer++) << 24);
}
StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
}
vaddr += 4;
index &= ~4;
}
for (;index; index -= 8) {
address_word paddr;
int cca;
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
uword64 value;
if (BigEndianMem) {
value = ((uword64)(*buffer++) << 56);
value |= ((uword64)(*buffer++) << 48);
value |= ((uword64)(*buffer++) << 40);
value |= ((uword64)(*buffer++) << 32);
value |= ((uword64)(*buffer++) << 24);
value |= ((uword64)(*buffer++) << 16);
value |= ((uword64)(*buffer++) << 8);
value |= ((uword64)(*buffer++) << 0);
} else {
value = ((uword64)(*buffer++) << 0);
value |= ((uword64)(*buffer++) << 8);
value |= ((uword64)(*buffer++) << 16);
value |= ((uword64)(*buffer++) << 24);
value |= ((uword64)(*buffer++) << 32);
value |= ((uword64)(*buffer++) << 40);
value |= ((uword64)(*buffer++) << 48);
value |= ((uword64)(*buffer++) << 56);
}
StoreMemory(cca,AccessLength_DOUBLEWORD,value,0,paddr,vaddr,isRAW);
}
vaddr += 8;
}
return(size);
return(index);
}
int
@ -683,22 +592,17 @@ sim_read (sd,addr,buffer,size)
sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
#endif /* DEBUG */
/* TODO: Perform same optimisation as the sim_write() code
above. NOTE: This will require a bit more work since we will need
to ensure that the source physical address is doubleword aligned
before, and then deal with trailing bytes. */
for (index = 0; (index < size); index++) {
address_word vaddr;
address_word paddr;
unsigned64 value;
int cca;
vaddr = (address_word)addr + index;
if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&cca,isTARGET,isRAW)) {
LoadMemory(&value,NULL,cca,AccessLength_BYTE,paddr,vaddr,isDATA,isRAW);
for (index = 0; (index < size); index++)
{
address_word vaddr = (address_word)addr + index;
address_word paddr;
unsigned64 value;
int cca;
if (!AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &cca, isTARGET, isRAW))
break;
LoadMemory (&value, NULL, cca, AccessLength_BYTE, paddr, vaddr, isDATA, isRAW);
buffer[index] = (unsigned char)(value&0xFF);
} else
break;
}
}
return(index);
}
@ -951,6 +855,22 @@ mips_size(sd, newsize)
/*-- Private simulator support interface ------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Read a null terminated string from memory, return in a buffer */
static char *
fetch_str (sd, addr)
SIM_DESC sd;
address_word addr;
{
char *buf;
int nr = 0;
char null;
while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0)
nr++;
buf = NZALLOC (char, nr + 1);
sim_read (sd, addr, buf, nr);
return buf;
}
/* Simple monitor interface (currently setup for the IDT and PMON monitors) */
static void
sim_monitor(sd,reason)
@ -969,68 +889,72 @@ sim_monitor(sd,reason)
/* The following callback functions are available, however the
monitor we are simulating does not make use of them: get_errno,
isatty, lseek, rename, system, time and unlink */
switch (reason) {
switch (reason)
{
case 6: /* int open(char *path,int flags) */
{
address_word paddr;
int cca;
if (AddressTranslation(A0,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
V0 = sim_io_open(sd,(char *)((int)paddr),(int)A1);
else
sim_io_error(sd,"Attempt to pass pointer that does not reference simulated memory");
char *path = fetch_str (sd, A0);
V0 = sim_io_open (sd, path, (int)A1);
zfree (path);
break;
}
break;
case 7: /* int read(int file,char *ptr,int len) */
{
address_word paddr;
int cca;
if (AddressTranslation(A1,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
V0 = sim_io_read(sd,(int)A0,(char *)((int)paddr),(int)A2);
else
sim_io_error(sd,"Attempt to pass pointer that does not reference simulated memory");
int fd = A0;
int nr = A2;
char *buf = zalloc (nr);
V0 = sim_io_read (sd, fd, buf, nr);
sim_write (sd, A1, buf, nr);
zfree (buf);
}
break;
case 8: /* int write(int file,char *ptr,int len) */
{
address_word paddr;
int cca;
if (AddressTranslation(A1,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
V0 = sim_io_write(sd,(int)A0,(const char *)((int)paddr),(int)A2);
else
sim_io_error(sd,"Attempt to pass pointer that does not reference simulated memory");
int fd = A0;
int nr = A2;
char *buf = zalloc (nr);
sim_read (sd, A1, buf, nr);
V0 = sim_io_write (sd, fd, buf, nr);
zfree (buf);
break;
}
break;
case 10: /* int close(int file) */
V0 = sim_io_close(sd,(int)A0);
break;
{
V0 = sim_io_close (sd, (int)A0);
break;
}
case 11: /* char inbyte(void) */
{
char tmp;
if (sim_io_read_stdin(sd,&tmp,sizeof(char)) != sizeof(char)) {
sim_io_error(sd,"Invalid return from character read");
V0 = (ut_reg)-1;
}
if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
{
sim_io_error(sd,"Invalid return from character read");
V0 = (ut_reg)-1;
}
else
V0 = (ut_reg)tmp;
V0 = (ut_reg)tmp;
break;
}
break;
case 12: /* void outbyte(char chr) : write a byte to "stdout" */
{
char tmp = (char)(A0 & 0xFF);
sim_io_write_stdout(sd,&tmp,sizeof(char));
sim_io_write_stdout (sd, &tmp, sizeof(char));
break;
}
break;
case 17: /* void _exit() */
sim_io_eprintf(sd,"sim_monitor(17): _exit(int reason) to be coded\n");
sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA, sim_exited,
(unsigned int)(A0 & 0xFFFFFFFF));
break;
{
sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n");
sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA, sim_exited,
(unsigned int)(A0 & 0xFFFFFFFF));
break;
}
case 28 : /* PMON flush_cache */
break;
@ -1041,40 +965,13 @@ sim_monitor(sd,reason)
/* [A0 + 4] = instruction cache size */
/* [A0 + 8] = data cache size */
{
address_word vaddr = A0;
address_word paddr, value;
int cca;
int failed = 0;
/* NOTE: We use RAW memory writes here, but since we are not
gathering statistics for the monitor calls we are simulating,
it is not an issue. */
/* Memory size */
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isREAL)) {
value = (uword64)STATE_MEM_SIZE (sd);
StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
/* We re-do the address translations, in-case the block
overlaps a memory boundary: */
value = 0;
vaddr += (AccessLength_WORD + 1);
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isREAL)) {
StoreMemory(cca,AccessLength_WORD,0,value,paddr,vaddr,isRAW);
vaddr += (AccessLength_WORD + 1);
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isREAL))
StoreMemory(cca,AccessLength_WORD,value,0,paddr,vaddr,isRAW);
else
failed = -1;
} else
failed = -1;
} else
failed = -1;
if (failed)
sim_io_error(sd,"Invalid pointer passed into monitor call");
address_word value = MEM_SIZE /* FIXME STATE_MEM_SIZE (sd) */;
H2T (value);
sim_write (sd, A0, (char *)&value, sizeof (value));
sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n");
break;
}
break;
case 158 : /* PMON printf */
/* in: A0 = pointer to format string */
/* A1 = optional argument 1 */
@ -1083,108 +980,116 @@ sim_monitor(sd,reason)
/* out: void */
/* The following is based on the PMON printf source */
{
address_word paddr;
int cca;
address_word s = A0;
char c;
signed_word *ap = &A1; /* 1st argument */
/* This isn't the quickest way, since we call the host print
routine for every character almost. But it does avoid
having to allocate and manage a temporary string buffer. */
if (AddressTranslation(A0,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL)) {
char *s = (char *)((int)paddr);
signed_word *ap = &A1; /* 1st argument */
/* TODO: Include check that we only use three arguments (A1, A2 and A3) */
for (; *s;) {
if (*s == '%') {
char tmp[40];
enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
int width = 0, trunc = 0, haddot = 0, longlong = 0;
s++;
for (; *s; s++) {
if (strchr ("dobxXulscefg%", *s))
break;
else if (*s == '-')
fmt = FMT_LJUST;
else if (*s == '0')
fmt = FMT_RJUST0;
else if (*s == '~')
fmt = FMT_CENTER;
else if (*s == '*') {
if (haddot)
trunc = (int)*ap++;
else
width = (int)*ap++;
} else if (*s >= '1' && *s <= '9') {
char *t;
unsigned int n;
for (t = s; isdigit (*s); s++);
strncpy (tmp, t, s - t);
tmp[s - t] = '\0';
n = (unsigned int)strtol(tmp,NULL,10);
if (haddot)
trunc = n;
else
width = n;
s--;
} else if (*s == '.')
haddot = 1;
}
if (*s == '%') {
sim_io_printf(sd,"%%");
} else if (*s == 's') {
if ((int)*ap != 0) {
if (AddressTranslation(*ap++,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL)) {
char *p = (char *)((int)paddr);;
sim_io_printf(sd,p);
} else {
ap++;
sim_io_error(sd,"Attempt to pass pointer that does not reference simulated memory");
}
}
else
sim_io_printf(sd,"(null)");
} else if (*s == 'c') {
int n = (int)*ap++;
sim_io_printf(sd,"%c",n);
} else {
if (*s == 'l') {
if (*++s == 'l') {
longlong = 1;
++s;
}
}
if (strchr ("dobxXu", *s)) {
word64 lv = (word64) *ap++;
if (*s == 'b')
sim_io_printf(sd,"<binary not supported>");
else {
sprintf(tmp,"%%%s%c",longlong ? "ll" : "",*s);
if (longlong)
sim_io_printf(sd,tmp,lv);
else
sim_io_printf(sd,tmp,(int)lv);
}
} else if (strchr ("eEfgG", *s)) {
#ifdef _MSC_VER /* MSVC version 2.x can't convert from uword64 directly */
double dbl = (double)((word64)*ap++);
#else
double dbl = (double)*ap++;
#endif
sprintf(tmp,"%%%d.%d%c",width,trunc,*s);
sim_io_printf(sd,tmp,dbl);
trunc = 0;
}
}
s++;
} else
sim_io_printf(sd,"%c",*s++);
}
} else
sim_io_error(sd,"Attempt to pass pointer that does not reference simulated memory");
/* TODO: Include check that we only use three arguments (A1,
A2 and A3) */
while (sim_read (sd, s++, &c, 1) && c != '\0')
{
if (c == '%')
{
char tmp[40];
enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
int width = 0, trunc = 0, haddot = 0, longlong = 0;
while (sim_read (sd, s++, &c, 1) && c != '\0')
{
if (strchr ("dobxXulscefg%", s))
break;
else if (c == '-')
fmt = FMT_LJUST;
else if (c == '0')
fmt = FMT_RJUST0;
else if (c == '~')
fmt = FMT_CENTER;
else if (c == '*')
{
if (haddot)
trunc = (int)*ap++;
else
width = (int)*ap++;
}
else if (c >= '1' && c <= '9')
{
address_word t = s;
unsigned int n;
while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c))
tmp[s - t] = c;
tmp[s - t] = '\0';
n = (unsigned int)strtol(tmp,NULL,10);
if (haddot)
trunc = n;
else
width = n;
s--;
}
else if (c == '.')
haddot = 1;
}
switch (c)
{
case '%':
sim_io_printf (sd, "%%");
break;
case 's':
if ((int)*ap != 0)
{
address_word p = *ap++;
char ch;
while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0')
sim_io_printf(sd, "%c", ch);
}
else
sim_io_printf(sd,"(null)");
break;
case 'c':
sim_io_printf (sd, "%c", (int)*ap++);
break;
default:
if (c == 'l')
{
sim_read (sd, s++, &c, 1);
if (c == 'l')
{
longlong = 1;
sim_read (sd, s++, &c, 1);
}
}
if (strchr ("dobxXu", c))
{
word64 lv = (word64) *ap++;
if (c == 'b')
sim_io_printf(sd,"<binary not supported>");
else
{
sprintf (tmp, "%%%s%c", longlong ? "ll" : "", c);
if (longlong)
sim_io_printf(sd, tmp, lv);
else
sim_io_printf(sd, tmp, (int)lv);
}
}
else if (strchr ("eEfgG", c))
{
double dbl = *(double*)(ap++);
sprintf (tmp, "%%%d.%d%c", width, trunc, c);
sim_io_printf (sd, tmp, dbl);
trunc = 0;
}
}
}
else
sim_io_printf(sd, "%c", c);
}
break;
}
break;
default:
sim_io_eprintf(sd,"TODO: sim_monitor(%d) : PC = 0x%s\n",reason,pr_addr(IPC));
sim_io_eprintf(sd,"(Arguments : A0 = 0x%s : A1 = 0x%s : A2 = 0x%s : A3 = 0x%s)\n",pr_addr(A0),pr_addr(A1),pr_addr(A2),pr_addr(A3));
sim_io_error (sd, "TODO: sim_monitor(%d) : PC = 0x%s\n",
reason, pr_addr(IPC));
break;
}
return;
@ -1517,14 +1422,13 @@ ColdReset (sd)
function raises an exception and does not return. */
int
address_translation(sd,vAddr,IorD,LorS,pAddr,CCA,host,raw)
address_translation(sd,vAddr,IorD,LorS,pAddr,CCA,raw)
SIM_DESC sd;
address_word vAddr;
int IorD;
int LorS;
address_word *pAddr;
int *CCA;
int host;
int raw;
{
int res = -1; /* TRUE : Assume good return */
@ -1558,11 +1462,9 @@ address_translation(sd,vAddr,IorD,LorS,pAddr,CCA,host,raw)
LoadMemory and StoreMemory functions. They should be merged into
a single function (that can be in-lined if required). */
if ((vAddr >= STATE_MEM_BASE (sd)) && (vAddr < (STATE_MEM_BASE (sd) + STATE_MEM_SIZE (sd)))) {
if (host)
*pAddr = (int)&STATE_MEMORY (sd)[((unsigned int)(vAddr - STATE_MEM_BASE (sd)) & (STATE_MEM_SIZE (sd) - 1))];
/* do nothing */
} else if ((vAddr >= monitor_base) && (vAddr < (monitor_base + monitor_size))) {
if (host)
*pAddr = (int)&monitor[((unsigned int)(vAddr - monitor_base) & (monitor_size - 1))];
/* do nothing */
} else {
#ifdef DEBUG
sim_io_eprintf(sd,"Failed: AddressTranslation(0x%s,%s,%s,...) IPC = 0x%s\n",pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(LorS ? "isSTORE" : "isLOAD"),pr_addr(IPC));
@ -1661,10 +1563,11 @@ load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw)
/* Decide which physical memory locations are being dealt with. At
this point we should be able to split the pAddr bits into the
relevant address map being simulated. If the "raw" variable is
set, the memory read being performed should *NOT* update any I/O
state or affect the CPU state. This also includes avoiding
affecting statistics gathering. */
relevant address map being simulated. */
/* If the "raw" variable is set, the memory read being performed
should *NOT* update any I/O state or affect the CPU state
(including statistics gathering). The parameter MEMVALP is least
significant byte justified. */
/* If instruction fetch then we need to check that the two lo-order
bits are zero, otherwise raise a InstructionFetch exception: */
@ -1787,10 +1690,8 @@ load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw)
(int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value));
#endif /* DEBUG */
/* TODO: We could try and avoid the shifts when dealing with raw
memory accesses. This would mean updating the LoadMemory and
StoreMemory routines to avoid shifting the data before
returning or using it. */
/* When dealing with raw memory accesses there is no need to
deal with shifts. */
if (AccessLength <= AccessLength_DOUBLEWORD) {
if (!raw) { /* do nothing for raw accessess */
if (BigEndianMem)
@ -1807,8 +1708,8 @@ load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw)
}
}
*memvalp = value;
if (memval1p) *memval1p = value1;
*memvalp = value;
if (memval1p) *memval1p = value1;
}
@ -1858,6 +1759,11 @@ store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw)
we could merge a lot of this code with the LoadMemory
routine. However, this would slow the simulator down with
run-time conditionals. */
/* If the "raw" variable is set, the memory read being performed
should *NOT* update any I/O state or affect the CPU state
(including statistics gathering). The parameter MEMELEM is least
significant byte justified. */
{
unsigned int index = 0;
unsigned char *mem = NULL;
@ -1882,6 +1788,8 @@ store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw)
if (AccessLength <= AccessLength_DOUBLEWORD) {
if (BigEndianMem) {
if (raw)
/* need to shift raw (least significant byte aligned) data
into correct byte slots */
shift = ((7 - AccessLength) * 8);
else /* real memory access */
shift = ((pAddr & LOADDRMASK) * 8);

View file

@ -672,8 +672,9 @@ void decode_coproc PARAMS ((SIM_DESC sd,unsigned int instruction));
#define isSTORE (1 == 1) /* TRUE */
#define isREAL (1 == 0) /* FALSE */
#define isRAW (1 == 1) /* TRUE */
/* The parameter HOST (isTARGET / isHOST) is ignored */
#define isTARGET (1 == 0) /* FALSE */
#define isHOST (1 == 1) /* TRUE */
/* #define isHOST (1 == 1) TRUE */
/* The "AccessLength" specifications for Loads and Stores. NOTE: This
is the number of bytes minus 1. */
@ -687,9 +688,9 @@ void decode_coproc PARAMS ((SIM_DESC sd,unsigned int instruction));
#define AccessLength_DOUBLEWORD (7)
#define AccessLength_QUADWORD (15)
int address_translation PARAMS ((SIM_DESC sd, address_word vAddr, int IorD, int LorS, address_word *pAddr, int *CCA, int host, int raw));
int address_translation PARAMS ((SIM_DESC sd, address_word vAddr, int IorD, int LorS, address_word *pAddr, int *CCA, int raw));
#define AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw) \
address_translation(sd, vAddr,IorD,LorS,pAddr,CCA,host,raw)
address_translation(sd, vAddr,IorD,LorS,pAddr,CCA,raw)
void load_memory PARAMS ((SIM_DESC sd, uword64* memvalp, uword64* memval1p, int CCA, int AccessLength, address_word pAddr, address_word vAddr, int IorD, int raw));
#define LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) \