memory.cc Source File
Back to the index.
Go to the documentation of this file.
34 #include <sys/types.h>
67 for (i=0; i<len; i++) {
72 for (i=len-1; i>=0; i--) {
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)
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);
622 for (i=start2; i<len; i++)
625 for (i=0; i<len; 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);
655 #define DUMP_MEM_STRING_MAX 45
660 unsigned char ch =
'\0';
666 if (ch >=
' ' && ch < 126)
681 if ((
addr >> 32) == 0)
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)
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;
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;
809 unsigned char data[2];
811 data[0] = (data16 >> 8) & 255;
812 data[1] = (data16) & 255;
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];
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];
925 unsigned char data[2];
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;
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;
993 unsigned char *
data, uint16_t data16)
995 data[0] = (data16 >> 8) & 255;
996 data[1] = (data16) & 255;
int store_16bit_word(struct cpu *cpu, uint64_t addr, uint64_t data16)
void f(int s, int func, int only_name)
uint64_t dyntrans_write_low
int store_64bit_word(struct cpu *cpu, uint64_t addr, uint64_t data64)
uint16_t load_16bit_word(struct cpu *cpu, uint64_t addr)
struct symbol_context symbol_context
void store_pointer_and_advance(struct cpu *cpu, uint64_t *addrp, uint64_t data, int flag64)
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
void store_byte(struct cpu *cpu, uint64_t addr, uint8_t data)
void dump_mem_string(struct cpu *cpu, uint64_t addr)
char * get_symbol_name(struct symbol_context *, uint64_t addr, uint64_t *offset)
uint32_t load_32bit_word(struct cpu *cpu, uint64_t addr)
void add_environment_string(struct cpu *cpu, const char *s, uint64_t *addr)
unsigned char * memory_paddr_to_hostaddr(struct memory *mem, uint64_t paddr, int writeflag)
addr & if(addr >=0x24 &&page !=NULL)
int(* f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *)
void memory_device_remove(struct memory *mem, int i)
uint64_t memory_checksum(struct memory *mem)
void add_environment_string_dual(struct cpu *cpu, uint64_t *ptrp, uint64_t *addrp, const char *s1, const char *s2)
void memory_device_dyntrans_access(struct cpu *cpu, struct memory *mem, void *extra, uint64_t *low, uint64_t *high)
struct memory_device * devices
#define DM_DYNTRANS_WRITE_OK
void COMBINE() strlen(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
void fatal(const char *fmt,...)
uint64_t mmap_dev_maxaddr
int halt_on_nonexistant_memaccess
uint64_t mmap_dev_minaddr
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
#define UPDATE_CHECKSUM(value)
void memory_device_update_data(struct memory *mem, void *extra, unsigned char *data)
void(* invalidate_translation_caches)(struct cpu *, uint64_t paddr, int flags)
#define BITS_PER_MEMBLOCK
unsigned char * dyntrans_data
void store_string(struct cpu *cpu, uint64_t addr, const char *s)
struct memory * memory_new(uint64_t physical_max, int arch)
void store_buf(struct cpu *cpu, uint64_t addr, const char *s, size_t len)
uint64_t dyntrans_write_high
#define BITS_PER_PAGETABLE
#define EMUL_LITTLE_ENDIAN
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)
char * memory_conv_to_string(struct cpu *cpu, struct memory *mem, uint64_t addr, char *buf, int bufsize)
uint64_t load_64bit_word(struct cpu *cpu, uint64_t addr)
void * zeroed_alloc(size_t s)
void store_32bit_word_in_host(struct cpu *cpu, unsigned char *data, uint64_t data32)
#define DUMP_MEM_STRING_MAX
void memory_warn_about_unimplemented_addr(struct cpu *cpu, struct memory *mem, int writeflag, uint64_t paddr, uint8_t *data, size_t len)
#define MEM_PCI_LITTLE_ENDIAN
int memory_points_to_string(struct cpu *cpu, struct memory *mem, uint64_t addr, int min_string_length)
int dev_dyntrans_alignment
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_64bit_word_in_host(struct cpu *cpu, unsigned char *data, uint64_t data64)
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
#define JUST_MARK_AS_NON_WRITABLE
#define CHECK_ALLOCATION(ptr)
Generated on Tue Mar 24 2020 14:04:48 for GXemul by
1.8.17