1 /*
2  *  Copyright (C) 2003-2009  Anders Gavare.  All rights reserved.
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions are met:
6  *
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. The name of the author may not be used to endorse or promote products
13  *     derived from this software without specific prior written permission.
14  *
15  *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  *  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  *  SUCH DAMAGE.
26  *
27  *
28  *  Functions for handling the memory of an emulated machine.
29  */
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/mman.h>
36 
37 #include "cpu.h"
38 #include "machine.h"
39 #include "memory.h"
40 #include "misc.h"
41 
42 
43 extern int verbose;
44 extern int quiet_mode;
45 
46 
47 /*
48  *  memory_readmax64():
49  *
50  *  Read at most 64 bits of data from a buffer.  Length is given by
51  *  len, and the byte order by cpu->byte_order.
52  *
53  *  This function should not be called with cpu == NULL.
54  */
memory_readmax64(struct cpu * cpu,unsigned char * buf,int len)55 uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
56 {
57 	int i, byte_order = cpu->byte_order;
58 	uint64_t x = 0;
59 
60 	if (len & MEM_PCI_LITTLE_ENDIAN) {
61 		len &= ~MEM_PCI_LITTLE_ENDIAN;
62 		byte_order = EMUL_LITTLE_ENDIAN;
63 	}
64 
65 	/*  Switch byte order for incoming data, if necessary:  */
66 	if (byte_order == EMUL_BIG_ENDIAN)
67 		for (i=0; i<len; i++) {
68 			x <<= 8;
69 			x |= buf[i];
70 		}
71 	else
72 		for (i=len-1; i>=0; i--) {
73 			x <<= 8;
74 			x |= buf[i];
75 		}
76 
77 	return x;
78 }
79 
80 
81 /*
82  *  memory_writemax64():
83  *
84  *  Write at most 64 bits of data to a buffer.  Length is given by
85  *  len, and the byte order by cpu->byte_order.
86  *
87  *  This function should not be called with cpu == NULL.
88  */
memory_writemax64(struct cpu * cpu,unsigned char * buf,int len,uint64_t data)89 void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len,
90 	uint64_t data)
91 {
92 	int i, byte_order = cpu->byte_order;
93 
94 	if (len & MEM_PCI_LITTLE_ENDIAN) {
95 		len &= ~MEM_PCI_LITTLE_ENDIAN;
96 		byte_order = EMUL_LITTLE_ENDIAN;
97 	}
98 
99 	if (byte_order == EMUL_LITTLE_ENDIAN)
100 		for (i=0; i<len; i++) {
101 			buf[i] = data & 255;
102 			data >>= 8;
103 		}
104 	else
105 		for (i=0; i<len; i++) {
106 			buf[len - 1 - i] = data & 255;
107 			data >>= 8;
108 		}
109 }
110 
111 
112 /*
113  *  zeroed_alloc():
114  *
115  *  Allocates a block of memory using mmap(), and if that fails, try
116  *  malloc() + memset(). The returned memory block contains only zeroes.
117  */
zeroed_alloc(size_t s)118 void *zeroed_alloc(size_t s)
119 {
120 	void *p = mmap(NULL, s, PROT_READ | PROT_WRITE,
121 	    MAP_ANON | MAP_PRIVATE, -1, 0);
122 
123 	if (p == NULL) {
124 #if 1
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"
128 		    " environment.\n");
129 		exit(1);
130 #else
131 		CHECK_ALLOCATION(p = malloc(s));
132 		memset(p, 0, s);
133 #endif
134 	}
135 
136 	return p;
137 }
138 
139 
140 /*
141  *  memory_new():
142  *
143  *  This function creates a new memory object. An emulated machine needs one
144  *  of these.
145  */
memory_new(uint64_t physical_max,int arch)146 struct memory *memory_new(uint64_t physical_max, int arch)
147 {
148 	struct memory *mem;
149 	int bits_per_pagetable = BITS_PER_PAGETABLE;
150 	int bits_per_memblock = BITS_PER_MEMBLOCK;
151 	int entries_per_pagetable = 1 << BITS_PER_PAGETABLE;
152 	int max_bits = MAX_BITS;
153 	size_t s;
154 
155 	CHECK_ALLOCATION(mem = (struct memory *) malloc(sizeof(struct memory)));
156 	memset(mem, 0, sizeof(struct memory));
157 
158 	/*  Check bits_per_pagetable and bits_per_memblock for sanity:  */
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");
162 		exit(1);
163 	}
164 
165 	mem->physical_max = physical_max;
166 	mem->dev_dyntrans_alignment = 4095;
167 
168 	s = entries_per_pagetable * sizeof(void *);
169 
170 	mem->pagetable = (unsigned char *) mmap(NULL, s,
171 	    PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
172 	if (mem->pagetable == NULL) {
173 		CHECK_ALLOCATION(mem->pagetable = malloc(s));
174 		memset(mem->pagetable, 0, s);
175 	}
176 
177 	mem->mmap_dev_minaddr = 0xffffffffffffffffULL;
178 	mem->mmap_dev_maxaddr = 0;
179 
180 	return mem;
181 }
182 
183 
184 /*
185  *  memory_points_to_string():
186  *
187  *  Returns 1 if there's something string-like in emulated memory at address
188  *  addr, otherwise 0.
189  */
memory_points_to_string(struct cpu * cpu,struct memory * mem,uint64_t addr,int min_string_length)190 int memory_points_to_string(struct cpu *cpu, struct memory *mem, uint64_t addr,
191 	int min_string_length)
192 {
193 	int cur_length = 0;
194 	unsigned char c;
195 
196 	for (;;) {
197 		c = '\0';
198 		cpu->memory_rw(cpu, mem, addr+cur_length,
199 		    &c, sizeof(c), MEM_READ, CACHE_NONE | NO_EXCEPTIONS);
200 		if (c=='\n' || c=='\t' || c=='\r' || (c>=' ' && c<127)) {
201 			cur_length ++;
202 			if (cur_length >= min_string_length)
203 				return 1;
204 		} else {
205 			if (cur_length >= min_string_length)
206 				return 1;
207 			else
208 				return 0;
209 		}
210 	}
211 }
212 
213 
214 /*
215  *  memory_conv_to_string():
216  *
217  *  Convert emulated memory contents to a string, placing it in a buffer
218  *  provided by the caller.
219  */
memory_conv_to_string(struct cpu * cpu,struct memory * mem,uint64_t addr,char * buf,int bufsize)220 char *memory_conv_to_string(struct cpu *cpu, struct memory *mem, uint64_t addr,
221 	char *buf, int bufsize)
222 {
223 	int len = 0;
224 	int output_index = 0;
225 	unsigned char c, p='\0';
226 
227 	while (output_index < bufsize-1) {
228 		c = '\0';
229 		cpu->memory_rw(cpu, mem, addr+len, &c, sizeof(c), MEM_READ,
230 		    CACHE_NONE | NO_EXCEPTIONS);
231 		buf[output_index] = c;
232 		if (c>=' ' && c<127) {
233 			len ++;
234 			output_index ++;
235 		} else if (c=='\n' || c=='\r' || c=='\t') {
236 			len ++;
237 			buf[output_index] = '\\';
238 			output_index ++;
239 			switch (c) {
240 			case '\n':	p = 'n'; break;
241 			case '\r':	p = 'r'; break;
242 			case '\t':	p = 't'; break;
243 			}
244 			if (output_index < bufsize-1) {
245 				buf[output_index] = p;
246 				output_index ++;
247 			}
248 		} else {
249 			buf[output_index] = '\0';
250 			return buf;
251 		}
252 	}
253 
254 	buf[bufsize-1] = '\0';
255 	return buf;
256 }
257 
258 
259 /*
260  *  memory_device_dyntrans_access():
261  *
262  *  Get the lowest and highest dyntrans access since last time.
263  */
memory_device_dyntrans_access(struct cpu * cpu,struct memory * mem,void * extra,uint64_t * low,uint64_t * high)264 void memory_device_dyntrans_access(struct cpu *cpu, struct memory *mem,
265 	void *extra, uint64_t *low, uint64_t *high)
266 {
267 	size_t s;
268 	int i, need_inval = 0;
269 
270 	/*  TODO: This is O(n), so it might be good to rewrite it some day.
271 	    For now, it will be enough, as long as this function is not
272 	    called too often.  */
273 
274 	for (i=0; i<mem->n_mmapped_devices; i++) {
275 		if (mem->devices[i].extra == extra &&
276 		    mem->devices[i].flags & DM_DYNTRANS_WRITE_OK &&
277 		    mem->devices[i].dyntrans_data != NULL) {
278 			if (mem->devices[i].dyntrans_write_low != (uint64_t) -1)
279 				need_inval = 1;
280 			if (low != NULL)
281 				*low = mem->devices[i].dyntrans_write_low;
282 			mem->devices[i].dyntrans_write_low = (uint64_t) -1;
283 
284 			if (high != NULL)
285 				*high = mem->devices[i].dyntrans_write_high;
286 			mem->devices[i].dyntrans_write_high = 0;
287 
288 			if (!need_inval)
289 				return;
290 
291 			/*  Invalidate any pages of this device that might
292 			    be in the dyntrans load/store cache, by marking
293 			    the pages read-only.  */
294 			if (cpu->invalidate_translation_caches != NULL) {
295 				for (s = *low; s <= *high;
296 				    s += cpu->machine->arch_pagesize)
297 					cpu->invalidate_translation_caches
298 					    (cpu, mem->devices[i].baseaddr + s,
299 					    JUST_MARK_AS_NON_WRITABLE
300 					    | INVALIDATE_PADDR);
301 			}
302 
303 			return;
304 		}
305 	}
306 }
307 
308 
309 /*
310  *  memory_device_update_data():
311  *
312  *  Update a device' dyntrans data pointer.
313  *
314  *  SUPER-IMPORTANT NOTE: Anyone who changes a dyntrans data pointer while
315  *  things are running also needs to invalidate all CPUs' address translation
316  *  caches!  Otherwise, these may contain old pointers to the old data.
317  */
memory_device_update_data(struct memory * mem,void * extra,unsigned char * data)318 void memory_device_update_data(struct memory *mem, void *extra,
319 	unsigned char *data)
320 {
321 	int i;
322 
323 	for (i=0; i<mem->n_mmapped_devices; i++) {
324 		if (mem->devices[i].extra != extra)
325 			continue;
326 
327 		mem->devices[i].dyntrans_data = data;
328 		mem->devices[i].dyntrans_write_low = (uint64_t)-1;
329 		mem->devices[i].dyntrans_write_high = 0;
330 	}
331 }
332 
333 
334 /*
335  *  memory_device_register():
336  *
337  *  Register a memory mapped device.
338  */
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)339 void memory_device_register(struct memory *mem, const char *device_name,
340 	uint64_t baseaddr, uint64_t len,
341 	int (*f)(struct cpu *,struct memory *,uint64_t,unsigned char *,
342 		size_t,int,void *),
343 	void *extra, int flags, unsigned char *dyntrans_data)
344 {
345 	int i, newi = 0;
346 
347 	/*
348 	 *  Figure out at which index to insert this device, and simultaneously
349 	 *  check for collisions:
350 	 */
351 	newi = -1;
352 	for (i=0; i<mem->n_mmapped_devices; i++) {
353 		if (i == 0 && baseaddr + len <= mem->devices[i].baseaddr)
354 			newi = i;
355 		if (i > 0 && baseaddr + len <= mem->devices[i].baseaddr &&
356 		    baseaddr >= mem->devices[i-1].endaddr)
357 			newi = i;
358 		if (i == mem->n_mmapped_devices - 1 &&
359 		    baseaddr >= mem->devices[i].endaddr)
360 			newi = i + 1;
361 
362 		/*  If this is not colliding with device i, then continue:  */
363 		if (baseaddr + len <= mem->devices[i].baseaddr)
364 			continue;
365 		if (baseaddr >= mem->devices[i].endaddr)
366 			continue;
367 
368 		fatal("\nERROR! \"%s\" collides with device %i (\"%s\")!\n",
369 		    device_name, i, mem->devices[i].name);
370 		exit(1);
371 	}
372 	if (mem->n_mmapped_devices == 0)
373 		newi = 0;
374 	if (newi == -1) {
375 		fatal("INTERNAL ERROR\n");
376 		exit(1);
377 	}
378 
379 	if (verbose >= 2) {
380 		/*  (40 bits of physical address is displayed)  */
381 		debug("device at 0x%010" PRIx64": %s", (uint64_t) baseaddr,
382 		    device_name);
383 
384 		if (flags & (DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK)
385 		    && (baseaddr & mem->dev_dyntrans_alignment) != 0) {
386 			fatal("\nWARNING: Device dyntrans access, but unaligned"
387 			    " baseaddr 0x%" PRIx64".\n", (uint64_t) baseaddr);
388 		}
389 
390 		if (flags & (DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK)) {
391 			debug(" (dyntrans %s)",
392 			    (flags & DM_DYNTRANS_WRITE_OK)? "R/W" : "R");
393 		}
394 		debug("\n");
395 	}
396 
397 	for (i=0; i<mem->n_mmapped_devices; i++) {
398 		if (dyntrans_data == mem->devices[i].dyntrans_data &&
399 		    mem->devices[i].flags&(DM_DYNTRANS_OK|DM_DYNTRANS_WRITE_OK)
400 		    && flags & (DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK)) {
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,
405 			    mem->devices[i].name);
406 			exit(1);
407 		}
408 	}
409 
410 	mem->n_mmapped_devices++;
411 
412 	CHECK_ALLOCATION(mem->devices = (struct memory_device *) realloc(mem->devices,
413 	    sizeof(struct memory_device) * mem->n_mmapped_devices));
414 
415 	/*  Make space for the new entry:  */
416 	if (newi + 1 != mem->n_mmapped_devices)
417 		memmove(&mem->devices[newi+1], &mem->devices[newi],
418 		    sizeof(struct memory_device)
419 		    * (mem->n_mmapped_devices - newi - 1));
420 
421 	CHECK_ALLOCATION(mem->devices[newi].name = strdup(device_name));
422 	mem->devices[newi].baseaddr = baseaddr;
423 	mem->devices[newi].endaddr = baseaddr + len;
424 	mem->devices[newi].length = len;
425 	mem->devices[newi].flags = flags;
426 	mem->devices[newi].dyntrans_data = dyntrans_data;
427 
428 	if (flags & (DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK)
429 	    && !(flags & DM_EMULATED_RAM) && dyntrans_data == NULL) {
430 		fatal("\nERROR: Device dyntrans access, but dyntrans_data"
431 		    " = NULL!\n");
432 		exit(1);
433 	}
434 
435 	if ((size_t)dyntrans_data & (sizeof(void *) - 1)) {
436 		fprintf(stderr, "memory_device_register():"
437 		    " dyntrans_data not aligned correctly (%p)\n",
438 		    dyntrans_data);
439 		abort();
440 	}
441 
442 	mem->devices[newi].dyntrans_write_low = (uint64_t)-1;
443 	mem->devices[newi].dyntrans_write_high = 0;
444 	mem->devices[newi].f = f;
445 	mem->devices[newi].extra = extra;
446 
447 	if (baseaddr < mem->mmap_dev_minaddr)
448 		mem->mmap_dev_minaddr = baseaddr & ~mem->dev_dyntrans_alignment;
449 	if (baseaddr + len > mem->mmap_dev_maxaddr)
450 		mem->mmap_dev_maxaddr = (((baseaddr + len) - 1) |
451 		    mem->dev_dyntrans_alignment) + 1;
452 
453 	if (newi < mem->last_accessed_device)
454 		mem->last_accessed_device ++;
455 }
456 
457 
458 /*
459  *  memory_device_remove():
460  *
461  *  Unregister a memory mapped device from a memory object.
462  */
memory_device_remove(struct memory * mem,int i)463 void memory_device_remove(struct memory *mem, int i)
464 {
465 	if (i < 0 || i >= mem->n_mmapped_devices) {
466 		fatal("memory_device_remove(): invalid device number %i\n", i);
467 		exit(1);
468 	}
469 
470 	mem->n_mmapped_devices --;
471 
472 	if (i == mem->n_mmapped_devices)
473 		return;
474 
475 	memmove(&mem->devices[i], &mem->devices[i+1],
476 	    sizeof(struct memory_device) * (mem->n_mmapped_devices - i));
477 
478 	if (i <= mem->last_accessed_device)
479 		mem->last_accessed_device --;
480 	if (mem->last_accessed_device < 0)
481 		mem->last_accessed_device = 0;
482 }
483 
484 
485 /*
486  *  memory_paddr_to_hostaddr():
487  *
488  *  Translate a physical address into a host address. The usual way to call
489  *  this function is to make sure that paddr is page aligned, which will result
490  *  in the host _page_ corresponding to that address.
491  *
492  *  Return value is a pointer to the address in the host, or NULL on failure.
493  *  On reads, a NULL return value should be interpreted as reading all zeroes.
494  */
memory_paddr_to_hostaddr(struct memory * mem,uint64_t paddr,int writeflag)495 unsigned char *memory_paddr_to_hostaddr(struct memory *mem,
496 	uint64_t paddr, int writeflag)
497 {
498 	void **table;
499 	int entry;
500 	const int mask = (1 << BITS_PER_PAGETABLE) - 1;
501 	const int shrcount = MAX_BITS - BITS_PER_PAGETABLE;
502 	unsigned char *hostptr;
503 
504 	table = (void **) mem->pagetable;
505 	entry = (paddr >> shrcount) & mask;
506 
507 	/*  printf("memory_paddr_to_hostaddr(): p=%16" PRIx64
508 	    " w=%i => entry=0x%x\n", (uint64_t) paddr, writeflag, entry);  */
509 
510 	if (table[entry] == NULL) {
511 		size_t alloclen;
512 
513 		/*
514 		 *  Special case:  reading from a nonexistant memblock
515 		 *  returns all zeroes, and doesn't allocate anything.
516 		 *  (If any intermediate pagetable is nonexistant, then
517 		 *  the same thing happens):
518 		 */
519 		if (writeflag == MEM_READ)
520 			return NULL;
521 
522 		/*  Allocate a memblock:  */
523 		alloclen = 1 << BITS_PER_MEMBLOCK;
524 
525 		/*  printf("  allocating for entry %i, len=%i\n",
526 		    entry, alloclen);  */
527 
528 		/*  Anonymous mmap() should return zero-filled memory,
529 		    try malloc + memset if mmap failed.  */
530 		table[entry] = (void *) mmap(NULL, alloclen,
531 		    PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
532 		if (table[entry] == NULL) {
533 			CHECK_ALLOCATION(table[entry] = malloc(alloclen));
534 			memset(table[entry], 0, alloclen);
535 		}
536 	}
537 
538 	hostptr = (unsigned char *) table[entry];
539 
540 	if (hostptr != NULL)
541 		hostptr += (paddr & ((1 << BITS_PER_MEMBLOCK) - 1));
542 
543 	return hostptr;
544 }
545 
546 
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;				\
553 	}
554 
555 
556 /*
557  *  memory_checksum():
558  *
559  *  Calculate a 64-bit checksum of everything in a struct memory. This is
560  *  useful for tracking down bugs; an old (presumably working) version of
561  *  the emulator can be compared to a newer (buggy) version.
562  */
memory_checksum(struct memory * mem)563 uint64_t memory_checksum(struct memory *mem)
564 {
565 	uint64_t internal_state = 0x80624185376feff2ULL;
566 	uint64_t checksum = 0xcb9a87d5c010072cULL;
567 	const size_t n_entries = (1 << BITS_PER_PAGETABLE) - 1;
568 	const size_t len = (1 << BITS_PER_MEMBLOCK) / sizeof(uint64_t);
569 	size_t entry, i;
570 
571 	for (entry=0; entry<=n_entries; entry++) {
572 		uint64_t **table = (uint64_t **) mem->pagetable;
573 		uint64_t *memblock = table[entry];
574 
575 		if (memblock == NULL) {
576 			UPDATE_CHECKSUM(0x1198ab7c8174a76fULL);
577 			continue;
578 		}
579 
580 		for (i=0; i<len; i++)
581 			UPDATE_CHECKSUM(memblock[i]);
582 	}
583 
584 	return checksum;
585 }
586 
587 
588 /*
589  *  memory_warn_about_unimplemented_addr():
590  *
591  *  Called from memory_rw whenever memory outside of the physical address space
592  *  is accessed (and quiet_mode isn't set).
593  */
memory_warn_about_unimplemented_addr(struct cpu * cpu,struct memory * mem,int writeflag,uint64_t paddr,uint8_t * data,size_t len)594 void memory_warn_about_unimplemented_addr(struct cpu *cpu, struct memory *mem,
595 	int writeflag, uint64_t paddr, uint8_t *data, size_t len)
596 {
597 	uint64_t offset, old_pc = cpu->pc;
598 	char *symbol;
599 
600 	/*
601 	 *  This allows guest OS kernels to probe memory a few KBs past the
602 	 *  end of memory, without giving too many warnings.
603 	 */
604 	if (paddr < mem->physical_max + 0x40000)
605 		return;
606 
607 	if (!cpu->machine->halt_on_nonexistant_memaccess && quiet_mode)
608 		return;
609 
610 	fatal("[ memory_rw(): %s ", writeflag? "write":"read");
611 
612 	if (writeflag) {
613 		unsigned int i;
614 		debug("data={", writeflag);
615 		if (len > 16) {
616 			int start2 = len-16;
617 			for (i=0; i<16; i++)
618 				debug("%s%02x", i?",":"", data[i]);
619 			debug(" .. ");
620 			if (start2 < 16)
621 				start2 = 16;
622 			for (i=start2; i<len; i++)
623 				debug("%s%02x", i?",":"", data[i]);
624 		} else
625 			for (i=0; i<len; i++)
626 				debug("%s%02x", i?",":"", data[i]);
627 		debug("} ");
628 	}
629 
630 	fatal("paddr=0x%" PRIx64" >= physical_max; pc=", paddr);
631 	if (cpu->is_32bit)
632 		fatal("0x%08" PRIx32, (uint32_t) old_pc);
633 	else
634 		fatal("0x%016" PRIx64, (uint64_t) old_pc);
635 	symbol = get_symbol_name(&cpu->machine->symbol_context,
636 	    old_pc, &offset);
637 	fatal(" <%s> ]\n", symbol? symbol : " no symbol ");
638 
639 	if (cpu->machine->halt_on_nonexistant_memaccess) {
640 		/*  TODO: Halt in a nicer way. Not possible with the
641 		    current dyntrans system...  */
642 		exit(1);
643 	}
644 }
645 
646 
647 /*
648  *  dump_mem_string():
649  *
650  *  Dump the contents of emulated RAM as readable text.  Bytes that aren't
651  *  readable are dumped in [xx] notation, where xx is in hexadecimal.
652  *  Dumping ends after DUMP_MEM_STRING_MAX bytes, or when a terminating
653  *  zero byte is found.
654  */
655 #define DUMP_MEM_STRING_MAX	45
dump_mem_string(struct cpu * cpu,uint64_t addr)656 void dump_mem_string(struct cpu *cpu, uint64_t addr)
657 {
658 	int i;
659 	for (i=0; i<DUMP_MEM_STRING_MAX; i++) {
660 		unsigned char ch = '\0';
661 
662 		cpu->memory_rw(cpu, cpu->mem, addr + i, &ch, sizeof(ch),
663 		    MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
664 		if (ch == '\0')
665 			return;
666 		if (ch >= ' ' && ch < 126)
667 			debug("%c", ch);
668 		else
669 			debug("[%02x]", ch);
670 	}
671 }
672 
673 
674 /*
675  *  store_byte():
676  *
677  *  Stores a byte in emulated ram. (Helper function.)
678  */
store_byte(struct cpu * cpu,uint64_t addr,uint8_t data)679 void store_byte(struct cpu *cpu, uint64_t addr, uint8_t data)
680 {
681 	if ((addr >> 32) == 0)
682 		addr = (int64_t)(int32_t)addr;
683 	cpu->memory_rw(cpu, cpu->mem,
684 	    addr, &data, sizeof(data), MEM_WRITE, CACHE_DATA);
685 }
686 
687 
688 /*
689  *  store_string():
690  *
691  *  Stores chars into emulated RAM until a zero byte (string terminating
692  *  character) is found. The zero byte is also copied.
693  *  (strcpy()-like helper function, host-RAM-to-emulated-RAM.)
694  */
store_string(struct cpu * cpu,uint64_t addr,const char * s)695 void store_string(struct cpu *cpu, uint64_t addr, const char *s)
696 {
697 	do {
698 		store_byte(cpu, addr++, *s);
699 	} while (*s++);
700 }
701 
702 
703 /*
704  *  add_environment_string():
705  *
706  *  Like store_string(), but advances the pointer afterwards. The most
707  *  obvious use is to place a number of strings (such as environment variable
708  *  strings) after one-another in emulated memory.
709  */
add_environment_string(struct cpu * cpu,const char * s,uint64_t * addr)710 void add_environment_string(struct cpu *cpu, const char *s, uint64_t *addr)
711 {
712 	store_string(cpu, *addr, s);
713 	(*addr) += strlen(s) + 1;
714 }
715 
716 
717 /*
718  *  add_environment_string_dual():
719  *
720  *  Add "dual" environment strings, one for the variable name and one for the
721  *  value, and update pointers afterwards.
722  */
add_environment_string_dual(struct cpu * cpu,uint64_t * ptrp,uint64_t * addrp,const char * s1,const char * s2)723 void add_environment_string_dual(struct cpu *cpu,
724 	uint64_t *ptrp, uint64_t *addrp, const char *s1, const char *s2)
725 {
726 	uint64_t ptr = *ptrp, addr = *addrp;
727 
728 	store_32bit_word(cpu, ptr, addr);
729 	ptr += sizeof(uint32_t);
730 	if (addr != 0) {
731 		store_string(cpu, addr, s1);
732 		addr += strlen(s1) + 1;
733 	}
734 	store_32bit_word(cpu, ptr, addr);
735 	ptr += sizeof(uint32_t);
736 	if (addr != 0) {
737 		store_string(cpu, addr, s2);
738 		addr += strlen(s2) + 1;
739 	}
740 
741 	*ptrp = ptr;
742 	*addrp = addr;
743 }
744 
745 
746 /*
747  *  store_64bit_word():
748  *
749  *  Stores a 64-bit word in emulated RAM.  Byte order is taken into account.
750  *  Helper function.
751  */
store_64bit_word(struct cpu * cpu,uint64_t addr,uint64_t data64)752 int store_64bit_word(struct cpu *cpu, uint64_t addr, uint64_t data64)
753 {
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;
765 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
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;
770 	}
771 	return cpu->memory_rw(cpu, cpu->mem,
772 	    addr, data, sizeof(data), MEM_WRITE, CACHE_DATA);
773 }
774 
775 
776 /*
777  *  store_32bit_word():
778  *
779  *  Stores a 32-bit word in emulated RAM.  Byte order is taken into account.
780  *  (This function takes a 64-bit word as argument, to suppress some
781  *  warnings, but only the lowest 32 bits are used.)
782  */
store_32bit_word(struct cpu * cpu,uint64_t addr,uint64_t data32)783 int store_32bit_word(struct cpu *cpu, uint64_t addr, uint64_t data32)
784 {
785 	unsigned char data[4];
786 
787 	data[0] = (data32 >> 24) & 255;
788 	data[1] = (data32 >> 16) & 255;
789 	data[2] = (data32 >> 8) & 255;
790 	data[3] = (data32) & 255;
791 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
792 		int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
793 		tmp = data[1]; data[1] = data[2]; data[2] = tmp;
794 	}
795 	return cpu->memory_rw(cpu, cpu->mem,
796 	    addr, data, sizeof(data), MEM_WRITE, CACHE_DATA);
797 }
798 
799 
800 /*
801  *  store_16bit_word():
802  *
803  *  Stores a 16-bit word in emulated RAM.  Byte order is taken into account.
804  *  (This function takes a 64-bit word as argument, to suppress some
805  *  warnings, but only the lowest 16 bits are used.)
806  */
store_16bit_word(struct cpu * cpu,uint64_t addr,uint64_t data16)807 int store_16bit_word(struct cpu *cpu, uint64_t addr, uint64_t data16)
808 {
809 	unsigned char data[2];
810 
811 	data[0] = (data16 >> 8) & 255;
812 	data[1] = (data16) & 255;
813 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
814 		int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
815 	}
816 	return cpu->memory_rw(cpu, cpu->mem,
817 	    addr, data, sizeof(data), MEM_WRITE, CACHE_DATA);
818 }
819 
820 
821 /*
822  *  store_buf():
823  *
824  *  memcpy()-like helper function, from host RAM to emulated RAM.
825  */
store_buf(struct cpu * cpu,uint64_t addr,const char * s,size_t len)826 void store_buf(struct cpu *cpu, uint64_t addr, const char *s, size_t len)
827 {
828 	size_t psize = 1024;	/*  1024 256 64 16 4 1  */
829 
830 	while (len != 0) {
831 		if ((addr & (psize-1)) == 0) {
832 			while (len >= psize) {
833 				cpu->memory_rw(cpu, cpu->mem, addr,
834 				    (unsigned char *)s, psize, MEM_WRITE,
835 				    CACHE_DATA);
836 				addr += psize;
837 				s += psize;
838 				len -= psize;
839 			}
840 		}
841 		psize >>= 2;
842 	}
843 
844 	while (len-- != 0)
845 		store_byte(cpu, addr++, *s++);
846 }
847 
848 
849 /*
850  *  store_pointer_and_advance():
851  *
852  *  Stores a 32-bit or 64-bit pointer in emulated RAM, and advances the
853  *  target address. (Useful for e.g. ARCBIOS environment initialization.)
854  */
store_pointer_and_advance(struct cpu * cpu,uint64_t * addrp,uint64_t data,int flag64)855 void store_pointer_and_advance(struct cpu *cpu, uint64_t *addrp,
856 	uint64_t data, int flag64)
857 {
858 	uint64_t addr = *addrp;
859 	if (flag64) {
860 		store_64bit_word(cpu, addr, data);
861 		addr += 8;
862 	} else {
863 		store_32bit_word(cpu, addr, data);
864 		addr += 4;
865 	}
866 	*addrp = addr;
867 }
868 
869 
870 /*
871  *  load_64bit_word():
872  *
873  *  Helper function. Emulated byte order is taken into account.
874  */
load_64bit_word(struct cpu * cpu,uint64_t addr)875 uint64_t load_64bit_word(struct cpu *cpu, uint64_t addr)
876 {
877 	unsigned char data[8];
878 
879 	cpu->memory_rw(cpu, cpu->mem,
880 	    addr, data, sizeof(data), MEM_READ, CACHE_DATA);
881 
882 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
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;
887 	}
888 
889 	return
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];
894 }
895 
896 
897 /*
898  *  load_32bit_word():
899  *
900  *  Helper function. Emulated byte order is taken into account.
901  */
load_32bit_word(struct cpu * cpu,uint64_t addr)902 uint32_t load_32bit_word(struct cpu *cpu, uint64_t addr)
903 {
904 	unsigned char data[4];
905 
906 	cpu->memory_rw(cpu, cpu->mem,
907 	    addr, data, sizeof(data), MEM_READ, CACHE_DATA);
908 
909 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
910 		int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
911 		tmp = data[1]; data[1] = data[2]; data[2] = tmp;
912 	}
913 
914 	return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
915 }
916 
917 
918 /*
919  *  load_16bit_word():
920  *
921  *  Helper function. Emulated byte order is taken into account.
922  */
load_16bit_word(struct cpu * cpu,uint64_t addr)923 uint16_t load_16bit_word(struct cpu *cpu, uint64_t addr)
924 {
925 	unsigned char data[2];
926 
927 	cpu->memory_rw(cpu, cpu->mem,
928 	    addr, data, sizeof(data), MEM_READ, CACHE_DATA);
929 
930 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
931 		int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
932 	}
933 
934 	return (data[0] << 8) + data[1];
935 }
936 
937 
938 /*
939  *  store_64bit_word_in_host():
940  *
941  *  Stores a 64-bit word in the _host's_ RAM.  Emulated byte order is taken
942  *  into account.  This is useful when building structs in the host's RAM
943  *  which will later be copied into emulated RAM.
944  */
store_64bit_word_in_host(struct cpu * cpu,unsigned char * data,uint64_t data64)945 void store_64bit_word_in_host(struct cpu *cpu,
946 	unsigned char *data, uint64_t data64)
947 {
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;
956 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
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;
961 	}
962 }
963 
964 
965 /*
966  *  store_32bit_word_in_host():
967  *
968  *  See comment for store_64bit_word_in_host().
969  *
970  *  (Note:  The data32 parameter is a uint64_t. This is done to suppress
971  *  some warnings.)
972  */
store_32bit_word_in_host(struct cpu * cpu,unsigned char * data,uint64_t data32)973 void store_32bit_word_in_host(struct cpu *cpu,
974 	unsigned char *data, uint64_t data32)
975 {
976 	data[0] = (data32 >> 24) & 255;
977 	data[1] = (data32 >> 16) & 255;
978 	data[2] = (data32 >> 8) & 255;
979 	data[3] = (data32) & 255;
980 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
981 		int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
982 		tmp = data[1]; data[1] = data[2]; data[2] = tmp;
983 	}
984 }
985 
986 
987 /*
988  *  store_16bit_word_in_host():
989  *
990  *  See comment for store_64bit_word_in_host().
991  */
store_16bit_word_in_host(struct cpu * cpu,unsigned char * data,uint16_t data16)992 void store_16bit_word_in_host(struct cpu *cpu,
993 	unsigned char *data, uint16_t data16)
994 {
995 	data[0] = (data16 >> 8) & 255;
996 	data[1] = (data16) & 255;
997 	if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
998 		int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
999 	}
1000 }
1001 
1002