/[gxemul]/trunk/src/memory_rw.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/memory_rw.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 23 by dpavlin, Mon Oct 8 16:19:37 2007 UTC revision 24 by dpavlin, Mon Oct 8 16:19:56 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: memory_rw.c,v 1.82 2005/12/31 15:48:32 debug Exp $   *  $Id: memory_rw.c,v 1.87 2006/06/22 11:43:03 debug Exp $
29   *   *
30   *  Generic memory_rw(), with special hacks for specific CPU families.   *  Generic memory_rw(), with special hacks for specific CPU families.
31   *   *
# Line 53  Line 53 
53   *  If the address indicates access to a memory mapped device, that device'   *  If the address indicates access to a memory mapped device, that device'
54   *  read/write access function is called.   *  read/write access function is called.
55   *   *
  *  If instruction latency/delay support is enabled, then  
  *  cpu->instruction_delay is increased by the number of instruction to  
  *  delay execution.  
  *  
56   *  This function should not be called with cpu == NULL.   *  This function should not be called with cpu == NULL.
57   *   *
58   *  Returns one of the following:   *  Returns one of the following:
# Line 80  int MEMORY_RW(struct cpu *cpu, struct me Line 76  int MEMORY_RW(struct cpu *cpu, struct me
76          uint64_t paddr;          uint64_t paddr;
77          int cache, no_exceptions, offset;          int cache, no_exceptions, offset;
78          unsigned char *memblock;          unsigned char *memblock;
 #ifdef MEM_MIPS  
         int bintrans_cached = cpu->machine->bintrans_enable;  
 #endif  
79          int dyntrans_device_danger = 0;          int dyntrans_device_danger = 0;
80    
81          no_exceptions = misc_flags & NO_EXCEPTIONS;          no_exceptions = misc_flags & NO_EXCEPTIONS;
# Line 150  int MEMORY_RW(struct cpu *cpu, struct me Line 143  int MEMORY_RW(struct cpu *cpu, struct me
143          }          }
144  #endif  /*  X86  */  #endif  /*  X86  */
145    
 #ifdef MEM_MIPS  
         if (bintrans_cached) {  
                 if (cache == CACHE_INSTRUCTION) {  
                         cpu->cd.mips.pc_bintrans_host_4kpage = NULL;  
                         cpu->cd.mips.pc_bintrans_paddr_valid = 0;  
                 }  
         }  
 #endif  /*  MEM_MIPS  */  
146    
147  #ifdef MEM_USERLAND  #ifdef MEM_USERLAND
148  #ifdef MEM_ALPHA  #ifdef MEM_ALPHA
# Line 165  int MEMORY_RW(struct cpu *cpu, struct me Line 150  int MEMORY_RW(struct cpu *cpu, struct me
150  #else  #else
151          paddr = vaddr & 0x7fffffff;          paddr = vaddr & 0x7fffffff;
152  #endif  #endif
153          goto have_paddr;  #else   /*  !MEM_USERLAND  */
 #endif  
   
 #ifndef MEM_USERLAND  
 #ifdef MEM_MIPS  
         /*  
          *  For instruction fetch, are we on the same page as the last  
          *  instruction we fetched?  
          *  
          *  NOTE: There's no need to check this stuff here if this address  
          *  is known to be in host ram, as it's done at instruction fetch  
          *  time in cpu.c!  Only check if _host_4k_page == NULL.  
          */  
         if (cache == CACHE_INSTRUCTION &&  
             cpu->cd.mips.pc_last_host_4k_page == NULL &&  
             (vaddr & ~0xfff) == cpu->cd.mips.pc_last_virtual_page) {  
                 paddr = cpu->cd.mips.pc_last_physical_page | (vaddr & 0xfff);  
                 goto have_paddr;  
         }  
 #endif  /*  MEM_MIPS  */  
   
