25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: memory.c,v 1.190 2006/06/16 18:31:25 debug Exp $ |
* $Id: memory.c,v 1.192 2006/07/14 16:33:27 debug Exp $ |
29 |
* |
* |
30 |
* Functions for handling the memory of an emulated machine. |
* Functions for handling the memory of an emulated machine. |
31 |
*/ |
*/ |
313 |
|
|
314 |
|
|
315 |
/* |
/* |
316 |
|
* memory_device_update_data(): |
317 |
|
* |
318 |
|
* Update a device' dyntrans data pointer. |
319 |
|
* |
320 |
|
* SUPER-IMPORTANT NOTE: Anyone who changes a dyntrans data pointer while |
321 |
|
* things are running also needs to invalidate all CPUs' address translation |
322 |
|
* caches! Otherwise, these may contain old pointers to the old data. |
323 |
|
*/ |
324 |
|
void memory_device_update_data(struct memory *mem, void *extra, |
325 |
|
unsigned char *data) |
326 |
|
{ |
327 |
|
int i; |
328 |
|
|
329 |
|
for (i=0; i<mem->n_mmapped_devices; i++) { |
330 |
|
if (mem->dev_extra[i] != extra) |
331 |
|
continue; |
332 |
|
|
333 |
|
mem->dev_dyntrans_data[i] = data; |
334 |
|
mem->dev_dyntrans_write_low[i] = (uint64_t)-1; |
335 |
|
mem->dev_dyntrans_write_high[i] = 0; |
336 |
|
} |
337 |
|
} |
338 |
|
|
339 |
|
|
340 |
|
/* |
341 |
* memory_device_register(): |
* memory_device_register(): |
342 |
* |
* |
343 |
* Register a (memory mapped) device by adding it to the dev_* fields of a |
* Register a (memory mapped) device by adding it to the dev_* fields of a |
543 |
/* |
/* |
544 |
* memory_paddr_to_hostaddr(): |
* memory_paddr_to_hostaddr(): |
545 |
* |
* |
546 |
* Translate a physical address into a host address. |
* Translate a physical address into a host address. The usual way to call |
547 |
|
* this function is to make sure that paddr is page aligned, which will result |
548 |
|
* in the host _page_ corresponding to that address. |
549 |
* |
* |
550 |
* Return value is a pointer to a host memblock, or NULL on failure. |
* Return value is a pointer to the address in the host, or NULL on failure. |
551 |
* On reads, a NULL return value should be interpreted as reading all zeroes. |
* On reads, a NULL return value should be interpreted as reading all zeroes. |
552 |
*/ |
*/ |
553 |
unsigned char *memory_paddr_to_hostaddr(struct memory *mem, |
unsigned char *memory_paddr_to_hostaddr(struct memory *mem, |
557 |
int entry; |
int entry; |
558 |
const int mask = (1 << BITS_PER_PAGETABLE) - 1; |
const int mask = (1 << BITS_PER_PAGETABLE) - 1; |
559 |
const int shrcount = MAX_BITS - BITS_PER_PAGETABLE; |
const int shrcount = MAX_BITS - BITS_PER_PAGETABLE; |
560 |
|
unsigned char *hostptr; |
561 |
|
|
562 |
table = mem->pagetable; |
table = mem->pagetable; |
563 |
entry = (paddr >> shrcount) & mask; |
entry = (paddr >> shrcount) & mask; |
597 |
} |
} |
598 |
} |
} |
599 |
|
|
600 |
return (unsigned char *) table[entry]; |
hostptr = (unsigned char *) table[entry]; |
601 |
|
|
602 |
|
if (hostptr != NULL) |
603 |
|
hostptr += (paddr & ((1 << BITS_PER_MEMBLOCK) - 1)); |
604 |
|
|
605 |
|
return hostptr; |
606 |
} |
} |
607 |
|
|
608 |
|
|