1 |
/* |
/* |
2 |
* Copyright (C) 2003-2006 Anders Gavare. All rights reserved. |
* Copyright (C) 2003-2007 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: memory.c,v 1.199 2006/10/24 09:32:48 debug Exp $ |
* $Id: memory.c,v 1.201 2006/12/30 13:30:52 debug Exp $ |
29 |
* |
* |
30 |
* Functions for handling the memory of an emulated machine. |
* Functions for handling the memory of an emulated machine. |
31 |
*/ |
*/ |
43 |
|
|
44 |
|
|
45 |
extern int verbose; |
extern int verbose; |
46 |
|
extern int quiet_mode; |
47 |
|
|
48 |
|
|
49 |
/* |
/* |
621 |
return checksum; |
return checksum; |
622 |
} |
} |
623 |
|
|
624 |
|
|
625 |
|
/* |
626 |
|
* memory_warn_about_unimplemented_addr(): |
627 |
|
* |
628 |
|
* Called from memory_rw whenever memory outside of the physical address space |
629 |
|
* is accessed (and quiet_mode isn't set). |
630 |
|
*/ |
631 |
|
void memory_warn_about_unimplemented_addr(struct cpu *cpu, struct memory *mem, |
632 |
|
int writeflag, uint64_t paddr, uint8_t *data, size_t len) |
633 |
|
{ |
634 |
|
uint64_t offset, old_pc = cpu->pc; |
635 |
|
char *symbol; |
636 |
|
|
637 |
|
/* |
638 |
|
* This allows guest OS kernels to probe memory a few KBs past the |
639 |
|
* end of memory, without giving too many warnings. |
640 |
|
*/ |
641 |
|
if (paddr < mem->physical_max + 0x40000) |
642 |
|
return; |
643 |
|
|
644 |
|
if (!cpu->machine->halt_on_nonexistant_memaccess && quiet_mode) |
645 |
|
return; |
646 |
|
|
647 |
|
fatal("[ memory_rw(): %s ", writeflag? "write":"read"); |
648 |
|
|
649 |
|
if (writeflag) { |
650 |
|
unsigned int i; |
651 |
|
debug("data={", writeflag); |
652 |
|
if (len > 16) { |
653 |
|
int start2 = len-16; |
654 |
|
for (i=0; i<16; i++) |
655 |
|
debug("%s%02x", i?",":"", data[i]); |
656 |
|
debug(" .. "); |
657 |
|
if (start2 < 16) |
658 |
|
start2 = 16; |
659 |
|
for (i=start2; i<len; i++) |
660 |
|
debug("%s%02x", i?",":"", data[i]); |
661 |
|
} else |
662 |
|
for (i=0; i<len; i++) |
663 |
|
debug("%s%02x", i?",":"", data[i]); |
664 |
|
debug("} "); |
665 |
|
} |
666 |
|
|
667 |
|
fatal("paddr=0x%llx >= physical_max; pc=", (long long)paddr); |
668 |
|
if (cpu->is_32bit) |
669 |
|
fatal("0x%08"PRIx32, (uint32_t) old_pc); |
670 |
|
else |
671 |
|
fatal("0x%016"PRIx64, (uint64_t) old_pc); |
672 |
|
symbol = get_symbol_name(&cpu->machine->symbol_context, |
673 |
|
old_pc, &offset); |
674 |
|
fatal(" <%s> ]\n", symbol? symbol : " no symbol "); |
675 |
|
|
676 |
|
if (cpu->machine->halt_on_nonexistant_memaccess) { |
677 |
|
/* TODO: Halt in a nicer way. Not possible with the |
678 |
|
current dyntrans system... */ |
679 |
|
exit(1); |
680 |
|
} |
681 |
|
} |
682 |
|
|