/[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 31 by dpavlin, Mon Oct 8 16:20:40 2007 UTC revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: memory_rw.c,v 1.95 2006/07/25 21:49:14 debug Exp $   *  $Id: memory_rw.c,v 1.97 2006/09/07 11:44:01 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 98  int MEMORY_RW(struct cpu *cpu, struct me Line 98  int MEMORY_RW(struct cpu *cpu, struct me
98          /*  Crossing a page boundary? Then do one byte at a time:  */          /*  Crossing a page boundary? Then do one byte at a time:  */
99          if ((vaddr & 0xfff) + len > 0x1000 && !(misc_flags & PHYSICAL)          if ((vaddr & 0xfff) + len > 0x1000 && !(misc_flags & PHYSICAL)
100              && cpu->cd.x86.cr[0] & X86_CR0_PG) {              && cpu->cd.x86.cr[0] & X86_CR0_PG) {
101                  /*  For WRITES: Read ALL BYTES FIRST and write them back!!!                  /*
102                      Then do a write of all the new bytes. This is to make sure                   *  For WRITES: Read ALL BYTES FIRST and write them back!!!
103                      than both pages around the boundary are writable so we don't                   *  Then do a write of all the new bytes. This is to make sure
104                      do a partial write.  */                   *  than both pages around the boundary are writable so that
105                     *  there is no "partial write" performed.
106                     */
107                  int res = 0;                  int res = 0;
108                  size_t i;                  size_t i;
109                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
# Line 164  int MEMORY_RW(struct cpu *cpu, struct me Line 166  int MEMORY_RW(struct cpu *cpu, struct me
166                      + (misc_flags & MEMORY_USER_ACCESS)                      + (misc_flags & MEMORY_USER_ACCESS)
167  #endif  #endif
168                      + (cache==CACHE_INSTRUCTION? FLAG_INSTR : 0));                      + (cache==CACHE_INSTRUCTION? FLAG_INSTR : 0));
169                  /*  If the translation caused an exception, or was invalid in  
170                      some way, we simply return without doing the memory                  /*
171                      access:  */                   *  If the translation caused an exception, or was invalid in
172                     *  some way, then simply return without doing the memory
173                     *  access:
174                     */
175                  if (!ok)                  if (!ok)
176                          return MEMORY_ACCESS_FAILED;                          return MEMORY_ACCESS_FAILED;
177          }          }
# Line 224  int MEMORY_RW(struct cpu *cpu, struct me Line 229  int MEMORY_RW(struct cpu *cpu, struct me
229                   */                   */
230  #if 1  #if 1
231                  for (i=0; i<mem->n_mmapped_devices; i++)                  for (i=0; i<mem->n_mmapped_devices; i++)
232                          if (paddr >= (mem->dev_baseaddr[i] & ~offset_mask) &&                          if (paddr >= (mem->devices[i].baseaddr & ~offset_mask)&&
233                              paddr <= ((mem->dev_endaddr[i]-1) | offset_mask)) {                              paddr <= ((mem->devices[i].endaddr-1)|offset_mask)){
234                                  dyntrans_device_danger = 1;                                  dyntrans_device_danger = 1;
235                                  break;                                  break;
236                          }                          }
# Line 236  int MEMORY_RW(struct cpu *cpu, struct me Line 241  int MEMORY_RW(struct cpu *cpu, struct me
241    
242                  /*  Scan through all devices:  */                  /*  Scan through all devices:  */
243                  do {                  do {
244                          if (paddr >= mem->dev_baseaddr[i] &&                          if (paddr >= mem->devices[i].baseaddr &&
245                              paddr < mem->dev_endaddr[i]) {                              paddr < mem->devices[i].endaddr) {
246                                  /*  Found a device, let's access it:  */                                  /*  Found a device, let's access it:  */
247                                  mem->last_accessed_device = i;                                  mem->last_accessed_device = i;
248    
249                                  paddr -= mem->dev_baseaddr[i];                                  paddr -= mem->devices[i].baseaddr;
250                                  if (paddr + len > mem->dev_length[i])                                  if (paddr + len > mem->devices[i].length)
251                                          len = mem->dev_length[i] - paddr;                                          len = mem->devices[i].length - paddr;
252    
253                                  if (cpu->update_translation_table != NULL &&                                  if (cpu->update_translation_table != NULL &&
254                                      !(ok & MEMORY_NOT_FULL_PAGE) &&                                      !(ok & MEMORY_NOT_FULL_PAGE) &&
255                                      mem->dev_flags[i] & DM_DYNTRANS_OK) {                                      mem->devices[i].flags & DM_DYNTRANS_OK) {
256                                          int wf = writeflag == MEM_WRITE? 1 : 0;                                          int wf = writeflag == MEM_WRITE? 1 : 0;
257                                          unsigned char *host_addr;                                          unsigned char *host_addr;
258    
259                                          if (!(mem->dev_flags[i] &                                          if (!(mem->devices[i].flags &
260                                              DM_DYNTRANS_WRITE_OK))                                              DM_DYNTRANS_WRITE_OK))
261                                                  wf = 0;                                                  wf = 0;
262    
263                                          if (writeflag && wf) {                                          if (writeflag && wf) {
264                                                  if (paddr < mem->                                                  if (paddr < mem->devices[i].
265                                                      dev_dyntrans_write_low[i])                                                      dyntrans_write_low)
266                                                          mem->                                                          mem->devices[i].
267                                                          dev_dyntrans_write_low                                                          dyntrans_write_low =
268                                                              [i] = paddr &                                                              paddr &~offset_mask;
269                                                              ~offset_mask;                                                  if (paddr >= mem->devices[i].
270                                                  if (paddr >= mem->                                                      dyntrans_write_high)
271                                                      dev_dyntrans_write_high[i])                                                          mem->devices[i].
272                                                          mem->                                                          dyntrans_write_high =
273                                                          dev_dyntrans_write_high                                                              paddr | offset_mask;
                                                             [i] = paddr |  
                                                             offset_mask;  
274                                          }                                          }
275    
276                                          if (mem->dev_flags[i] &                                          if (mem->devices[i].flags &
277                                              DM_EMULATED_RAM) {                                              DM_EMULATED_RAM) {
278                                                  /*  MEM_WRITE to force the page                                                  /*  MEM_WRITE to force the page
279                                                      to be allocated, if it                                                      to be allocated, if it
280                                                      wasn't already  */                                                      wasn't already  */
281                                                  uint64_t *pp = (uint64_t *)                                                  uint64_t *pp = (uint64_t *)mem->
282                                                      mem->dev_dyntrans_data[i];                                                      devices[i].dyntrans_data;
283                                                  uint64_t p = orig_paddr - *pp;                                                  uint64_t p = orig_paddr - *pp;
284                                                  host_addr =                                                  host_addr =
285                                                      memory_paddr_to_hostaddr(                                                      memory_paddr_to_hostaddr(
286                                                      mem, p & ~offset_mask,                                                      mem, p & ~offset_mask,
287                                                      MEM_WRITE);                                                      MEM_WRITE);
288                                          } else {                                          } else {
289                                                  host_addr =                                                  host_addr = mem->devices[i].
290                                                      mem->dev_dyntrans_data[i] +                                                      dyntrans_data +
291                                                      (paddr & ~offset_mask);                                                      (paddr & ~offset_mask);
292                                          }                                          }
293    
# Line 294  int MEMORY_RW(struct cpu *cpu, struct me Line 297  int MEMORY_RW(struct cpu *cpu, struct me
297                                  }                                  }
298    
299                                  res = 0;                                  res = 0;
300                                  if (!no_exceptions || (mem->dev_flags[i] &                                  if (!no_exceptions || (mem->devices[i].flags &
301                                      DM_READS_HAVE_NO_SIDE_EFFECTS))                                      DM_READS_HAVE_NO_SIDE_EFFECTS))
302                                          res = mem->dev_f[i](cpu, mem, paddr,                                          res = mem->devices[i].f(cpu, mem, paddr,
303                                              data, len, writeflag,                                              data, len, writeflag,
304                                              mem->dev_extra[i]);                                              mem->devices[i].extra);
305    
306                                  if (res == 0)                                  if (res == 0)
307                                          res = -1;                                          res = -1;
# Line 312  int MEMORY_RW(struct cpu *cpu, struct me Line 315  int MEMORY_RW(struct cpu *cpu, struct me
315                                          debug("%s device '%s' addr %08lx "                                          debug("%s device '%s' addr %08lx "
316                                              "failed\n", writeflag?                                              "failed\n", writeflag?
317                                              "writing to" : "reading from",                                              "writing to" : "reading from",
318                                              mem->dev_name[i], (long)paddr);                                              mem->devices[i].name, (long)paddr);
319  #ifdef MEM_MIPS  #ifdef MEM_MIPS
320                                          mips_cpu_exception(cpu, EXCEPTION_DBE,                                          mips_cpu_exception(cpu, EXCEPTION_DBE,
321                                              0, vaddr, 0, 0, 0, 0);                                              0, vaddr, 0, 0, 0, 0);
# Line 323  int MEMORY_RW(struct cpu *cpu, struct me Line 326  int MEMORY_RW(struct cpu *cpu, struct me
326                                  goto do_return_ok;                                  goto do_return_ok;
327                          }                          }
328    
329                          if (paddr < mem->dev_baseaddr[i])                          if (paddr < mem->devices[i].baseaddr)
330                                  end = i - 1;                                  end = i - 1;
331                          if (paddr >= mem->dev_endaddr[i])                          if (paddr >= mem->devices[i].endaddr)
332                                  start = i + 1;                                  start = i + 1;
333                          i = (start + end) >> 1;                          i = (start + end) >> 1;
334                  } while (start <= end);                  } while (start <= end);
# Line 501  int MEMORY_RW(struct cpu *cpu, struct me Line 504  int MEMORY_RW(struct cpu *cpu, struct me
504  #endif  #endif
505                      paddr & ~offset_mask);                      paddr & ~offset_mask);
506    
507          /*  Invalidate code translations for the page we are writing to.  */          /*
508             *  If writing, then invalidate code translations for the (physical)
509             *  page address:
510             */
511          if (writeflag == MEM_WRITE && cpu->invalidate_code_translation != NULL)          if (writeflag == MEM_WRITE && cpu->invalidate_code_translation != NULL)
512                  cpu->invalidate_code_translation(cpu, paddr, INVALIDATE_PADDR);                  cpu->invalidate_code_translation(cpu, paddr, INVALIDATE_PADDR);
513    

Legend:
Removed from v.31  
changed lines
  Added in v.32

  ViewVC Help
Powered by ViewVC 1.1.26