--- trunk/src/memory_rw.c 2007/10/08 16:19:01 16 +++ trunk/src/memory_rw.c 2007/10/08 16:19:11 18 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: memory_rw.c,v 1.65 2005/10/10 18:43:36 debug Exp $ + * $Id: memory_rw.c,v 1.75 2005/10/27 14:01:12 debug Exp $ * * Generic memory_rw(), with special hacks for specific CPU families. * @@ -310,8 +310,7 @@ */ for (i=0; in_mmapped_devices; i++) if (paddr >= (mem->dev_baseaddr[i] & ~offset_mask) && - paddr <= ((mem->dev_baseaddr[i] + - mem->dev_length[i] - 1) | offset_mask)) { + paddr <= ((mem->dev_endaddr[i]-1) | offset_mask)) { bintrans_device_danger = 1; break; } @@ -321,7 +320,7 @@ /* Scan through all devices: */ do { if (paddr >= mem->dev_baseaddr[i] && - paddr < mem->dev_baseaddr[i] + mem->dev_length[i]) { + paddr < mem->dev_endaddr[i]) { /* Found a device, let's access it: */ mem->last_accessed_device = i; @@ -332,8 +331,13 @@ if (cpu->update_translation_table != NULL && mem->dev_flags[i] & MEM_DYNTRANS_OK) { int wf = writeflag == MEM_WRITE? 1 : 0; + unsigned char *host_addr; - if (writeflag) { + if (!(mem->dev_flags[i] & + MEM_DYNTRANS_WRITE_OK)) + wf = 0; + + if (writeflag && wf) { if (paddr < mem-> dev_dyntrans_write_low[i]) mem-> @@ -348,14 +352,27 @@ offset_mask; } - if (!(mem->dev_flags[i] & - MEM_DYNTRANS_WRITE_OK)) - wf = 0; - + if (mem->dev_flags[i] & + MEM_EMULATED_RAM) { + /* MEM_WRITE to force the page + to be allocated, if it + wasn't already */ + uint64_t *pp = (uint64_t *) + mem->dev_dyntrans_data[i]; + uint64_t p = orig_paddr - *pp; + host_addr = + memory_paddr_to_hostaddr( + mem, p, MEM_WRITE) + + (p & ~offset_mask + & ((1 << + BITS_PER_MEMBLOCK) - 1)); + } else { + host_addr = + mem->dev_dyntrans_data[i] + + (paddr & ~offset_mask); + } cpu->update_translation_table(cpu, - vaddr & ~offset_mask, - mem->dev_dyntrans_data[i] + - (paddr & ~offset_mask), + vaddr & ~offset_mask, host_addr, wf, orig_paddr & ~offset_mask); } @@ -370,10 +387,12 @@ if (res == 0) res = -1; +#ifdef MEM_MIPS cpu->cd.mips.instruction_delay += ( (abs(res) - 1) * cpu->cd.mips.cpu_type.instrs_per_cycle ); #endif +#endif #ifndef MEM_X86 /* @@ -550,6 +569,14 @@ /* * Uncached access: + * + * 1) Translate the physical address to a host address. + * + * 2) Insert this virtual->physical->host translation into the + * fast translation arrays (using update_translation_table()). + * + * 3) If this was a Write, then invalidate any code translations + * in that page. */ memblock = memory_paddr_to_hostaddr(mem, paddr, writeflag); if (memblock == NULL) { @@ -561,18 +588,29 @@ offset = paddr & ((1 << BITS_PER_MEMBLOCK) - 1); if (cpu->update_translation_table != NULL && !bintrans_device_danger +#ifndef MEM_MIPS +/* && !(cache_flags & MEMORY_USER_ACCESS) */ +#ifndef MEM_USERLAND + && !(ok & MEMORY_NOT_FULL_PAGE) +#endif +#endif && !no_exceptions) cpu->update_translation_table(cpu, vaddr & ~offset_mask, memblock + (offset & ~offset_mask), + (cache_flags & MEMORY_USER_ACCESS) | +#ifndef MEM_MIPS + (cache == CACHE_INSTRUCTION? TLB_CODE : 0) | +#endif #if 0 - cache == CACHE_INSTRUCTION? + (cache == CACHE_INSTRUCTION? (writeflag == MEM_WRITE? 1 : 0) - : ok - 1, + : ok - 1), #else - writeflag == MEM_WRITE? 1 : 0, + (writeflag == MEM_WRITE? 1 : 0), #endif paddr & ~offset_mask); + /* Invalidate code translations for the page we are writing to. */ if (writeflag == MEM_WRITE && cpu->invalidate_code_translation != NULL) cpu->invalidate_code_translation(cpu, paddr, INVALIDATE_PADDR);