25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: memory_rw.c,v 1.87 2006/06/22 11:43:03 debug Exp $ |
* $Id: memory_rw.c,v 1.93 2006/07/14 16:33:27 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 |
* |
* |
151 |
paddr = vaddr & 0x7fffffff; |
paddr = vaddr & 0x7fffffff; |
152 |
#endif |
#endif |
153 |
#else /* !MEM_USERLAND */ |
#else /* !MEM_USERLAND */ |
154 |
if (misc_flags & PHYSICAL || cpu->translate_address == NULL) { |
if (misc_flags & PHYSICAL || cpu->translate_v2p == NULL) { |
155 |
paddr = vaddr; |
paddr = vaddr; |
156 |
} else { |
} else { |
157 |
ok = cpu->translate_address(cpu, vaddr, &paddr, |
ok = cpu->translate_v2p(cpu, vaddr, &paddr, |
158 |
(writeflag? FLAG_WRITEFLAG : 0) + |
(writeflag? FLAG_WRITEFLAG : 0) + |
159 |
(no_exceptions? FLAG_NOEXCEPTIONS : 0) |
(no_exceptions? FLAG_NOEXCEPTIONS : 0) |
160 |
#ifdef MEM_X86 |
#ifdef MEM_X86 |
280 |
uint64_t p = orig_paddr - *pp; |
uint64_t p = orig_paddr - *pp; |
281 |
host_addr = |
host_addr = |
282 |
memory_paddr_to_hostaddr( |
memory_paddr_to_hostaddr( |
283 |
mem, p, MEM_WRITE) |
mem, p & ~offset_mask, |
284 |
+ (p & ~offset_mask |
MEM_WRITE); |
|
& ((1 << |
|
|
BITS_PER_MEMBLOCK) - 1)); |
|
285 |
} else { |
} else { |
286 |
host_addr = |
host_addr = |
287 |
mem->dev_dyntrans_data[i] + |
mem->dev_dyntrans_data[i] + |
288 |
(paddr & ~offset_mask); |
(paddr & ~offset_mask); |
289 |
} |
} |
290 |
|
|
291 |
cpu->update_translation_table(cpu, |
cpu->update_translation_table(cpu, |
292 |
vaddr & ~offset_mask, host_addr, |
vaddr & ~offset_mask, host_addr, |
293 |
wf, orig_paddr & ~offset_mask); |
wf, orig_paddr & ~offset_mask); |
468 |
* 3) If this was a Write, then invalidate any code translations |
* 3) If this was a Write, then invalidate any code translations |
469 |
* in that page. |
* in that page. |
470 |
*/ |
*/ |
471 |
memblock = memory_paddr_to_hostaddr(mem, paddr, writeflag); |
memblock = memory_paddr_to_hostaddr(mem, paddr & ~offset_mask, |
472 |
|
writeflag); |
473 |
if (memblock == NULL) { |
if (memblock == NULL) { |
474 |
if (writeflag == MEM_READ) |
if (writeflag == MEM_READ) |
475 |
memset(data, 0, len); |
memset(data, 0, len); |
476 |
goto do_return_ok; |
goto do_return_ok; |
477 |
} |
} |
478 |
|
|
479 |
offset = paddr & ((1 << BITS_PER_MEMBLOCK) - 1); |
offset = paddr & offset_mask; |
480 |
|
|
481 |
if (cpu->update_translation_table != NULL && !dyntrans_device_danger |
if (cpu->update_translation_table != NULL && !dyntrans_device_danger |
482 |
|
#ifdef MEM_MIPS |
483 |
|
/* Ugly hack for R2000/R3000 caches: */ |
484 |
|
&& (cpu->cd.mips.cpu_type.mmu_model != MMU3K || |
485 |
|
!(cpu->cd.mips.coproc[0]->reg[COP0_STATUS] & MIPS1_ISOL_CACHES)) |
486 |
|
#endif |
487 |
#ifndef MEM_MIPS |
#ifndef MEM_MIPS |
488 |
/* && !(misc_flags & MEMORY_USER_ACCESS) */ |
/* && !(misc_flags & MEMORY_USER_ACCESS) */ |
489 |
#ifndef MEM_USERLAND |
#ifndef MEM_USERLAND |
492 |
#endif |
#endif |
493 |
&& !no_exceptions) |
&& !no_exceptions) |
494 |
cpu->update_translation_table(cpu, vaddr & ~offset_mask, |
cpu->update_translation_table(cpu, vaddr & ~offset_mask, |
495 |
memblock + (offset & ~offset_mask), |
memblock, (misc_flags & MEMORY_USER_ACCESS) | |
|
(misc_flags & MEMORY_USER_ACCESS) | |
|
|
#ifndef MEM_MIPS |
|
|
(cache == CACHE_INSTRUCTION? TLB_CODE : 0) | |
|
|
#endif |
|
496 |
#if !defined(MEM_MIPS) && !defined(MEM_USERLAND) |
#if !defined(MEM_MIPS) && !defined(MEM_USERLAND) |
497 |
(cache == CACHE_INSTRUCTION? |
(cache == CACHE_INSTRUCTION? |
498 |
(writeflag == MEM_WRITE? 1 : 0) : ok - 1), |
(writeflag == MEM_WRITE? 1 : 0) : ok - 1), |
505 |
if (writeflag == MEM_WRITE && cpu->invalidate_code_translation != NULL) |
if (writeflag == MEM_WRITE && cpu->invalidate_code_translation != NULL) |
506 |
cpu->invalidate_code_translation(cpu, paddr, INVALIDATE_PADDR); |
cpu->invalidate_code_translation(cpu, paddr, INVALIDATE_PADDR); |
507 |
|
|
508 |
|
if ((paddr&((1<<BITS_PER_MEMBLOCK)-1)) + len > (1<<BITS_PER_MEMBLOCK)) { |
509 |
|
printf("Write over memblock boundary?\n"); |
510 |
|
exit(1); |
511 |
|
} |
512 |
|
|
513 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
514 |
/* Ugly optimization, but it works: */ |
/* Ugly optimization, but it works: */ |
515 |
if (len == sizeof(uint32_t) && (offset & 3)==0 |
if (len == sizeof(uint32_t) && (offset & 3)==0 |