/[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 10 by dpavlin, Mon Oct 8 16:18:27 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.38 2005/06/27 07:03:39 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
72            const int offset_mask = 0x1fff;
73    #else
74            const int offset_mask = 0xfff;
75    #endif
76    
77  #ifndef MEM_USERLAND  #ifndef MEM_USERLAND
78          int ok = 1;          int ok = 1;
79  #endif  #endif
80          uint64_t paddr;          uint64_t paddr;
81          int cache, no_exceptions, offset;          int cache, no_exceptions, offset;
82          unsigned char *memblock;          unsigned char *memblock;
83  #ifdef BINTRANS  #ifdef MEM_MIPS
84          int bintrans_cached = cpu->machine->bintrans_enable;          int bintrans_cached = cpu->machine->bintrans_enable;
         int bintrans_device_danger = 0;  
85  #endif  #endif
86          no_exceptions = cache_flags & NO_EXCEPTIONS;          int bintrans_device_danger = 0;
         cache = cache_flags & CACHE_FLAGS_MASK;  
87    
88  #ifdef MEM_PPC          no_exceptions = misc_flags & NO_EXCEPTIONS;
89          if (cpu->cd.ppc.bits == 32)          cache = misc_flags & CACHE_FLAGS_MASK;
                 vaddr &= 0xffffffff;  
 #endif  
   
 #ifdef MEM_ARM  
         vaddr &= 0x3fffffff;  
 #endif  
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 115  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 133  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 150  int MEMORY_RW(struct cpu *cpu, struct me Line 148  int MEMORY_RW(struct cpu *cpu, struct me
148          }          }
149  #endif  /*  X86  */  #endif  /*  X86  */
150    
 #ifdef MEM_URISC  
         {  
                 uint64_t mask = (uint64_t) -1;  
                 if (cpu->cd.urisc.wordlen < 64)  
                         mask = ((int64_t)1 << cpu->cd.urisc.wordlen) - 1;  
                 vaddr &= mask;  
         }  
 #endif  
   
151  #ifdef MEM_MIPS  #ifdef MEM_MIPS
 #ifdef BINTRANS  
152          if (bintrans_cached) {          if (bintrans_cached) {
153                  if (cache == CACHE_INSTRUCTION) {                  if (cache == CACHE_INSTRUCTION) {
154                          cpu->cd.mips.pc_bintrans_host_4kpage = NULL;                          cpu->cd.mips.pc_bintrans_host_4kpage = NULL;
155                          cpu->cd.mips.pc_bintrans_paddr_valid = 0;                          cpu->cd.mips.pc_bintrans_paddr_valid = 0;
156                  }                  }
157          }          }
 #endif  
158  #endif  /*  MEM_MIPS  */  #endif  /*  MEM_MIPS  */
159    
160  #ifdef MEM_USERLAND  #ifdef MEM_USERLAND
161    #ifdef MEM_ALPHA
162            paddr = vaddr;
163    #else
164          paddr = vaddr & 0x7fffffff;          paddr = vaddr & 0x7fffffff;
165    #endif
166          goto have_paddr;          goto have_paddr;
167  #endif  #endif
168    
# Line 193  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
190                    /*  paddr &= 0x1fffffff;  For testalpha  */
191                    paddr &= 0x000003ffffffffffULL;
192    #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
200    #ifdef MEM_ARM
201                        + (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 213  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 255  have_paddr: Line 253  have_paddr:
253    
254  #ifdef MEM_MIPS  #ifdef MEM_MIPS
255          /*  TODO: How about bintrans vs cache emulation?  */          /*  TODO: How about bintrans vs cache emulation?  */
 #ifdef BINTRANS  
256          if (bintrans_cached) {          if (bintrans_cached) {
257                  if (cache == CACHE_INSTRUCTION) {                  if (cache == CACHE_INSTRUCTION) {
258                          cpu->cd.mips.pc_bintrans_paddr_valid = 1;                          cpu->cd.mips.pc_bintrans_paddr_valid = 1;
259                          cpu->cd.mips.pc_bintrans_paddr = paddr;                          cpu->cd.mips.pc_bintrans_paddr = paddr;
260                  }                  }
261          }          }
 #endif  
262  #endif  /*  MEM_MIPS  */  #endif  /*  MEM_MIPS  */
263    
264    
# Line 276  have_paddr: Line 272  have_paddr:
272           *  to a device to           *  to a device to
273           */           */
274          if (paddr >= mem->mmap_dev_minaddr && paddr < mem->mmap_dev_maxaddr) {          if (paddr >= mem->mmap_dev_minaddr && paddr < mem->mmap_dev_maxaddr) {
 #ifdef BINTRANS  
275                  uint64_t orig_paddr = paddr;                  uint64_t orig_paddr = paddr;
 #endif  
276                  int i, start, res;                  int i, start, res;
277    
 #ifdef BINTRANS  
278                  /*                  /*
279                   *  Really really slow, but unfortunately necessary. This is                   *  Really really slow, but unfortunately necessary. This is
280                   *  to avoid the folowing scenario:                   *  to avoid the folowing scenario:
# Line 300  have_paddr: Line 293  have_paddr:
293                   *  on _any_ offset on pages that are device mapped avoids                   *  on _any_ offset on pages that are device mapped avoids
294                   *  this problem, but it is probably not very fast.                   *  this problem, but it is probably not very fast.
295                   */                   */
296                  if (bintrans_cached) {                  for (i=0; i<mem->n_mmapped_devices; i++)
297                          for (i=0; i<mem->n_mmapped_devices; i++)                          if (paddr >= (mem->dev_baseaddr[i] & ~offset_mask) &&
298                                  if (paddr >= (mem->dev_baseaddr[i] & ~0xfff) &&                              paddr <= ((mem->dev_endaddr[i]-1) | offset_mask)) {
299                                      paddr <= ((mem->dev_baseaddr[i] +                                  bintrans_device_danger = 1;
300                                      mem->dev_length[i] - 1) | 0xfff)) {                                  break;
301                                          bintrans_device_danger = 1;                          }
                                         break;  
                                 }  
                 }  
 #endif  
302    
303                  i = start = mem->last_accessed_device;                  i = start = mem->last_accessed_device;
304    
305                  /*  Scan through all devices:  */                  /*  Scan through all devices:  */
306                  do {                  do {
307                          if (paddr >= mem->dev_baseaddr[i] &&                          if (paddr >= mem->dev_baseaddr[i] &&
308                              paddr < mem->dev_baseaddr[i] + mem->dev_length[i]) {                              paddr < mem->dev_endaddr[i]) {
309                                  /*  Found a device, let's access it:  */                                  /*  Found a device, let's access it:  */
310                                  mem->last_accessed_device = i;                                  mem->last_accessed_device = i;
311    
# Line 324  have_paddr: Line 313  have_paddr:
313                                  if (paddr + len > mem->dev_length[i])                                  if (paddr + len > mem->dev_length[i])
314                                          len = mem->dev_length[i] - paddr;                                          len = mem->dev_length[i] - paddr;
315    
316  #ifdef BINTRANS                                  if (cpu->update_translation_table != NULL &&
317                                  if (bintrans_cached && mem->dev_flags[i] &                                      !(ok & MEMORY_NOT_FULL_PAGE) &&
318                                      MEM_BINTRANS_OK) {                                      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;
321    
322                                          if (writeflag) {                                          if (!(mem->dev_flags[i] &
323                                                DM_DYNTRANS_WRITE_OK))
324                                                    wf = 0;
325    
326                                            if (writeflag && wf) {
327                                                  if (paddr < mem->                                                  if (paddr < mem->
328                                                      dev_bintrans_write_low[i])                                                      dev_dyntrans_write_low[i])
329                                                          mem->                                                          mem->
330                                                          dev_bintrans_write_low                                                          dev_dyntrans_write_low
331                                                              [i] =                                                              [i] = paddr &
332                                                              paddr & ~0xfff;                                                              ~offset_mask;
333                                                  if (paddr > mem->                                                  if (paddr >= mem->
334                                                      dev_bintrans_write_high[i])                                                      dev_dyntrans_write_high[i])
335                                                          mem->                                                          mem->
336                                                          dev_bintrans_write_high                                                          dev_dyntrans_write_high
337                                                              [i] = paddr | 0xfff;                                                              [i] = paddr |
338                                                                offset_mask;
339                                          }                                          }
340    
341                                          if (!(mem->dev_flags[i] &                                          if (mem->dev_flags[i] &
342                                              MEM_BINTRANS_WRITE_OK))                                              DM_EMULATED_RAM) {
343                                                  wf = 0;                                                  /*  MEM_WRITE to force the page
344                                                        to be allocated, if it
345                                          update_translation_table(cpu,                                                      wasn't already  */
346                                              vaddr & ~0xfff,                                                  uint64_t *pp = (uint64_t *)
347                                              mem->dev_bintrans_data[i] +                                                      mem->dev_dyntrans_data[i];
348                                              (paddr & ~0xfff),                                                  uint64_t p = orig_paddr - *pp;
349                                              wf, orig_paddr & ~0xfff);                                                  host_addr =
350                                                        memory_paddr_to_hostaddr(
351                                                        mem, p, MEM_WRITE)
352                                                        + (p & ~offset_mask
353                                                        & ((1 <<
354                                                        BITS_PER_MEMBLOCK) - 1));
355                                            } else {
356                                                    host_addr =
357                                                        mem->dev_dyntrans_data[i] +
358                                                        (paddr & ~offset_mask);
359                                            }
360                                            cpu->update_translation_table(cpu,
361                                                vaddr & ~offset_mask, host_addr,
362                                                wf, orig_paddr & ~offset_mask);
363                                  }                                  }
 #endif  
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 366  have_paddr: Line 373  have_paddr:
373                                  if (res == 0)                                  if (res == 0)
374                                          res = -1;                                          res = -1;
375    
376    #ifdef MEM_MIPS
377                                  cpu->cd.mips.instruction_delay +=                                  cpu->cd.mips.instruction_delay +=
378                                      ( (abs(res) - 1) *                                      ( (abs(res) - 1) *
379                                       cpu->cd.mips.cpu_type.instrs_per_cycle );                                       cpu->cd.mips.cpu_type.instrs_per_cycle );
380  #endif  #endif
381    #endif
382    
383  #ifndef MEM_X86  #ifndef MEM_X86
384                                  /*                                  /*
# Line 406  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 414  have_paddr: Line 423  have_paddr:
423                                  goto do_return_ok;                                  goto do_return_ok;
424                  }                  }
425                  break;                  break;
 #if 0  
 /*  Remove this, it doesn't work anyway  */  
         case MMU10K:  
                 /*  other cpus:  */  
                 /*  
                  *  SUPER-UGLY HACK for SGI-IP32 PROM, R10000:  
                  *  K0 bits == 0x3 means uncached...  
                  *  
                  *  It seems that during bootup, the SGI-IP32 prom  
                  *  stores a return pointers a 0x80000f10, then tests  
                  *  memory by writing bit patterns to 0xa0000xxx, and  
                  *  then when it's done, reads back the return pointer  
                  *  from 0x80000f10.  
                  *  
                  *  I need to find the correct way to disconnect the  
                  *  cache from the main memory for R10000.  (TODO !!!)  
                  */  
 /*              if ((cpu->cd.mips.coproc[0]->reg[COP0_CONFIG] & 7) == 3) {  */  
 /*  
                 if (cache == CACHE_DATA &&  
                     cpu->r10k_cache_disable_TODO) {  
                         paddr &= ((512*1024)-1);  
                         paddr += 512*1024;  
                 }  
 */  
                 break;  
 #endif  
426          default:          default:
427                  /*  R4000 etc  */                  /*  R4000 etc  */
428                  /*  TODO  */                  /*  TODO  */
# Line 465  have_paddr: Line 447  have_paddr:
447                  {                  {
448                          if (paddr >= mem->physical_max) {                          if (paddr >= mem->physical_max) {
449                                  char *symbol;                                  char *symbol;
 #ifdef MEM_MIPS  
450                                  uint64_t offset;                                  uint64_t offset;
451    #ifdef MEM_MIPS
452                                    uint64_t old_pc = cpu->cd.mips.pc_last;
453    #else
454                                    uint64_t old_pc = cpu->pc;
455  #endif  #endif
456    
457                                  /*  This allows for example OS kernels to probe                                  /*  This allows for example OS kernels to probe
458                                      memory a few KBs past the end of memory,                                      memory a few KBs past the end of memory,
459                                      without giving too many warnings.  */                                      without giving too many warnings.  */
460                                  if (!quiet_mode && paddr >=                                  if (!quiet_mode && !no_exceptions && paddr >=
461                                      mem->physical_max + 0x40000) {                                      mem->physical_max + 0x40000) {
462                                          fatal("[ memory_rw(): writeflag=%i ",                                          fatal("[ memory_rw(): writeflag=%i ",
463                                              writeflag);                                              writeflag);
# Line 499  have_paddr: Line 485  have_paddr:
485                                                                      data[i]);                                                                      data[i]);
486                                                  debug("}");                                                  debug("}");
487                                          }                                          }
488  #ifdef MEM_MIPS  
489                                            fatal(" paddr=0x%llx >= physical_max"
490                                                "; pc=", (long long)paddr);
491                                            if (cpu->is_32bit)
492                                                    fatal("0x%08x",(int)old_pc);
493                                            else
494                                                    fatal("0x%016llx",
495                                                        (long long)old_pc);
496                                          symbol = get_symbol_name(                                          symbol = get_symbol_name(
497                                              &cpu->machine->symbol_context,                                              &cpu->machine->symbol_context,
498                                              cpu->cd.mips.pc_last, &offset);                                              old_pc, &offset);
499  #else                                          fatal(" <%s> ]\n",
500                                          symbol = "(unimpl for non-MIPS)";                                              symbol? symbol : " no symbol ");
 #endif  
   
 /*  TODO: fix! not mips.pc_last for for example ppc  */  
   
                                         fatal(" paddr=%llx >= physical_max pc="  
                                             "0x%08llx <%s> ]\n",  
                                             (long long)paddr,  
                                             (long long)cpu->cd.mips.pc_last,  
                                             symbol? symbol : "no symbol");  
501                                  }                                  }
502    
503                                  if (cpu->machine->single_step_on_bad_addr) {                                  if (cpu->machine->single_step_on_bad_addr) {
504                                          fatal("[ unimplemented access to "                                          fatal("[ unimplemented access to "
505                                              "0x%016llx, pc = 0x%016llx ]\n",                                              "0x%llx, pc=0x",(long long)paddr);
506                                              (long long)paddr,                                          if (cpu->is_32bit)
507                                              (long long)cpu->pc);                                                  fatal("%08x ]\n",
508                                                        (int)old_pc);
509                                            else
510                                                    fatal("%016llx ]\n",
511                                                        (long long)old_pc);
512                                          single_step = 1;                                          single_step = 1;
513                                  }                                  }
514                          }                          }
# Line 563  have_paddr: Line 551  have_paddr:
551    
552          /*          /*
553           *  Uncached access:           *  Uncached access:
554             *
555             *  1)  Translate the physical address to a host address.
556             *
557             *  2)  Insert this virtual->physical->host translation into the
558             *      fast translation arrays (using update_translation_table()).
559             *
560             *  3)  If this was a Write, then invalidate any code translations
561             *      in that page.
562           */           */
563          memblock = memory_paddr_to_hostaddr(mem, paddr, writeflag);          memblock = memory_paddr_to_hostaddr(mem, paddr, writeflag);
564          if (memblock == NULL) {          if (memblock == NULL) {
# Line 573  have_paddr: Line 569  have_paddr:
569    
570          offset = paddr & ((1 << BITS_PER_MEMBLOCK) - 1);          offset = paddr & ((1 << BITS_PER_MEMBLOCK) - 1);
571    
572  #ifdef BINTRANS          if (cpu->update_translation_table != NULL && !bintrans_device_danger
573          if (bintrans_cached && !bintrans_device_danger)  #ifndef MEM_MIPS
574                  update_translation_table(cpu, vaddr & ~0xfff,  /*          && !(misc_flags & MEMORY_USER_ACCESS)  */
575                      memblock + (offset & ~0xfff),  #ifndef MEM_USERLAND
576  #if 0              && !(ok & MEMORY_NOT_FULL_PAGE)
                     cache == CACHE_INSTRUCTION?  
                         (writeflag == MEM_WRITE? 1 : 0)  
                         : ok - 1,  
 #else  
                     writeflag == MEM_WRITE? 1 : 0,  
577  #endif  #endif
                     paddr & ~0xfff);  
578  #endif  #endif
579                && !no_exceptions)
580                    cpu->update_translation_table(cpu, vaddr & ~offset_mask,
581                        memblock + (offset & ~offset_mask),
582                        (misc_flags & MEMORY_USER_ACCESS) |
583    #ifndef MEM_MIPS
584                        (cache == CACHE_INSTRUCTION? TLB_CODE : 0) |
585    #endif
586    #if !defined(MEM_MIPS) && !defined(MEM_USERLAND)
587                        (cache == CACHE_INSTRUCTION?
588                            (writeflag == MEM_WRITE? 1 : 0) : ok - 1),
589    #else
590                        (writeflag == MEM_WRITE? 1 : 0),
591    #endif
592                        paddr & ~offset_mask);
593    
594            /*  Invalidate code translations for the page we are writing to.  */
595            if (writeflag == MEM_WRITE && cpu->invalidate_code_translation != NULL)
596                    cpu->invalidate_code_translation(cpu, paddr, INVALIDATE_PADDR);
597    
598          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
599                  if (len == sizeof(uint32_t) && (offset & 3)==0)                  /*  Ugly optimization, but it works:  */
600                    if (len == sizeof(uint32_t) && (offset & 3)==0
601                        && ((size_t)data&3)==0)
602                          *(uint32_t *)(memblock + offset) = *(uint32_t *)data;                          *(uint32_t *)(memblock + offset) = *(uint32_t *)data;
603                  else if (len == sizeof(uint8_t))                  else if (len == sizeof(uint8_t))
604                          *(uint8_t *)(memblock + offset) = *(uint8_t *)data;                          *(uint8_t *)(memblock + offset) = *(uint8_t *)data;
605                  else                  else
606                          memcpy(memblock + offset, data, len);                          memcpy(memblock + offset, data, len);
607          } else {          } else {
608                  if (len == sizeof(uint32_t) && (offset & 3)==0)                  /*  Ugly optimization, but it works:  */
609                    if (len == sizeof(uint32_t) && (offset & 3)==0
610                        && ((size_t)data&3)==0)
611                          *(uint32_t *)data = *(uint32_t *)(memblock + offset);                          *(uint32_t *)data = *(uint32_t *)(memblock + offset);
612                  else if (len == sizeof(uint8_t))                  else if (len == sizeof(uint8_t))
613                          *(uint8_t *)data = *(uint8_t *)(memblock + offset);                          *(uint8_t *)data = *(uint8_t *)(memblock + offset);
# Line 605  have_paddr: Line 617  have_paddr:
617  #ifdef MEM_MIPS  #ifdef MEM_MIPS
618                  if (cache == CACHE_INSTRUCTION) {                  if (cache == CACHE_INSTRUCTION) {
619                          cpu->cd.mips.pc_last_host_4k_page = memblock                          cpu->cd.mips.pc_last_host_4k_page = memblock
620                              + (offset & ~0xfff);                              + (offset & ~offset_mask);
 #ifdef BINTRANS  
621                          if (bintrans_cached) {                          if (bintrans_cached) {
622                                  cpu->cd.mips.pc_bintrans_host_4kpage =                                  cpu->cd.mips.pc_bintrans_host_4kpage =
623                                      cpu->cd.mips.pc_last_host_4k_page;                                      cpu->cd.mips.pc_last_host_4k_page;
624                          }                          }
 #endif  
625                  }                  }
626  #endif  /*  MIPS  */  #endif  /*  MIPS  */
627          }          }

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

  ViewVC Help
Powered by ViewVC 1.1.26