/[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 2 by dpavlin, Mon Oct 8 16:17:48 2007 UTC revision 12 by dpavlin, Mon Oct 8 16:18:38 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: memory_rw.c,v 1.10 2005/03/01 08:23:55 debug Exp $   *  $Id: memory_rw.c,v 1.57 2005/08/12 21:57:02 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 68  Line 68 
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 cache_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;
85  #endif  #endif
86            int bintrans_device_danger = 0;
87    
88          no_exceptions = cache_flags & NO_EXCEPTIONS;          no_exceptions = cache_flags & NO_EXCEPTIONS;
89          cache = cache_flags & CACHE_FLAGS_MASK;          cache = cache_flags & CACHE_FLAGS_MASK;
90    
91  #ifdef MEM_PPC  #ifdef MEM_X86
92          if (cpu->cd.ppc.bits == 32)          /*  Real-mode wrap-around:  */
93                  vaddr &= 0xffffffff;          if (REAL_MODE && !(cache_flags & PHYSICAL)) {
94  #endif                  if ((vaddr & 0xffff) + len > 0x10000) {
95                            /*  Do one byte at a time:  */
96                            int res = 0, i;
97                            for (i=0; i<len; i++)
98                                    res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,
99                                        writeflag, cache_flags);
100                            return res;
101                    }
102            }
103    
104  #ifdef MEM_URISC          /*  Crossing a page boundary? Then do one byte at a time:  */
105          {          if ((vaddr & 0xfff) + len > 0x1000 && !(cache_flags & PHYSICAL)
106                  uint64_t mask = (uint64_t) -1;              && cpu->cd.x86.cr[0] & X86_CR0_PG) {
107                  if (cpu->cd.urisc.wordlen < 64)                  /*  For WRITES: Read ALL BYTES FIRST and write them back!!!
108                          mask = ((int64_t)1 << cpu->cd.urisc.wordlen) - 1;                      Then do a write of all the new bytes. This is to make sure
109                  vaddr &= mask;                      than both pages around the boundary are writable so we don't
110                        do a partial write.  */
111                    int res = 0, i;
112                    if (writeflag == MEM_WRITE) {
113                            unsigned char tmp;
114                            for (i=0; i<len; i++) {
115                                    res = MEMORY_RW(cpu, mem, vaddr+i, &tmp, 1,
116                                        MEM_READ, cache_flags);
117                                    if (!res)
118                                            return 0;
119                                    res = MEMORY_RW(cpu, mem, vaddr+i, &tmp, 1,
120                                        MEM_WRITE, cache_flags);
121                                    if (!res)
122                                            return 0;
123                            }
124                            for (i=0; i<len; i++) {
125                                    res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,
126                                        MEM_WRITE, cache_flags);
127                                    if (!res)
128                                            return 0;
129                            }
130                    } else {
131                            for (i=0; i<len; i++) {
132                                    /*  Do one byte at a time:  */
133                                    res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,
134                                        writeflag, cache_flags);
135                                    if (!res) {
136                                            if (cache == CACHE_INSTRUCTION) {
137                                                    fatal("FAILED instruction "
138                                                        "fetch across page boundar"
139                                                        "y: todo. vaddr=0x%08x\n",
140                                                        (int)vaddr);
141                                                    cpu->running = 0;
142                                            }
143                                            return 0;
144                                    }
145                            }
146                    }
147                    return res;
148          }          }
149  #endif  #endif  /*  X86  */
150    
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 130  int MEMORY_RW(struct cpu *cpu, struct me Line 186  int MEMORY_RW(struct cpu *cpu, struct me
186    
187          if (cache_flags & PHYSICAL || cpu->translate_address == NULL) {          if (cache_flags & PHYSICAL || cpu->translate_address == NULL) {
188                  paddr = vaddr;                  paddr = vaddr;
189    
190    #ifdef MEM_ALPHA
191            /*  paddr &= 0x1fffffff;  For testalpha  */
192            paddr &= 0x000003ffffffffffULL;
193    #endif
194    
195    #ifdef MEM_ARM
196            paddr &= 0x3fffffff;
197    #endif
198    
199    #ifdef MEM_IA64
200            /*  For testia64  */
201            paddr &= 0x3fffffff;
202    #endif
203    
204    #ifdef MEM_PPC
205            if (cpu->cd.ppc.bits == 32)
206                    paddr &= 0xffffffff;
207    #endif
208    
209          } else {          } else {
210                  ok = cpu->translate_address(cpu, vaddr, &paddr,                  ok = cpu->translate_address(cpu, vaddr, &paddr,
211                      (writeflag? FLAG_WRITEFLAG : 0) +                      (writeflag? FLAG_WRITEFLAG : 0) +
212                      (no_exceptions? FLAG_NOEXCEPTIONS : 0)                      (no_exceptions? FLAG_NOEXCEPTIONS : 0)
213    #ifdef MEM_X86
214                        + (cache_flags & NO_SEGMENTATION)
215    #endif
216                      + (cache==CACHE_INSTRUCTION? FLAG_INSTR : 0));                      + (cache==CACHE_INSTRUCTION? FLAG_INSTR : 0));
217                  /*  If the translation caused an exception, or was invalid in                  /*  If the translation caused an exception, or was invalid in
218                      some way, we simply return without doing the memory                      some way, we simply return without doing the memory
# Line 143  int MEMORY_RW(struct cpu *cpu, struct me Line 222  int MEMORY_RW(struct cpu *cpu, struct me
222          }          }
223    
224    
225    #ifdef MEM_X86
226            /*  DOS debugging :-)  */
227            if (!quiet_mode && !(cache_flags & PHYSICAL)) {
228                    if (paddr >= 0x400 && paddr <= 0x4ff)
229                            debug("{ PC BIOS DATA AREA: %s 0x%x }\n", writeflag ==
230                                MEM_WRITE? "writing to" : "reading from",
231                                (int)paddr);
232    #if 0
233                    if (paddr >= 0xf0000 && paddr <= 0xfffff)
234                            debug("{ BIOS ACCESS: %s 0x%x }\n",
235                                writeflag == MEM_WRITE? "writing to" :
236                                "reading from", (int)paddr);
237    #endif
238            }
239    #endif
240    
241  #ifdef MEM_MIPS  #ifdef MEM_MIPS
242          /*          /*
243           *  If correct cache emulation is enabled, and we need to simluate           *  If correct cache emulation is enabled, and we need to simluate
# Line 164  int MEMORY_RW(struct cpu *cpu, struct me Line 259  int MEMORY_RW(struct cpu *cpu, struct me
259  #endif  /*  ifndef MEM_USERLAND  */  #endif  /*  ifndef MEM_USERLAND  */
260    
261    
262    #if defined(MEM_MIPS) || defined(MEM_USERLAND)
263  have_paddr:  have_paddr:
264    #endif
265    
266    
267  #ifdef MEM_MIPS  #ifdef MEM_MIPS
268          /*  TODO: How about bintrans vs cache emulation?  */          /*  TODO: How about bintrans vs cache emulation?  */
 #ifdef BINTRANS  
269          if (bintrans_cached) {          if (bintrans_cached) {
270                  if (cache == CACHE_INSTRUCTION) {                  if (cache == CACHE_INSTRUCTION) {
271                          cpu->cd.mips.pc_bintrans_paddr_valid = 1;                          cpu->cd.mips.pc_bintrans_paddr_valid = 1;
272                          cpu->cd.mips.pc_bintrans_paddr = paddr;                          cpu->cd.mips.pc_bintrans_paddr = paddr;
273                  }                  }
274          }          }
 #endif  
275  #endif  /*  MEM_MIPS  */  #endif  /*  MEM_MIPS  */
276    
277    
         if (!(cache_flags & PHYSICAL))  
                 if (no_exceptions)  
                         goto no_exception_access;  
   
278    
279  #ifndef MEM_USERLAND  #ifndef MEM_USERLAND
280          /*          /*
# Line 194  have_paddr: Line 285  have_paddr:
285           *  to a device to           *  to a device to
286           */           */
287          if (paddr >= mem->mmap_dev_minaddr && paddr < mem->mmap_dev_maxaddr) {          if (paddr >= mem->mmap_dev_minaddr && paddr < mem->mmap_dev_maxaddr) {
 #ifdef BINTRANS  
288                  uint64_t orig_paddr = paddr;                  uint64_t orig_paddr = paddr;
 #endif  
289                  int i, start, res;                  int i, start, res;
290    
291                    /*
292                     *  Really really slow, but unfortunately necessary. This is
293                     *  to avoid the folowing scenario:
294                     *
295                     *      a) offsets 0x000..0x123 are normal memory
296                     *      b) offsets 0x124..0x777 are a device
297                     *
298                     *      1) a read is done from offset 0x100. the page is
299                     *         added to the bintrans system as a "RAM" page
300                     *      2) a bintranslated read is done from offset 0x200,
301                     *         which should access the device, but since the
302                     *         entire page is added, it will access non-existant
303                     *         RAM instead, without warning.
304                     *
305                     *  Setting bintrans_device_danger = 1 on accesses which are
306                     *  on _any_ offset on pages that are device mapped avoids
307                     *  this problem, but it is probably not very fast.
308                     */
309                    for (i=0; i<mem->n_mmapped_devices; i++)
310                            if (paddr >= (mem->dev_baseaddr[i] & ~offset_mask) &&
311                                paddr <= ((mem->dev_baseaddr[i] +
312                                mem->dev_length[i] - 1) | offset_mask)) {
313                                    bintrans_device_danger = 1;
314                                    break;
315                            }
316    
317                  i = start = mem->last_accessed_device;                  i = start = mem->last_accessed_device;
318    
319                  /*  Scan through all devices:  */                  /*  Scan through all devices:  */
# Line 211  have_paddr: Line 327  have_paddr:
327                                  if (paddr + len > mem->dev_length[i])                                  if (paddr + len > mem->dev_length[i])
328                                          len = mem->dev_length[i] - paddr;                                          len = mem->dev_length[i] - paddr;
329    
330  #ifdef BINTRANS                                  if (cpu->update_translation_table != NULL &&
331                                  if (bintrans_cached && mem->dev_flags[i] &                                      mem->dev_flags[i] & MEM_DYNTRANS_OK) {
                                     MEM_BINTRANS_OK) {  
332                                          int wf = writeflag == MEM_WRITE? 1 : 0;                                          int wf = writeflag == MEM_WRITE? 1 : 0;
333    
334                                          if (writeflag) {                                          if (writeflag) {
335                                                  if (paddr < mem->                                                  if (paddr < mem->
336                                                      dev_bintrans_write_low[i])                                                      dev_dyntrans_write_low[i])
337                                                          mem->                                                          mem->
338                                                          dev_bintrans_write_low                                                          dev_dyntrans_write_low
339                                                              [i] =                                                              [i] = paddr &
340                                                              paddr & ~0xfff;                                                              ~offset_mask;
341                                                  if (paddr > mem->                                                  if (paddr >= mem->
342                                                      dev_bintrans_write_high[i])                                                      dev_dyntrans_write_high[i])
343                                                          mem->                                                          mem->
344                                                          dev_bintrans_write_high                                                          dev_dyntrans_write_high
345                                                              [i] = paddr | 0xfff;                                                              [i] = paddr |
346                                                                offset_mask;
347                                          }                                          }
348    
349                                          if (!(mem->dev_flags[i] &                                          if (!(mem->dev_flags[i] &
350                                              MEM_BINTRANS_WRITE_OK))                                              MEM_DYNTRANS_WRITE_OK))
351                                                  wf = 0;                                                  wf = 0;
352    
353                                          update_translation_table(cpu,                                          cpu->update_translation_table(cpu,
354                                              vaddr & ~0xfff,                                              vaddr & ~offset_mask,
355                                              mem->dev_bintrans_data[i] +                                              mem->dev_dyntrans_data[i] +
356                                              (paddr & ~0xfff),                                              (paddr & ~offset_mask),
357                                              wf, orig_paddr & ~0xfff);                                              wf, orig_paddr & ~offset_mask);
358                                  }                                  }
 #endif  
359    
360                                  res = mem->dev_f[i](cpu, mem, paddr, data, len,                                  res = 0;
361                                      writeflag, mem->dev_extra[i]);                                  if (!no_exceptions || (mem->dev_flags[i] &
362                                        MEM_READING_HAS_NO_SIDE_EFFECTS))
363                                            res = mem->dev_f[i](cpu, mem, paddr,
364                                                data, len, writeflag,
365                                                mem->dev_extra[i]);
366    
367  #ifdef ENABLE_INSTRUCTION_DELAYS  #ifdef ENABLE_INSTRUCTION_DELAYS
368                                  if (res == 0)                                  if (res == 0)
# Line 253  have_paddr: Line 372  have_paddr:
372                                      ( (abs(res) - 1) *                                      ( (abs(res) - 1) *
373                                       cpu->cd.mips.cpu_type.instrs_per_cycle );                                       cpu->cd.mips.cpu_type.instrs_per_cycle );
374  #endif  #endif
375    
376    #ifndef MEM_X86
377                                  /*                                  /*
378                                   *  If accessing the memory mapped device                                   *  If accessing the memory mapped device
379                                   *  failed, then return with a DBE exception.                                   *  failed, then return with a DBE exception.
380                                   */                                   */
381                                  if (res <= 0) {                                  if (res <= 0 && !no_exceptions) {
382                                          debug("%s device '%s' addr %08lx "                                          debug("%s device '%s' addr %08lx "
383                                              "failed\n", writeflag?                                              "failed\n", writeflag?
384                                              "writing to" : "reading from",                                              "writing to" : "reading from",
# Line 268  have_paddr: Line 389  have_paddr:
389  #endif  #endif
390                                          return MEMORY_ACCESS_FAILED;                                          return MEMORY_ACCESS_FAILED;
391                                  }                                  }
392    #endif
393                                  goto do_return_ok;                                  goto do_return_ok;
394                          }                          }
395    
# Line 295  have_paddr: Line 416  have_paddr:
416                                  goto do_return_ok;                                  goto do_return_ok;
417                  }                  }
418                  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  
419          default:          default:
420                  /*  R4000 etc  */                  /*  R4000 etc  */
421                  /*  TODO  */                  /*  TODO  */
# Line 332  have_paddr: Line 426  have_paddr:
426    
427          /*  Outside of physical RAM?  */          /*  Outside of physical RAM?  */
428          if (paddr >= mem->physical_max) {          if (paddr >= mem->physical_max) {
429                  if ((paddr & 0xffff000000ULL) == 0x1f000000) {  #ifdef MEM_MIPS
430                    if ((paddr & 0xffffc00000ULL) == 0x1fc00000) {
431                          /*  Ok, this is PROM stuff  */                          /*  Ok, this is PROM stuff  */
432                  } else if ((paddr & 0xfffff00000ULL) == 0x1ff00000) {                  } else if ((paddr & 0xfffff00000ULL) == 0x1ff00000) {
433                          /*  Sprite reads from this area of memory...  */                          /*  Sprite reads from this area of memory...  */
# Line 340  have_paddr: Line 435  have_paddr:
435                          if (writeflag == MEM_READ)                          if (writeflag == MEM_READ)
436                                  memset(data, 0, len);                                  memset(data, 0, len);
437                          goto do_return_ok;                          goto do_return_ok;
438                  } else {                  } else
439                          if (paddr >= mem->physical_max + 0 * 1024) {  #endif /* MIPS */
440                    {
441                            if (paddr >= mem->physical_max) {
442                                  char *symbol;                                  char *symbol;
443  #ifdef MEM_MIPS                                  uint64_t old_pc;
444                                  uint64_t offset;                                  uint64_t offset;
445    
446    #ifdef MEM_MIPS
447                                    old_pc = cpu->cd.mips.pc_last;
448    #else
449                                    /*  Default instruction size on most
450                                        RISC archs is 32 bits:  */
451                                    old_pc = cpu->pc - sizeof(uint32_t);
452  #endif  #endif
453                                  if (!quiet_mode) {  
454                                    /*  This allows for example OS kernels to probe
455                                        memory a few KBs past the end of memory,
456                                        without giving too many warnings.  */
457                                    if (!quiet_mode && !no_exceptions && paddr >=
458                                        mem->physical_max + 0x40000) {
459                                          fatal("[ memory_rw(): writeflag=%i ",                                          fatal("[ memory_rw(): writeflag=%i ",
460                                              writeflag);                                              writeflag);
461                                          if (writeflag) {                                          if (writeflag) {
# Line 373  have_paddr: Line 482  have_paddr:
482                                                                      data[i]);                                                                      data[i]);
483                                                  debug("}");                                                  debug("}");
484                                          }                                          }
485  #ifdef MEM_MIPS  
486                                            fatal(" paddr=0x%llx >= physical_max"
487                                                "; pc=", (long long)paddr);
488                                            if (cpu->is_32bit)
489                                                    fatal("0x%08x",(int)old_pc);
490                                            else
491                                                    fatal("0x%016llx",
492                                                        (long long)old_pc);
493                                          symbol = get_symbol_name(                                          symbol = get_symbol_name(
494                                              &cpu->machine->symbol_context,                                              &cpu->machine->symbol_context,
495                                              cpu->cd.mips.pc_last, &offset);                                              old_pc, &offset);
496  #else                                          fatal(" <%s> ]\n",
497                                          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");  
498                                  }                                  }
499    
500                                  if (cpu->machine->single_step_on_bad_addr) {                                  if (cpu->machine->single_step_on_bad_addr) {
501                                          fatal("[ unimplemented access to "                                          fatal("[ unimplemented access to "
502                                              "0x%016llx, pc = 0x%016llx ]\n",                                              "0x%llx, pc=0x",(long long)paddr);
503                                              (long long)paddr,                                          if (cpu->is_32bit)
504                                              (long long)cpu->pc);                                                  fatal("%08x ]\n",
505                                                        (int)old_pc);
506                                            else
507                                                    fatal("%016llx ]\n",
508                                                        (long long)old_pc);
509                                          single_step = 1;                                          single_step = 1;
510                                  }                                  }
511                          }                          }
512    
513                          if (writeflag == MEM_READ) {                          if (writeflag == MEM_READ) {
514    #ifdef MEM_X86
515                                    /*  Reading non-existant memory on x86:  */
516                                    memset(data, 0xff, len);
517    #else
518                                  /*  Return all zeroes? (Or 0xff? TODO)  */                                  /*  Return all zeroes? (Or 0xff? TODO)  */
519                                  memset(data, 0, len);                                  memset(data, 0, len);
520    #endif
521    
522  #ifdef MEM_MIPS  #ifdef MEM_MIPS
523                                  /*                                  /*
# Line 409  have_paddr: Line 525  have_paddr:
525                                   *  an exceptions on an illegal read:                                   *  an exceptions on an illegal read:
526                                   */                                   */
527                                  if (cache != CACHE_NONE && cpu->machine->                                  if (cache != CACHE_NONE && cpu->machine->
528                                      dbe_on_nonexistant_memaccess) {                                      dbe_on_nonexistant_memaccess &&
529                                        !no_exceptions) {
530                                          if (paddr >= mem->physical_max &&                                          if (paddr >= mem->physical_max &&
531                                              paddr < mem->physical_max+1048576)                                              paddr < mem->physical_max+1048576)
532                                                  mips_cpu_exception(cpu,                                                  mips_cpu_exception(cpu,
# Line 429  have_paddr: Line 546  have_paddr:
546  #endif  /*  ifndef MEM_USERLAND  */  #endif  /*  ifndef MEM_USERLAND  */
547    
548    
 no_exception_access:  
   
549          /*          /*
550           *  Uncached access:           *  Uncached access:
551           */           */
# Line 443  no_exception_access: Line 558  no_exception_access:
558    
559          offset = paddr & ((1 << BITS_PER_MEMBLOCK) - 1);          offset = paddr & ((1 << BITS_PER_MEMBLOCK) - 1);
560    
561  #ifdef BINTRANS          if (cpu->update_translation_table != NULL && !bintrans_device_danger)
562          if (bintrans_cached)                  cpu->update_translation_table(cpu, vaddr & ~offset_mask,
563                  update_translation_table(cpu, vaddr & ~0xfff,                      memblock + (offset & ~offset_mask),
                     memblock + (offset & ~0xfff),  
564  #if 0  #if 0
565                      cache == CACHE_INSTRUCTION?                      cache == CACHE_INSTRUCTION?
566                          (writeflag == MEM_WRITE? 1 : 0)                          (writeflag == MEM_WRITE? 1 : 0)
# Line 454  no_exception_access: Line 568  no_exception_access:
568  #else  #else
569                      writeflag == MEM_WRITE? 1 : 0,                      writeflag == MEM_WRITE? 1 : 0,
570  #endif  #endif
571                      paddr & ~0xfff);                      paddr & ~offset_mask);
 #endif  
572    
573          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
574                  if (len == sizeof(uint32_t) && (offset & 3)==0)                  /*  Ugly optimization, but it works:  */
575                    if (len == sizeof(uint32_t) && (offset & 3)==0
576                        && ((size_t)data&3)==0)
577                          *(uint32_t *)(memblock + offset) = *(uint32_t *)data;                          *(uint32_t *)(memblock + offset) = *(uint32_t *)data;
578                  else if (len == sizeof(uint8_t))                  else if (len == sizeof(uint8_t))
579                          *(uint8_t *)(memblock + offset) = *(uint8_t *)data;                          *(uint8_t *)(memblock + offset) = *(uint8_t *)data;
580                  else                  else
581                          memcpy(memblock + offset, data, len);                          memcpy(memblock + offset, data, len);
582          } else {          } else {
583                  if (len == sizeof(uint32_t) && (offset & 3)==0)                  /*  Ugly optimization, but it works:  */
584                    if (len == sizeof(uint32_t) && (offset & 3)==0
585                        && ((size_t)data&3)==0)
586                          *(uint32_t *)data = *(uint32_t *)(memblock + offset);                          *(uint32_t *)data = *(uint32_t *)(memblock + offset);
587                  else if (len == sizeof(uint8_t))                  else if (len == sizeof(uint8_t))
588                          *(uint8_t *)data = *(uint8_t *)(memblock + offset);                          *(uint8_t *)data = *(uint8_t *)(memblock + offset);
589                  else                  else
590                          memcpy(data, memblock + offset, len);                          memcpy(data, memblock + offset, len);
591    
592    #ifdef MEM_MIPS
593                  if (cache == CACHE_INSTRUCTION) {                  if (cache == CACHE_INSTRUCTION) {
594                          cpu->cd.mips.pc_last_host_4k_page = memblock                          cpu->cd.mips.pc_last_host_4k_page = memblock
595                              + (offset & ~0xfff);                              + (offset & ~offset_mask);
 #ifdef BINTRANS  
596                          if (bintrans_cached) {                          if (bintrans_cached) {
597                                  cpu->cd.mips.pc_bintrans_host_4kpage =                                  cpu->cd.mips.pc_bintrans_host_4kpage =
598                                      cpu->cd.mips.pc_last_host_4k_page;                                      cpu->cd.mips.pc_last_host_4k_page;
599                          }                          }
 #endif  
600                  }                  }
601    #endif  /*  MIPS  */
602          }          }
603    
604    

Legend:
Removed from v.2  
changed lines
  Added in v.12

  ViewVC Help
Powered by ViewVC 1.1.26