25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: memory_rw.c,v 1.10 2005/03/01 08:23:55 debug Exp $ |
* $Id: memory_rw.c,v 1.16 2005/04/19 01:24:35 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 |
* |
* |
76 |
unsigned char *memblock; |
unsigned char *memblock; |
77 |
#ifdef BINTRANS |
#ifdef BINTRANS |
78 |
int bintrans_cached = cpu->machine->bintrans_enable; |
int bintrans_cached = cpu->machine->bintrans_enable; |
79 |
|
int bintrans_device_danger = 0; |
80 |
#endif |
#endif |
81 |
no_exceptions = cache_flags & NO_EXCEPTIONS; |
no_exceptions = cache_flags & NO_EXCEPTIONS; |
82 |
cache = cache_flags & CACHE_FLAGS_MASK; |
cache = cache_flags & CACHE_FLAGS_MASK; |
86 |
vaddr &= 0xffffffff; |
vaddr &= 0xffffffff; |
87 |
#endif |
#endif |
88 |
|
|
89 |
|
#ifdef MEM_X86 |
90 |
|
if (cpu->cd.x86.bits == 32) { |
91 |
|
if ((vaddr >> 32) == 0xffffffff) |
92 |
|
vaddr &= 0xffffffff; |
93 |
|
|
94 |
|
/* TODO: Actual address translation */ |
95 |
|
if ((vaddr >> 32) == 0) { |
96 |
|
vaddr &= 0x0fffffff; |
97 |
|
|
98 |
|
if (cpu->cd.x86.mode == 16) { |
99 |
|
vaddr = (cpu->cd.x86.cursegment<<4) + |
100 |
|
(vaddr & 0xffff); |
101 |
|
/* TODO: A20 stuff */ |
102 |
|
if ((vaddr & 0xffff) + len > 0x10000) { |
103 |
|
fatal("x86 memory access crossing" |
104 |
|
" segment boundary: TODO\n"); |
105 |
|
cpu->running = 0; |
106 |
|
return 0; |
107 |
|
} |
108 |
|
} |
109 |
|
} |
110 |
|
} |
111 |
|
#endif |
112 |
|
|
113 |
#ifdef MEM_URISC |
#ifdef MEM_URISC |
114 |
{ |
{ |
115 |
uint64_t mask = (uint64_t) -1; |
uint64_t mask = (uint64_t) -1; |
189 |
#endif /* ifndef MEM_USERLAND */ |
#endif /* ifndef MEM_USERLAND */ |
190 |
|
|
191 |
|
|
192 |
|
#if defined(MEM_MIPS) || defined(MEM_USERLAND) |
193 |
have_paddr: |
have_paddr: |
194 |
|
#endif |
195 |
|
|
196 |
|
|
197 |
#ifdef MEM_MIPS |
#ifdef MEM_MIPS |
225 |
uint64_t orig_paddr = paddr; |
uint64_t orig_paddr = paddr; |
226 |
#endif |
#endif |
227 |
int i, start, res; |
int i, start, res; |
228 |
|
|
229 |
|
#ifdef BINTRANS |
230 |
|
/* |
231 |
|
* Really really slow, but unfortunately necessary. This is |
232 |
|
* to avoid the folowing scenario: |
233 |
|
* |
234 |
|
* a) offsets 0x000..0x123 are normal memory |
235 |
|
* b) offsets 0x124..0x777 are a device |
236 |
|
* |
237 |
|
* 1) a read is done from offset 0x100. the page is |
238 |
|
* added to the bintrans system as a "RAM" page |
239 |
|
* 2) a bintranslated read is done from offset 0x200, |
240 |
|
* which should access the device, but since the |
241 |
|
* entire page is added, it will access non-existant |
242 |
|
* RAM instead, without warning. |
243 |
|
* |
244 |
|
* Setting bintrans_device_danger = 1 on accesses which are |
245 |
|
* on _any_ offset on pages that are device mapped avoids |
246 |
|
* this problem, but it is probably not very fast. |
247 |
|
*/ |
248 |
|
if (bintrans_cached) { |
249 |
|
for (i=0; i<mem->n_mmapped_devices; i++) |
250 |
|
if (paddr >= (mem->dev_baseaddr[i] & ~0xfff) && |
251 |
|
paddr <= ((mem->dev_baseaddr[i] + |
252 |
|
mem->dev_length[i] - 1) | 0xfff)) { |
253 |
|
bintrans_device_danger = 1; |
254 |
|
break; |
255 |
|
} |
256 |
|
} |
257 |
|
#endif |
258 |
|
|
259 |
i = start = mem->last_accessed_device; |
i = start = mem->last_accessed_device; |
260 |
|
|
261 |
/* Scan through all devices: */ |
/* Scan through all devices: */ |
502 |
offset = paddr & ((1 << BITS_PER_MEMBLOCK) - 1); |
offset = paddr & ((1 << BITS_PER_MEMBLOCK) - 1); |
503 |
|
|
504 |
#ifdef BINTRANS |
#ifdef BINTRANS |
505 |
if (bintrans_cached) |
if (bintrans_cached && !bintrans_device_danger) |
506 |
update_translation_table(cpu, vaddr & ~0xfff, |
update_translation_table(cpu, vaddr & ~0xfff, |
507 |
memblock + (offset & ~0xfff), |
memblock + (offset & ~0xfff), |
508 |
#if 0 |
#if 0 |