/[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 4 by dpavlin, Mon Oct 8 16:18:00 2007 UTC revision 10 by dpavlin, Mon Oct 8 16:18:27 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: memory_rw.c,v 1.16 2005/04/19 01:24:35 debug Exp $   *  $Id: memory_rw.c,v 1.38 2005/06/27 07:03:39 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 86  int MEMORY_RW(struct cpu *cpu, struct me Line 86  int MEMORY_RW(struct cpu *cpu, struct me
86                  vaddr &= 0xffffffff;                  vaddr &= 0xffffffff;
87  #endif  #endif
88    
89    #ifdef MEM_ARM
90            vaddr &= 0x3fffffff;
91    #endif
92    
93  #ifdef MEM_X86  #ifdef MEM_X86
94          if (cpu->cd.x86.bits == 32) {          /*  Real-mode wrap-around:  */
95                  if ((vaddr >> 32) == 0xffffffff)          if (REAL_MODE && !(cache_flags & PHYSICAL)) {
96                          vaddr &= 0xffffffff;                  if ((vaddr & 0xffff) + len > 0x10000) {
97                            /*  Do one byte at a time:  */
98                  /*  TODO: Actual address translation  */                          int res = 0, i;
99                  if ((vaddr >> 32) == 0) {                          for (i=0; i<len; i++)
100                          vaddr &= 0x0fffffff;                                  res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,
101                                        writeflag, cache_flags);
102                          if (cpu->cd.x86.mode == 16) {                          return res;
103                                  vaddr = (cpu->cd.x86.cursegment<<4) +                  }
104                                      (vaddr & 0xffff);          }
105                                  /*  TODO: A20 stuff  */  
106                                  if ((vaddr & 0xffff) + len > 0x10000) {          /*  Crossing a page boundary? Then do one byte at a time:  */
107                                          fatal("x86 memory access crossing"          if ((vaddr & 0xfff) + len > 0x1000 && !(cache_flags & PHYSICAL)
108                                              " segment boundary: TODO\n");              && cpu->cd.x86.cr[0] & X86_CR0_PG) {
109                                          cpu->running = 0;                  /*  For WRITES: Read ALL BYTES FIRST and write them back!!!
110                        Then do a write of all the new bytes. This is to make sure
111                        than both pages around the boundary are writable so we don't
112                        do a partial write.  */
113                    int res = 0, i;
114                    if (writeflag == MEM_WRITE) {
115                            unsigned char tmp;
116                            for (i=0; i<len; i++) {
117                                    res = MEMORY_RW(cpu, mem, vaddr+i, &tmp, 1,
118                                        MEM_READ, cache_flags);
119                                    if (!res)
120                                            return 0;
121                                    res = MEMORY_RW(cpu, mem, vaddr+i, &tmp, 1,
122                                        MEM_WRITE, cache_flags);
123                                    if (!res)
124                                            return 0;
125                            }
126                            for (i=0; i<len; i++) {
127                                    res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,
128                                        MEM_WRITE, cache_flags);
129                                    if (!res)
130                                            return 0;
131                            }
132                    } else {
133                            for (i=0; i<len; i++) {
134                                    /*  Do one byte at a time:  */
135                                    res = MEMORY_RW(cpu, mem, vaddr+i, &data[i], 1,
136                                        writeflag, cache_flags);
137                                    if (!res) {
138                                            if (cache == CACHE_INSTRUCTION) {
139                                                    fatal("FAILED instruction "
140                                                        "fetch across page boundar"
141                                                        "y: todo. vaddr=0x%08x\n",
142                                                        (int)vaddr);
143                                                    cpu->running = 0;
144                                            }
145                                          return 0;                                          return 0;
146                                  }                                  }
147                          }                          }
148                  }                  }
149                    return res;
150          }          }
151  #endif  #endif  /*  X86  */
152    
153  #ifdef MEM_URISC  #ifdef MEM_URISC
154          {          {
# Line 159  int MEMORY_RW(struct cpu *cpu, struct me Line 199  int MEMORY_RW(struct cpu *cpu, struct me
199                  ok = cpu->translate_address(cpu, vaddr, &paddr,                  ok = cpu->translate_address(cpu, vaddr, &paddr,
200                      (writeflag? FLAG_WRITEFLAG : 0) +                      (writeflag? FLAG_WRITEFLAG : 0) +
201                      (no_exceptions? FLAG_NOEXCEPTIONS : 0)                      (no_exceptions? FLAG_NOEXCEPTIONS : 0)
202    #ifdef MEM_X86
203                        + (cache_flags & NO_SEGMENTATION)
204    #endif
205                      + (cache==CACHE_INSTRUCTION? FLAG_INSTR : 0));                      + (cache==CACHE_INSTRUCTION? FLAG_INSTR : 0));
206                  /*  If the translation caused an exception, or was invalid in                  /*  If the translation caused an exception, or was invalid in
207                      some way, we simply return without doing the memory                      some way, we simply return without doing the memory
# Line 168  int MEMORY_RW(struct cpu *cpu, struct me Line 211  int MEMORY_RW(struct cpu *cpu, struct me
211          }          }
212    
213    
214    #ifdef MEM_X86
215            /*  DOS debugging :-)  */
216            if (!quiet_mode && !(cache_flags & PHYSICAL)) {
217                    if (paddr >= 0x400 && paddr <= 0x4ff)
218                            debug("{ PC BIOS DATA AREA: %s 0x%x }\n", writeflag ==
219                                MEM_WRITE? "writing to" : "reading from",
220                                (int)paddr);
221    #if 0
222                    if (paddr >= 0xf0000 && paddr <= 0xfffff)
223                            debug("{ BIOS ACCESS: %s 0x%x }\n",
224                                writeflag == MEM_WRITE? "writing to" :
225                                "reading from", (int)paddr);
226    #endif
227            }
228    #endif
229    
230  #ifdef MEM_MIPS  #ifdef MEM_MIPS
231          /*          /*
232           *  If correct cache emulation is enabled, and we need to simluate           *  If correct cache emulation is enabled, and we need to simluate
# Line 207  have_paddr: Line 266  have_paddr:
266  #endif  /*  MEM_MIPS  */  #endif  /*  MEM_MIPS  */
267    
268    
         if (!(cache_flags & PHYSICAL))  
                 if (no_exceptions)  
                         goto no_exception_access;  
   
269    
270  #ifndef MEM_USERLAND  #ifndef MEM_USERLAND
271          /*          /*
# Line 300  have_paddr: Line 355  have_paddr:
355                                  }                                  }
356  #endif  #endif
357    
358                                  res = mem->dev_f[i](cpu, mem, paddr, data, len,                                  res = 0;
359                                      writeflag, mem->dev_extra[i]);                                  if (!no_exceptions || (mem->dev_flags[i] &
360                                        MEM_READING_HAS_NO_SIDE_EFFECTS))
361                                            res = mem->dev_f[i](cpu, mem, paddr,
362                                                data, len, writeflag,
363                                                mem->dev_extra[i]);
364    
365  #ifdef ENABLE_INSTRUCTION_DELAYS  #ifdef ENABLE_INSTRUCTION_DELAYS
366                                  if (res == 0)                                  if (res == 0)
# Line 311  have_paddr: Line 370  have_paddr:
370                                      ( (abs(res) - 1) *                                      ( (abs(res) - 1) *
371                                       cpu->cd.mips.cpu_type.instrs_per_cycle );                                       cpu->cd.mips.cpu_type.instrs_per_cycle );
372  #endif  #endif
373    
374    #ifndef MEM_X86
375                                  /*                                  /*
376                                   *  If accessing the memory mapped device                                   *  If accessing the memory mapped device
377                                   *  failed, then return with a DBE exception.                                   *  failed, then return with a DBE exception.
378                                   */                                   */
379                                  if (res <= 0) {                                  if (res <= 0 && !no_exceptions) {
380                                          debug("%s device '%s' addr %08lx "                                          debug("%s device '%s' addr %08lx "
381                                              "failed\n", writeflag?                                              "failed\n", writeflag?
382                                              "writing to" : "reading from",                                              "writing to" : "reading from",
# Line 326  have_paddr: Line 387  have_paddr:
387  #endif  #endif
388                                          return MEMORY_ACCESS_FAILED;                                          return MEMORY_ACCESS_FAILED;
389                                  }                                  }
390    #endif
391                                  goto do_return_ok;                                  goto do_return_ok;
392                          }                          }
393    
# Line 390  have_paddr: Line 451  have_paddr:
451    
452          /*  Outside of physical RAM?  */          /*  Outside of physical RAM?  */
453          if (paddr >= mem->physical_max) {          if (paddr >= mem->physical_max) {
454                  if ((paddr & 0xffff000000ULL) == 0x1f000000) {  #ifdef MEM_MIPS
455                    if ((paddr & 0xffffc00000ULL) == 0x1fc00000) {
456                          /*  Ok, this is PROM stuff  */                          /*  Ok, this is PROM stuff  */
457                  } else if ((paddr & 0xfffff00000ULL) == 0x1ff00000) {                  } else if ((paddr & 0xfffff00000ULL) == 0x1ff00000) {
458                          /*  Sprite reads from this area of memory...  */                          /*  Sprite reads from this area of memory...  */
# Line 398  have_paddr: Line 460  have_paddr:
460                          if (writeflag == MEM_READ)                          if (writeflag == MEM_READ)
461                                  memset(data, 0, len);                                  memset(data, 0, len);
462                          goto do_return_ok;                          goto do_return_ok;
463                  } else {                  } else
464                          if (paddr >= mem->physical_max + 0 * 1024) {  #endif /* MIPS */
465                    {
466                            if (paddr >= mem->physical_max) {
467                                  char *symbol;                                  char *symbol;
468  #ifdef MEM_MIPS  #ifdef MEM_MIPS
469                                  uint64_t offset;                                  uint64_t offset;
470  #endif  #endif
471                                  if (!quiet_mode) {                                  /*  This allows for example OS kernels to probe
472                                        memory a few KBs past the end of memory,
473                                        without giving too many warnings.  */
474                                    if (!quiet_mode && paddr >=
475                                        mem->physical_max + 0x40000) {
476                                          fatal("[ memory_rw(): writeflag=%i ",                                          fatal("[ memory_rw(): writeflag=%i ",
477                                              writeflag);                                              writeflag);
478                                          if (writeflag) {                                          if (writeflag) {
# Line 458  have_paddr: Line 526  have_paddr:
526                          }                          }
527    
528                          if (writeflag == MEM_READ) {                          if (writeflag == MEM_READ) {
529    #ifdef MEM_X86
530                                    /*  Reading non-existant memory on x86:  */
531                                    memset(data, 0xff, len);
532    #else
533                                  /*  Return all zeroes? (Or 0xff? TODO)  */                                  /*  Return all zeroes? (Or 0xff? TODO)  */
534                                  memset(data, 0, len);                                  memset(data, 0, len);
535    #endif
536    
537  #ifdef MEM_MIPS  #ifdef MEM_MIPS
538                                  /*                                  /*
# Line 467  have_paddr: Line 540  have_paddr:
540                                   *  an exceptions on an illegal read:                                   *  an exceptions on an illegal read:
541                                   */                                   */
542                                  if (cache != CACHE_NONE && cpu->machine->                                  if (cache != CACHE_NONE && cpu->machine->
543                                      dbe_on_nonexistant_memaccess) {                                      dbe_on_nonexistant_memaccess &&
544                                        !no_exceptions) {
545                                          if (paddr >= mem->physical_max &&                                          if (paddr >= mem->physical_max &&
546                                              paddr < mem->physical_max+1048576)                                              paddr < mem->physical_max+1048576)
547                                                  mips_cpu_exception(cpu,                                                  mips_cpu_exception(cpu,
# Line 487  have_paddr: Line 561  have_paddr:
561  #endif  /*  ifndef MEM_USERLAND  */  #endif  /*  ifndef MEM_USERLAND  */
562    
563    
 no_exception_access:  
   
564          /*          /*
565           *  Uncached access:           *  Uncached access:
566           */           */
# Line 530  no_exception_access: Line 602  no_exception_access:
602                  else                  else
603                          memcpy(data, memblock + offset, len);                          memcpy(data, memblock + offset, len);
604    
605    #ifdef MEM_MIPS
606                  if (cache == CACHE_INSTRUCTION) {                  if (cache == CACHE_INSTRUCTION) {
607                          cpu->cd.mips.pc_last_host_4k_page = memblock                          cpu->cd.mips.pc_last_host_4k_page = memblock
608                              + (offset & ~0xfff);                              + (offset & ~0xfff);
# Line 540  no_exception_access: Line 613  no_exception_access:
613                          }                          }
614  #endif  #endif
615                  }                  }
616    #endif  /*  MIPS  */
617          }          }
618    
619    

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

  ViewVC Help
Powered by ViewVC 1.1.26