From 525d929e4947c625f79ad3c2e02272f8db2c9f8c Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Wed, 5 Nov 1997 00:08:14 +0000 Subject: [PATCH] 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. --- sim/mips/ChangeLog | 17 ++ sim/mips/interp.c | 550 ++++++++++++++++++-------------------------- sim/mips/sim-main.h | 7 +- 3 files changed, 250 insertions(+), 324 deletions(-) diff --git a/sim/mips/ChangeLog b/sim/mips/ChangeLog index 0244eb2b4e..4aa5146cf9 100644 --- a/sim/mips/ChangeLog +++ b/sim/mips/ChangeLog @@ -1,3 +1,20 @@ +Wed Nov 5 09:35:59 1997 Andrew Cagney + + * 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 diff --git a/sim/mips/interp.c b/sim/mips/interp.c index 835dbdb0ed..f1b9f48175 100644 --- a/sim/mips/interp.c +++ b/sim/mips/interp.c @@ -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,""); - 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,""); + 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); diff --git a/sim/mips/sim-main.h b/sim/mips/sim-main.h index 7809714a08..a01f229e0e 100644 --- a/sim/mips/sim-main.h +++ b/sim/mips/sim-main.h @@ -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) \