34 #include <sys/types.h> 61 len &= ~MEM_PCI_LITTLE_ENDIAN;
67 for (i=0; i<len; i++) {
72 for (i=len-1; i>=0; i--) {
95 len &= ~MEM_PCI_LITTLE_ENDIAN;
100 for (i=0; i<len; i++) {
105 for (i=0; i<len; i++) {
106 buf[len - 1 - i] = data & 255;
120 void *p = mmap(NULL, s, PROT_READ | PROT_WRITE,
121 MAP_ANON | MAP_PRIVATE, -1, 0);
125 fprintf(stderr,
"zeroed_alloc(): mmap() failed. This should" 126 " not usually happen. If you can reproduce this, then" 127 " please contact me with details about your run-time" 156 memset(mem, 0,
sizeof(
struct memory));
159 if (bits_per_pagetable + bits_per_memblock != max_bits) {
160 fprintf(stderr,
"memory_new(): bits_per_pagetable and " 161 "bits_per_memblock mismatch\n");
168 s = entries_per_pagetable *
sizeof(
void *);
170 mem->
pagetable = (
unsigned char *) mmap(NULL, s,
171 PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
191 int min_string_length)
198 cpu->
memory_rw(cpu, mem, addr+cur_length,
200 if (c==
'\n' || c==
'\t' || c==
'\r' || (c>=
' ' && c<127)) {
202 if (cur_length >= min_string_length)
205 if (cur_length >= min_string_length)
221 char *buf,
int bufsize)
224 int output_index = 0;
225 unsigned char c, p=
'\0';
227 while (output_index < bufsize-1) {
231 buf[output_index] = c;
232 if (c>=
' ' && c<127) {
235 }
else if (c==
'\n' || c==
'\r' || c==
'\t') {
237 buf[output_index] =
'\\';
240 case '\n': p =
'n';
break;
241 case '\r': p =
'r';
break;
242 case '\t': p =
't';
break;
244 if (output_index < bufsize-1) {
245 buf[output_index] = p;
249 buf[output_index] =
'\0';
254 buf[bufsize-1] =
'\0';
265 void *extra, uint64_t *low, uint64_t *high)
268 int i, need_inval = 0;
295 for (s = *low; s <= *high;
340 uint64_t baseaddr, uint64_t len,
341 int (*
f)(
struct cpu *,
struct memory *,uint64_t,
unsigned char *,
343 void *extra,
int flags,
unsigned char *dyntrans_data)
353 if (i == 0 && baseaddr + len <= mem->
devices[i].baseaddr)
355 if (i > 0 && baseaddr + len <= mem->
devices[i].baseaddr &&
363 if (baseaddr + len <= mem->
devices[i].baseaddr)
368 fatal(
"\nERROR! \"%s\" collides with device %i (\"%s\")!\n",
375 fatal(
"INTERNAL ERROR\n");
381 debug(
"device at 0x%010" PRIx64
": %s", (uint64_t) baseaddr,
386 fatal(
"\nWARNING: Device dyntrans access, but unaligned" 387 " baseaddr 0x%" PRIx64
".\n", (uint64_t) baseaddr);
391 debug(
" (dyntrans %s)",
401 fatal(
"ERROR: the data pointer used for dyntrans " 402 "accesses must only be used once!\n");
403 fatal(
"(%p cannot be used by '%s'; already in use by '" 404 "%s')\n", dyntrans_data, device_name,
430 fatal(
"\nERROR: Device dyntrans access, but dyntrans_data" 435 if ((
size_t)dyntrans_data & (
sizeof(
void *) - 1)) {
436 fprintf(stderr,
"memory_device_register():" 437 " dyntrans_data not aligned correctly (%p)\n",
466 fatal(
"memory_device_remove(): invalid device number %i\n", i);
496 uint64_t paddr,
int writeflag)
502 unsigned char *hostptr;
505 entry = (paddr >> shrcount) & mask;
510 if (table[entry] == NULL) {
530 table[entry] = (
void *) mmap(NULL, alloclen,
531 PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
532 if (table[entry] == NULL) {
534 memset(table[entry], 0, alloclen);
538 hostptr = (
unsigned char *) table[entry];
547 #define UPDATE_CHECKSUM(value) { \ 548 internal_state -= 0x118c7771c0c0a77fULL; \ 549 internal_state = ((internal_state + (value)) << 7) ^ \ 550 (checksum >> 11) ^ ((checksum - (value)) << 3) ^ \ 551 (internal_state - checksum) ^ ((value) - internal_state); \ 552 checksum ^= internal_state; \ 565 uint64_t internal_state = 0x80624185376feff2ULL;
566 uint64_t checksum = 0xcb9a87d5c010072cULL;
571 for (entry=0; entry<=n_entries; entry++) {
572 uint64_t **table = (uint64_t **) mem->
pagetable;
573 uint64_t *memblock = table[entry];
575 if (memblock == NULL) {
580 for (i=0; i<len; i++)
595 int writeflag, uint64_t paddr, uint8_t *
data,
size_t len)
597 uint64_t offset, old_pc = cpu->
pc;
610 fatal(
"[ memory_rw(): %s ", writeflag?
"write":
"read");
614 debug(
"data={", writeflag);
618 debug(
"%s%02x", i?
",":
"", data[i]);
622 for (i=start2; i<len; i++)
623 debug(
"%s%02x", i?
",":
"", data[i]);
625 for (i=0; i<len; i++)
626 debug(
"%s%02x", i?
",":
"", data[i]);
630 fatal(
"paddr=0x%" PRIx64
" >= physical_max; pc=", paddr);
632 fatal(
"0x%08" PRIx32, (uint32_t) old_pc);
634 fatal(
"0x%016" PRIx64, (uint64_t) old_pc);
637 fatal(
" <%s> ]\n", symbol? symbol :
" no symbol ");
655 #define DUMP_MEM_STRING_MAX 45 660 unsigned char ch =
'\0';
662 cpu->
memory_rw(cpu, cpu->
mem, addr + i, &ch,
sizeof(ch),
666 if (ch >=
' ' && ch < 126)
681 if ((addr >> 32) == 0)
682 addr = (int64_t)(int32_t)
addr;
724 uint64_t *ptrp, uint64_t *addrp,
const char *s1,
const char *s2)
726 uint64_t ptr = *ptrp,
addr = *addrp;
729 ptr +=
sizeof(uint32_t);
735 ptr +=
sizeof(uint32_t);
754 unsigned char data[8];
755 if ((addr >> 32) == 0)
756 addr = (int64_t)(int32_t)
addr;
757 data[0] = (data64 >> 56) & 255;
758 data[1] = (data64 >> 48) & 255;
759 data[2] = (data64 >> 40) & 255;
760 data[3] = (data64 >> 32) & 255;
761 data[4] = (data64 >> 24) & 255;
762 data[5] = (data64 >> 16) & 255;
763 data[6] = (data64 >> 8) & 255;
764 data[7] = (data64) & 255;
766 int tmp = data[0]; data[0] = data[7]; data[7] = tmp;
767 tmp = data[1]; data[1] = data[6]; data[6] = tmp;
768 tmp = data[2]; data[2] = data[5]; data[5] = tmp;
769 tmp = data[3]; data[3] = data[4]; data[4] = tmp;
785 unsigned char data[4];
787 data[0] = (data32 >> 24) & 255;
788 data[1] = (data32 >> 16) & 255;
789 data[2] = (data32 >> 8) & 255;
790 data[3] = (data32) & 255;
792 int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
793 tmp = data[1]; data[1] = data[2]; data[2] = tmp;
809 unsigned char data[2];
811 data[0] = (data16 >> 8) & 255;
812 data[1] = (data16) & 255;
814 int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
831 if ((addr & (psize-1)) == 0) {
832 while (len >= psize) {
856 uint64_t
data,
int flag64)
858 uint64_t
addr = *addrp;
877 unsigned char data[8];
883 int tmp = data[0]; data[0] = data[7]; data[7] = tmp;
884 tmp = data[1]; data[1] = data[6]; data[6] = tmp;
885 tmp = data[2]; data[2] = data[5]; data[5] = tmp;
886 tmp = data[3]; data[3] = data[4]; data[4] = tmp;
890 ((uint64_t)data[0] << 56) + ((uint64_t)data[1] << 48) +
891 ((uint64_t)data[2] << 40) + ((uint64_t)data[3] << 32) +
892 ((uint64_t)data[4] << 24) + ((uint64_t)data[5] << 16) +
893 ((uint64_t)data[6] << 8) + (uint64_t)data[7];
904 unsigned char data[4];
910 int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
911 tmp = data[1]; data[1] = data[2]; data[2] = tmp;
914 return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
925 unsigned char data[2];
931 int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
934 return (data[0] << 8) + data[1];
946 unsigned char *
data, uint64_t data64)
948 data[0] = (data64 >> 56) & 255;
949 data[1] = (data64 >> 48) & 255;
950 data[2] = (data64 >> 40) & 255;
951 data[3] = (data64 >> 32) & 255;
952 data[4] = (data64 >> 24) & 255;
953 data[5] = (data64 >> 16) & 255;
954 data[6] = (data64 >> 8) & 255;
955 data[7] = (data64) & 255;
957 int tmp = data[0]; data[0] = data[7]; data[7] = tmp;
958 tmp = data[1]; data[1] = data[6]; data[6] = tmp;
959 tmp = data[2]; data[2] = data[5]; data[5] = tmp;
960 tmp = data[3]; data[3] = data[4]; data[4] = tmp;
974 unsigned char *
data, uint64_t data32)
976 data[0] = (data32 >> 24) & 255;
977 data[1] = (data32 >> 16) & 255;
978 data[2] = (data32 >> 8) & 255;
979 data[3] = (data32) & 255;
981 int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
982 tmp = data[1]; data[1] = data[2]; data[2] = tmp;
993 unsigned char *
data, uint16_t data16)
995 data[0] = (data16 >> 8) & 255;
996 data[1] = (data16) & 255;
998 int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
void dump_mem_string(struct cpu *cpu, uint64_t addr)
void fatal(const char *fmt,...)
int store_64bit_word(struct cpu *cpu, uint64_t addr, uint64_t data64)
#define JUST_MARK_AS_NON_WRITABLE
uint64_t memory_checksum(struct memory *mem)
void store_pointer_and_advance(struct cpu *cpu, uint64_t *addrp, uint64_t data, int flag64)
int store_16bit_word(struct cpu *cpu, uint64_t addr, uint64_t data16)
#define BITS_PER_PAGETABLE
void memory_device_remove(struct memory *mem, int i)
void store_byte(struct cpu *cpu, uint64_t addr, uint8_t data)
int(* f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *)
void f(int s, int func, int only_name)
uint32_t load_32bit_word(struct cpu *cpu, uint64_t addr)
uint16_t load_16bit_word(struct cpu *cpu, uint64_t addr)
int dev_dyntrans_alignment
void memory_device_dyntrans_access(struct cpu *cpu, struct memory *mem, void *extra, uint64_t *low, uint64_t *high)
void add_environment_string(struct cpu *cpu, const char *s, uint64_t *addr)
char * get_symbol_name(struct symbol_context *, uint64_t addr, uint64_t *offset)
uint64_t dyntrans_write_low
#define UPDATE_CHECKSUM(value)
unsigned char * memory_paddr_to_hostaddr(struct memory *mem, uint64_t paddr, int writeflag)
#define EMUL_LITTLE_ENDIAN
#define BITS_PER_MEMBLOCK
#define CHECK_ALLOCATION(ptr)
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
void add_environment_string_dual(struct cpu *cpu, uint64_t *ptrp, uint64_t *addrp, const char *s1, const char *s2)
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
struct memory * memory_new(uint64_t physical_max, int arch)
char * memory_conv_to_string(struct cpu *cpu, struct memory *mem, uint64_t addr, char *buf, int bufsize)
#define DM_DYNTRANS_WRITE_OK
uint64_t mmap_dev_maxaddr
void store_16bit_word_in_host(struct cpu *cpu, unsigned char *data, uint16_t data16)
int store_32bit_word(struct cpu *cpu, uint64_t addr, uint64_t data32)
int halt_on_nonexistant_memaccess
void memory_device_update_data(struct memory *mem, void *extra, unsigned char *data)
void COMBINE() strlen(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
void store_64bit_word_in_host(struct cpu *cpu, unsigned char *data, uint64_t data64)
void store_string(struct cpu *cpu, uint64_t addr, const char *s)
struct symbol_context symbol_context
unsigned char * dyntrans_data
uint64_t load_64bit_word(struct cpu *cpu, uint64_t addr)
void store_buf(struct cpu *cpu, uint64_t addr, const char *s, size_t len)
void * zeroed_alloc(size_t s)
uint64_t mmap_dev_minaddr
void memory_device_register(struct memory *mem, const char *device_name, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
void store_32bit_word_in_host(struct cpu *cpu, unsigned char *data, uint64_t data32)
struct memory_device * devices
addr & if(addr >=0x24 &&page !=NULL)
int memory_points_to_string(struct cpu *cpu, struct memory *mem, uint64_t addr, int min_string_length)
uint64_t dyntrans_write_high
#define DUMP_MEM_STRING_MAX
#define MEM_PCI_LITTLE_ENDIAN
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
void memory_warn_about_unimplemented_addr(struct cpu *cpu, struct memory *mem, int writeflag, uint64_t paddr, uint8_t *data, size_t len)
void(* invalidate_translation_caches)(struct cpu *, uint64_t paddr, int flags)