/[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 18 by dpavlin, Mon Oct 8 16:19:11 2007 UTC revision 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: memory_rw.c,v 1.75 2005/10/27 14:01:12 debug Exp $   *  $Id: memory_rw.c,v 1.80 2005/11/20 11:28:44 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 48  Line 48 
48   *                      a placeholder for data when reading from memory   *                      a placeholder for data when reading from memory
49   *      len             the length of the 'data' buffer   *      len             the length of the 'data' buffer
50   *      writeflag       set to MEM_READ or MEM_WRITE   *      writeflag       set to MEM_READ or MEM_WRITE
51   *      cache_flags     CACHE_{NONE,DATA,INSTRUCTION} | other flags   *      misc_flags      CACHE_{NONE,DATA,INSTRUCTION} | other flags
52   *   *
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.
# Line 66  Line 66 
66   *  (MEMORY_ACCESS_FAILED is 0.)   *  (MEMORY_ACCESS_FAILED is 0.)
67   */   */
68  int MEMORY_RW(struct cpu *cpu, struct memory *mem, uint64_t vaddr,  int MEMORY_RW(struct cpu *cpu, struct memory *mem, uint64_t vaddr,
69          unsigned char *data, size_t len, int writeflag, int cache_flags)          unsigned char *data, size_t len, int writeflag, int misc_flags)
70  {  {
71  #ifdef MEM_ALPHA  #ifdef MEM_ALPHA
72          const int offset_mask = 0x1fff;          const int offset_mask = 0x1fff;
# Line 85  int MEMORY_RW(struct cpu *cpu, struct me Line 85  int MEMORY_RW(struct cpu *cpu, struct me
85  #endif  #endif
86          int bintrans_device_danger = 0;          int bintrans_device_danger = 0;
87    
88          no_exceptions = cache_flags & NO_EXCEPTIONS;          no_exceptions = misc_flags & NO_EXCEPTIONS;
89          cache = cache_flags & CACHE_FLAGS_MASK;          cache = misc_flags & CACHE_FLAGS_MASK;
90    
91  #ifdef MEM_X86  #ifdef MEM_X86
92          /*  Real-mode wrap-around:  */          /*  Real-mode wrap-around:  */
93          if (REAL_MODE && !(cache_flags & PHYSICAL)) {          if (REAL_MODE && !(misc_flags & PHYSICAL)) {
94                  if ((vaddr & 0xffff) + len > 0x10000) {                  if ((vaddr & 0xffff) + len > 0x10000) {
95                          /*  Do one byte at a time:  */                          /*  Do one byte at a time:  */
96                          int res = 0, i;                          int res = 0, i;
97                          for (i=0; i<len; i++)                          for (i=0; i<len; i++)
98                                  res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,                                  res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,
99                                      writeflag, cache_flags);                                      writeflag, misc_flags);
100                          return res;                          return res;
101                  }                  }
102          }          }
103    
104          /*  Crossing a page boundary? Then do one byte at a time:  */          /*  Crossing a page boundary? Then do one byte at a time:  */
105          if ((vaddr & 0xfff) + len > 0x1000 && !(cache_flags & PHYSICAL)          if ((vaddr & 0xfff) + len > 0x1000 && !(misc_flags & PHYSICAL)
106              && cpu->cd.x86.cr[0] & X86_CR0_PG) {              && cpu->cd.x86.cr[0] & X86_CR0_PG) {
107                  /*  For WRITES: Read ALL BYTES FIRST and write them back!!!                  /*  For WRITES: Read ALL BYTES FIRST and write them back!!!
108                      Then do a write of all the new bytes. This is to make sure                      Then do a write of all the new bytes. This is to make sure
# Line 113  int MEMORY_RW(struct cpu *cpu, struct me Line 113  int MEMORY_RW(struct cpu *cpu, struct me
113                          unsigned char tmp;                          unsigned char tmp;
114                          for (i=0; i<len; i++) {                          for (i=0; i<len; i++) {
115                                  res = MEMORY_RW(cpu, mem, vaddr+i, &tmp, 1,                                  res = MEMORY_RW(cpu, mem, vaddr+i, &tmp, 1,
116                                      MEM_READ, cache_flags);                                      MEM_READ, misc_flags);
117                                  if (!res)                                  if (!res)
118                                          return 0;                                          return 0;
119                                  res = MEMORY_RW(cpu, mem, vaddr+i, &tmp, 1,                                  res = MEMORY_RW(cpu, mem, vaddr+i, &tmp, 1,
120                                      MEM_WRITE, cache_flags);                                      MEM_WRITE, misc_flags);
121                                  if (!res)                                  if (!res)
122                                          return 0;                                          return 0;
123                          }                          }
124                          for (i=0; i<len; i++) {                          for (i=0; i<len; i++) {
125                                  res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,                                  res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,
126                                      MEM_WRITE, cache_flags);                                      MEM_WRITE, misc_flags);
127                                  if (!res)                                  if (!res)
128                                          return 0;                                          return 0;
129                          }                          }
# Line 131  int MEMORY_RW(struct cpu *cpu, struct me Line 131  int MEMORY_RW(struct cpu *cpu, struct me
131                          for (i=0; i<len; i++) {                          for (i=0; i<len; i++) {
132                                  /*  Do one byte at a time:  */                                  /*  Do one byte at a time:  */
133                                  res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,                                  res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,
134                                      writeflag, cache_flags);                                      writeflag, misc_flags);
135                                  if (!res) {                                  if (!res) {
136                                          if (cache == CACHE_INSTRUCTION) {                                          if (cache == CACHE_INSTRUCTION) {
137                                                  fatal("FAILED instruction "                                                  fatal("FAILED instruction "
# Line 184  int MEMORY_RW(struct cpu *cpu, struct me Line 184  int MEMORY_RW(struct cpu *cpu, struct me
184          }          }
185  #endif  /*  MEM_MIPS  */  #endif  /*  MEM_MIPS  */
186    
187          if (cache_flags & PHYSICAL || cpu->translate_address == NULL) {          if (misc_flags & PHYSICAL || cpu->translate_address == NULL) {
188                  paddr = vaddr;                  paddr = vaddr;
   
189  #ifdef MEM_ALPHA  #ifdef MEM_ALPHA
190                  /*  paddr &= 0x1fffffff;  For testalpha  */                  /*  paddr &= 0x1fffffff;  For testalpha  */
191                  paddr &= 0x000003ffffffffffULL;                  paddr &= 0x000003ffffffffffULL;
192  #endif  #endif
   
 #ifdef MEM_IA64  
                 /*  For testia64  */  
                 paddr &= 0x3fffffff;  
 #endif  
   
 #ifdef MEM_PPC  
                 if (cpu->cd.ppc.bits == 32)  
                         paddr &= 0xffffffff;  
 #endif  
   
 #ifdef MEM_SH  
                 paddr &= 0xffffffff;  
 #endif  
193          } else {          } else {
194                  ok = cpu->translate_address(cpu, vaddr, &paddr,                  ok = cpu->translate_address(cpu, vaddr, &paddr,
195                      (writeflag? FLAG_WRITEFLAG : 0) +                      (writeflag? FLAG_WRITEFLAG : 0) +
196                      (no_exceptions? FLAG_NOEXCEPTIONS : 0)                      (no_exceptions? FLAG_NOEXCEPTIONS : 0)
197  #ifdef MEM_X86  #ifdef MEM_X86
198                      + (cache_flags & NO_SEGMENTATION)                      + (misc_flags & NO_SEGMENTATION)
199  #endif  #endif
200  #ifdef MEM_ARM  #ifdef MEM_ARM
201                      + (cache_flags & MEMORY_USER_ACCESS)                      + (misc_flags & MEMORY_USER_ACCESS)
202  #endif  #endif
203                      + (cache==CACHE_INSTRUCTION? FLAG_INSTR : 0));                      + (cache==CACHE_INSTRUCTION? FLAG_INSTR : 0));
204                  /*  If the translation caused an exception, or was invalid in                  /*  If the translation caused an exception, or was invalid in
# Line 226  int MEMORY_RW(struct cpu *cpu, struct me Line 211  int MEMORY_RW(struct cpu *cpu, struct me
211    
212  #ifdef MEM_X86  #ifdef MEM_X86
213          /*  DOS debugging :-)  */          /*  DOS debugging :-)  */
214          if (!quiet_mode && !(cache_flags & PHYSICAL)) {          if (!quiet_mode && !(misc_flags & PHYSICAL)) {
215                  if (paddr >= 0x400 && paddr <= 0x4ff)                  if (paddr >= 0x400 && paddr <= 0x4ff)
216                          debug("{ PC BIOS DATA AREA: %s 0x%x }\n", writeflag ==                          debug("{ PC BIOS DATA AREA: %s 0x%x }\n", writeflag ==
217                              MEM_WRITE? "writing to" : "reading from",                              MEM_WRITE? "writing to" : "reading from",
# Line 329  have_paddr: Line 314  have_paddr:
314                                          len = mem->dev_length[i] - paddr;                                          len = mem->dev_length[i] - paddr;
315    
316                                  if (cpu->update_translation_table != NULL &&                                  if (cpu->update_translation_table != NULL &&
317                                      mem->dev_flags[i] & MEM_DYNTRANS_OK) {                                      !(ok & MEMORY_NOT_FULL_PAGE) &&
318                                        mem->dev_flags[i] & DM_DYNTRANS_OK) {
319                                          int wf = writeflag == MEM_WRITE? 1 : 0;                                          int wf = writeflag == MEM_WRITE? 1 : 0;
320                                          unsigned char *host_addr;                                          unsigned char *host_addr;
321    
322                                          if (!(mem->dev_flags[i] &                                          if (!(mem->dev_flags[i] &
323                                              MEM_DYNTRANS_WRITE_OK))                                              DM_DYNTRANS_WRITE_OK))
324                                                  wf = 0;                                                  wf = 0;
325    
326                                          if (writeflag && wf) {                                          if (writeflag && wf) {
# Line 353  have_paddr: Line 339  have_paddr:
339                                          }                                          }
340    
341                                          if (mem->dev_flags[i] &                                          if (mem->dev_flags[i] &
342                                              MEM_EMULATED_RAM) {                                              DM_EMULATED_RAM) {
343                                                  /*  MEM_WRITE to force the page                                                  /*  MEM_WRITE to force the page
344                                                      to be allocated, if it                                                      to be allocated, if it
345                                                      wasn't already  */                                                      wasn't already  */
# Line 378  have_paddr: Line 364  have_paddr:
364    
365                                  res = 0;                                  res = 0;
366                                  if (!no_exceptions || (mem->dev_flags[i] &                                  if (!no_exceptions || (mem->dev_flags[i] &
367                                      MEM_READING_HAS_NO_SIDE_EFFECTS))                                      DM_READS_HAVE_NO_SIDE_EFFECTS))
368                                          res = mem->dev_f[i](cpu, mem, paddr,                                          res = mem->dev_f[i](cpu, mem, paddr,
369                                              data, len, writeflag,                                              data, len, writeflag,
370                                              mem->dev_extra[i]);                                              mem->dev_extra[i]);
# Line 429  have_paddr: Line 415  have_paddr:
415          switch (cpu->cd.mips.cpu_type.mmu_model) {          switch (cpu->cd.mips.cpu_type.mmu_model) {
416          case MMU3K:          case MMU3K:
417                  /*  if not uncached addess  (TODO: generalize this)  */                  /*  if not uncached addess  (TODO: generalize this)  */
418                  if (!(cache_flags & PHYSICAL) && cache != CACHE_NONE &&                  if (!(misc_flags & PHYSICAL) && cache != CACHE_NONE &&
419                      !((vaddr & 0xffffffffULL) >= 0xa0000000ULL &&                      !((vaddr & 0xffffffffULL) >= 0xa0000000ULL &&
420                        (vaddr & 0xffffffffULL) <= 0xbfffffffULL)) {                        (vaddr & 0xffffffffULL) <= 0xbfffffffULL)) {
421                          if (memory_cache_R3000(cpu, cache, paddr,                          if (memory_cache_R3000(cpu, cache, paddr,
# Line 461  have_paddr: Line 447  have_paddr:
447                  {                  {
448                          if (paddr >= mem->physical_max) {                          if (paddr >= mem->physical_max) {
449                                  char *symbol;                                  char *symbol;
                                 uint64_t old_pc;  
450                                  uint64_t offset;                                  uint64_t offset;
   
451  #ifdef MEM_MIPS  #ifdef MEM_MIPS
452                                  old_pc = cpu->cd.mips.pc_last;                                  uint64_t old_pc = cpu->cd.mips.pc_last;
453  #else  #else
454                                  /*  Default instruction size on most                                  uint64_t old_pc = cpu->pc;
                                     RISC archs is 32 bits:  */  
                                 old_pc = cpu->pc - sizeof(uint32_t);  
455  #endif  #endif
456    
457                                  /*  This allows for example OS kernels to probe                                  /*  This allows for example OS kernels to probe
# Line 589  have_paddr: Line 571  have_paddr:
571    
572          if (cpu->update_translation_table != NULL && !bintrans_device_danger          if (cpu->update_translation_table != NULL && !bintrans_device_danger
573  #ifndef MEM_MIPS  #ifndef MEM_MIPS
574  /*          && !(cache_flags & MEMORY_USER_ACCESS)  */  /*          && !(misc_flags & MEMORY_USER_ACCESS)  */
575  #ifndef MEM_USERLAND  #ifndef MEM_USERLAND
576              && !(ok & MEMORY_NOT_FULL_PAGE)              && !(ok & MEMORY_NOT_FULL_PAGE)
577  #endif  #endif
# Line 597  have_paddr: Line 579  have_paddr:
579              && !no_exceptions)              && !no_exceptions)
580                  cpu->update_translation_table(cpu, vaddr & ~offset_mask,                  cpu->update_translation_table(cpu, vaddr & ~offset_mask,
581                      memblock + (offset & ~offset_mask),                      memblock + (offset & ~offset_mask),
582                      (cache_flags & MEMORY_USER_ACCESS) |                      (misc_flags & MEMORY_USER_ACCESS) |
583  #ifndef MEM_MIPS  #ifndef MEM_MIPS
584                      (cache == CACHE_INSTRUCTION? TLB_CODE : 0) |                      (cache == CACHE_INSTRUCTION? TLB_CODE : 0) |
585  #endif  #endif
586  #if 0  #if !defined(MEM_MIPS) && !defined(MEM_USERLAND)
587                      (cache == CACHE_INSTRUCTION?                      (cache == CACHE_INSTRUCTION?
588                          (writeflag == MEM_WRITE? 1 : 0)                          (writeflag == MEM_WRITE? 1 : 0) : ok - 1),
                         : ok - 1),  
589  #else  #else
590                      (writeflag == MEM_WRITE? 1 : 0),                      (writeflag == MEM_WRITE? 1 : 0),
591  #endif  #endif
592                      paddr & ~offset_mask);                      paddr & ~offset_mask);
593    
594          /*  Invalidate code translations for the page we are writing to.  */          /*  Invalidate code translations for the page we are writing to.  */
595          if (writeflag == MEM_WRITE &&          if (writeflag == MEM_WRITE && cpu->invalidate_code_translation != NULL)
             cpu->invalidate_code_translation != NULL)  
596                  cpu->invalidate_code_translation(cpu, paddr, INVALIDATE_PADDR);                  cpu->invalidate_code_translation(cpu, paddr, INVALIDATE_PADDR);
597    
598          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {

Legend:
Removed from v.18  
changed lines
  Added in v.20

  ViewVC Help
Powered by ViewVC 1.1.26