/[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 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: memory_rw.c,v 1.80 2005/11/20 11:28:44 debug Exp $   *  $Id: memory_rw.c,v 1.82 2005/12/31 15:48:32 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 83  int MEMORY_RW(struct cpu *cpu, struct me Line 83  int MEMORY_RW(struct cpu *cpu, struct me
83  #ifdef MEM_MIPS  #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;          int dyntrans_device_danger = 0;
87    
88          no_exceptions = misc_flags & NO_EXCEPTIONS;          no_exceptions = misc_flags & NO_EXCEPTIONS;
89          cache = misc_flags & CACHE_FLAGS_MASK;          cache = misc_flags & CACHE_FLAGS_MASK;
# Line 93  int MEMORY_RW(struct cpu *cpu, struct me Line 93  int MEMORY_RW(struct cpu *cpu, struct me
93          if (REAL_MODE && !(misc_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;
97                            size_t i;
98                          for (i=0; i<len; i++)                          for (i=0; i<len; i++)
99                                  res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,                                  res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,
100                                      writeflag, misc_flags);                                      writeflag, misc_flags);
# Line 108  int MEMORY_RW(struct cpu *cpu, struct me Line 109  int MEMORY_RW(struct cpu *cpu, struct me
109                      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
110                      than both pages around the boundary are writable so we don't                      than both pages around the boundary are writable so we don't
111                      do a partial write.  */                      do a partial write.  */
112                  int res = 0, i;                  int res = 0;
113                    size_t i;
114                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
115                          unsigned char tmp;                          unsigned char tmp;
116                          for (i=0; i<len; i++) {                          for (i=0; i<len; i++) {
# Line 267  have_paddr: Line 269  have_paddr:
269          /*          /*
270           *  Memory mapped device?           *  Memory mapped device?
271           *           *
272           *  TODO: this is utterly slow.           *  TODO: if paddr < base, but len enough, then the device should
273           *  TODO2: if paddr<base, but len enough, then we should write           *  still be written to!
          *  to a device to  
274           */           */
275          if (paddr >= mem->mmap_dev_minaddr && paddr < mem->mmap_dev_maxaddr) {          if (paddr >= mem->mmap_dev_minaddr && paddr < mem->mmap_dev_maxaddr) {
276                  uint64_t orig_paddr = paddr;                  uint64_t orig_paddr = paddr;
277                  int i, start, res;                  int i, start, end, res;
278    
279                  /*                  /*
280                   *  Really really slow, but unfortunately necessary. This is                   *  Really really slow, but unfortunately necessary. This is
# Line 283  have_paddr: Line 284  have_paddr:
284                   *      b) offsets 0x124..0x777 are a device                   *      b) offsets 0x124..0x777 are a device
285                   *                   *
286                   *      1) a read is done from offset 0x100. the page is                   *      1) a read is done from offset 0x100. the page is
287                   *         added to the bintrans system as a "RAM" page                   *         added to the dyntrans system as a "RAM" page
288                   *      2) a bintranslated read is done from offset 0x200,                   *      2) a dyntranslated read is done from offset 0x200,
289                   *         which should access the device, but since the                   *         which should access the device, but since the
290                   *         entire page is added, it will access non-existant                   *         entire page is added, it will access non-existant
291                   *         RAM instead, without warning.                   *         RAM instead, without warning.
292                   *                   *
293                   *  Setting bintrans_device_danger = 1 on accesses which are                   *  Setting dyntrans_device_danger = 1 on accesses which are
294                   *  on _any_ offset on pages that are device mapped avoids                   *  on _any_ offset on pages that are device mapped avoids
295                   *  this problem, but it is probably not very fast.                   *  this problem, but it is probably not very fast.
296                     *
297                     *  TODO: Convert this into a quick (multi-level, 64-bit)
298                     *  address space lookup, to find dangerous pages.
299                   */                   */
300    #if 1
301                  for (i=0; i<mem->n_mmapped_devices; i++)                  for (i=0; i<mem->n_mmapped_devices; i++)
302                          if (paddr >= (mem->dev_baseaddr[i] & ~offset_mask) &&                          if (paddr >= (mem->dev_baseaddr[i] & ~offset_mask) &&
303                              paddr <= ((mem->dev_endaddr[i]-1) | offset_mask)) {                              paddr <= ((mem->dev_endaddr[i]-1) | offset_mask)) {
304                                  bintrans_device_danger = 1;                                  dyntrans_device_danger = 1;
305                                  break;                                  break;
306                          }                          }
307    #endif
308    
309                  i = start = mem->last_accessed_device;                  start = 0; end = mem->n_mmapped_devices - 1;
310                    i = mem->last_accessed_device;
311    
312                  /*  Scan through all devices:  */                  /*  Scan through all devices:  */
313                  do {                  do {
# Line 400  have_paddr: Line 407  have_paddr:
407                                  goto do_return_ok;                                  goto do_return_ok;
408                          }                          }
409    
410                          i ++;                          if (paddr < mem->dev_baseaddr[i])
411                          if (i == mem->n_mmapped_devices)                                  end = i - 1;
412                                  i = 0;                          if (paddr >= mem->dev_endaddr[i])
413                  } while (i != start);                                  start = i + 1;
414                            i = (start + end) >> 1;
415                    } while (start <= end);
416          }          }
417    
418    
# Line 569  have_paddr: Line 578  have_paddr:
578    
579          offset = paddr & ((1 << BITS_PER_MEMBLOCK) - 1);          offset = paddr & ((1 << BITS_PER_MEMBLOCK) - 1);
580    
581          if (cpu->update_translation_table != NULL && !bintrans_device_danger          if (cpu->update_translation_table != NULL && !dyntrans_device_danger
582  #ifndef MEM_MIPS  #ifndef MEM_MIPS
583  /*          && !(misc_flags & MEMORY_USER_ACCESS)  */  /*          && !(misc_flags & MEMORY_USER_ACCESS)  */
584  #ifndef MEM_USERLAND  #ifndef MEM_USERLAND

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

  ViewVC Help
Powered by ViewVC 1.1.26