154          if (misc_flags & PHYSICAL || cpu->translate_address == NULL) {          if (misc_flags & PHYSICAL || cpu->translate_address == NULL) {
155                  paddr = vaddr;                  paddr = vaddr;
 #ifdef MEM_ALPHA  
                 /*  paddr &= 0x1fffffff;  For testalpha  */  
                 paddr &= 0x000003ffffffffffULL;  
 #endif  
156          } else {          } else {
157                  ok = cpu->translate_address(cpu, vaddr, &paddr,                  ok = cpu->translate_address(cpu, vaddr, &paddr,
158                      (writeflag? FLAG_WRITEFLAG : 0) +                      (writeflag? FLAG_WRITEFLAG : 0) +
# Line 226  int MEMORY_RW(struct cpu *cpu, struct me Line 187  int MEMORY_RW(struct cpu *cpu, struct me
187  #endif  #endif
188          }          }
189  #endif  #endif
190    #endif  /*  !MEM_USERLAND  */
 #ifdef MEM_MIPS  
         /*  
          *  If correct cache emulation is enabled, and we need to simluate  
          *  cache misses even from the instruction cache, we can't run directly  
          *  from a host page. :-/  
          */  
 #if defined(ENABLE_CACHE_EMULATION) && defined(ENABLE_INSTRUCTION_DELAYS)  
 #else  
         if (cache == CACHE_INSTRUCTION) {  
                 cpu->cd.mips.pc_last_virtual_page = vaddr & ~0xfff;  
                 cpu->cd.mips.pc_last_physical_page = paddr & ~0xfff;  
                 cpu->cd.mips.pc_last_host_4k_page = NULL;  
   
                 /*  _last_host_4k_page will be set to 1 further down,  
                     if the page is actually in host ram  */  
         }  
 #endif  
 #endif  /*  MEM_MIPS  */  
 #endif  /*  ifndef MEM_USERLAND  */  
   
   
 #if defined(MEM_MIPS) || defined(MEM_USERLAND)  
 have_paddr:  
 #endif  
   
   
 #ifdef MEM_MIPS  
         /*  TODO: How about bintrans vs cache emulation?  */  
         if (bintrans_cached) {  
                 if (cache == CACHE_INSTRUCTION) {  
                         cpu->cd.mips.pc_bintrans_paddr_valid = 1;  
                         cpu->cd.mips.pc_bintrans_paddr = paddr;  
                 }  
         }  
 #endif  /*  MEM_MIPS  */  
   
191    
192    
193  #ifndef MEM_USERLAND  #ifndef MEM_USERLAND
# Line 376  have_paddr: Line 301  have_paddr:
301                                              data, len, writeflag,                                              data, len, writeflag,
302                                              mem->dev_extra[i]);                                              mem->dev_extra[i]);
303    
 #ifdef ENABLE_INSTRUCTION_DELAYS  
304                                  if (res == 0)                                  if (res == 0)
305                                          res = -1;                                          res = -1;
306    
 #ifdef MEM_MIPS  
                                 cpu->cd.mips.instruction_delay +=  
                                     ( (abs(res) - 1) *  
                                      cpu->cd.mips.cpu_type.instrs_per_cycle );  
 #endif  
 #endif  
   
307  #ifndef MEM_X86  #ifndef MEM_X86
308                                  /*                                  /*
309                                   *  If accessing the memory mapped device                                   *  If accessing the memory mapped device
# Line 455  have_paddr: Line 372  have_paddr:
372  #endif /* MIPS */  #endif /* MIPS */
373                  {                  {
374                          if (paddr >= mem->physical_max) {                          if (paddr >= mem->physical_max) {
375                                    uint64_t offset, old_pc = cpu->pc;
376                                  char *symbol;                                  char *symbol;
                                 uint64_t offset;  
 #ifdef MEM_MIPS  
                                 uint64_t old_pc = cpu->cd.mips.pc_last;  
 #else  
                                 uint64_t old_pc = cpu->pc;  
 #endif  
377    
378                                  /*  This allows for example OS kernels to probe                                  /*  This allows for example OS kernels to probe
379                                      memory a few KBs past the end of memory,                                      memory a few KBs past the end of memory,
# Line 508  have_paddr: Line 420  have_paddr:
420                                          fatal(" <%s> ]\n",                                          fatal(" <%s> ]\n",
421                                              symbol? symbol : " no symbol ");                                              symbol? symbol : " no symbol ");
422                                  }                                  }
   
                                 if (cpu->machine->single_step_on_bad_addr) {  
                                         fatal("[ unimplemented access to "  
                                             "0x%llx, pc=0x",(long long)paddr);  
                                         if (cpu->is_32bit)  
                                                 fatal("%08x ]\n",  
                                                     (int)old_pc);  
                                         else  
                                                 fatal("%016llx ]\n",  
                                                     (long long)old_pc);  
                                         single_step = 1;  
                                 }  
423                          }                          }
424    
425                          if (writeflag == MEM_READ) {                          if (writeflag == MEM_READ) {
# Line 622  have_paddr: Line 522  have_paddr:
522                          *(uint8_t *)data = *(uint8_t *)(memblock + offset);                          *(uint8_t *)data = *(uint8_t *)(memblock + offset);
523                  else                  else
524                          memcpy(data, memblock + offset, len);                          memcpy(data, memblock + offset, len);
   
 #ifdef MEM_MIPS  
                 if (cache == CACHE_INSTRUCTION) {  
                         cpu->cd.mips.pc_last_host_4k_page = memblock  
                             + (offset & ~offset_mask);  
                         if (bintrans_cached) {  
                                 cpu->cd.mips.pc_bintrans_host_4kpage =  
                                     cpu->cd.mips.pc_last_host_4k_page;  
                         }  
                 }  
 #endif  /*  MIPS  */  
525          }          }
526    
527    

Legend:
Removed from v.23  
changed lines
  Added in v.24

  ViewVC Help
Powered by ViewVC 1.1.26