/[gxemul]/upstream/0.3.8/src/machine.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/0.3.8/src/machine.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Mon Oct 8 16:19:43 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 27237 byte(s)
0.3.8
1 /*
2 * Copyright (C) 2003-2006 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 * $Id: machine.c,v 1.664 2006/02/05 10:26:35 debug Exp $
29 */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <stdarg.h>
34 #ifdef SOLARIS
35 /* TODO: is this strings vs string separation really necessary? */
36 #include <strings.h>
37 #else
38 #include <string.h>
39 #endif
40 #include <time.h>
41 #include <unistd.h>
42
43 #include "arcbios.h"
44 #include "bus_isa.h"
45 #include "bus_pci.h"
46 #include "cpu.h"
47 #include "device.h"
48 #include "devices.h"
49 #include "diskimage.h"
50 #include "emul.h"
51 #include "machine.h"
52 #include "machine_interrupts.h"
53 #include "memory.h"
54 #include "misc.h"
55 #include "net.h"
56 #include "symbol.h"
57
58
59 /* See main.c: */
60 extern int quiet_mode;
61 extern int verbose;
62
63
64 /* This is initialized by machine_init(): */
65 struct machine_entry *first_machine_entry = NULL;
66
67
68 /*
69 * machine_new():
70 *
71 * Returns a reasonably initialized struct machine.
72 */
73 struct machine *machine_new(char *name, struct emul *emul)
74 {
75 struct machine *m;
76 m = malloc(sizeof(struct machine));
77 if (m == NULL) {
78 fprintf(stderr, "machine_new(): out of memory\n");
79 exit(1);
80 }
81
82 memset(m, 0, sizeof(struct machine));
83
84 /* Back pointer: */
85 m->emul = emul;
86
87 m->name = strdup(name);
88
89 /* Sane default values: */
90 m->serial_nr = 1;
91 m->machine_type = MACHINE_NONE;
92 m->machine_subtype = MACHINE_NONE;
93 #ifdef BINTRANS
94 m->bintrans_enable = 1;
95 m->old_bintrans_enable = 1;
96 #endif
97 m->arch_pagesize = 4096; /* Should be overriden in
98 emul.c for other pagesizes. */
99 m->dyntrans_alignment_check = 1;
100 m->prom_emulation = 1;
101 m->speed_tricks = 1;
102 m->byte_order_override = NO_BYTE_ORDER_OVERRIDE;
103 m->boot_kernel_filename = "";
104 m->boot_string_argument = NULL;
105 m->automatic_clock_adjustment = 1;
106 m->x11_scaledown = 1;
107 m->x11_scaleup = 1;
108 m->n_gfx_cards = 1;
109 m->dbe_on_nonexistant_memaccess = 1;
110 m->show_symbolic_register_names = 1;
111 m->bintrans_size = DEFAULT_BINTRANS_SIZE_IN_MB * 1048576;
112 symbol_init(&m->symbol_context);
113
114 return m;
115 }
116
117
118 /*
119 * machine_name_to_type():
120 *
121 * Take a type and a subtype as strings, and convert them into numeric
122 * values used internally throughout the code.
123 *
124 * Return value is 1 on success, 0 if there was no match.
125 * Also, any errors/warnings are printed using fatal()/debug().
126 */
127 int machine_name_to_type(char *stype, char *ssubtype,
128 int *type, int *subtype, int *arch)
129 {
130 struct machine_entry *me;
131 int i, j, k, nmatches = 0;
132
133 *type = MACHINE_NONE;
134 *subtype = 0;
135
136 /* Check stype, and optionally ssubtype: */
137 me = first_machine_entry;
138 while (me != NULL) {
139 for (i=0; i<me->n_aliases; i++)
140 if (strcasecmp(me->aliases[i], stype) == 0) {
141 /* Found a type: */
142 *type = me->machine_type;
143 *arch = me->arch;
144
145 if (me->n_subtypes == 0)
146 return 1;
147
148 /* Check for subtype: */
149 for (j=0; j<me->n_subtypes; j++)
150 for (k=0; k<me->subtype[j]->n_aliases;
151 k++)
152 if (strcasecmp(ssubtype,
153 me->subtype[j]->aliases[k]
154 ) == 0) {
155 *subtype = me->subtype[
156 j]->machine_subtype;
157 return 1;
158 }
159
160 fatal("Unknown subtype '%s' for emulation"
161 " '%s'\n", ssubtype, stype);
162 if (!ssubtype[0])
163 fatal("(Maybe you forgot the -e"
164 " command line option?)\n");
165 exit(1);
166 }
167
168 me = me->next;
169 }
170
171 /* Not found? Then just check ssubtype: */
172 me = first_machine_entry;
173 while (me != NULL) {
174 if (me->n_subtypes == 0) {
175 me = me->next;
176 continue;
177 }
178
179 /* Check for subtype: */
180 for (j=0; j<me->n_subtypes; j++)
181 for (k=0; k<me->subtype[j]->n_aliases; k++)
182 if (strcasecmp(ssubtype, me->subtype[j]->
183 aliases[k]) == 0) {
184 *type = me->machine_type;
185 *arch = me->arch;
186 *subtype = me->subtype[j]->
187 machine_subtype;
188 nmatches ++;
189 }
190
191 me = me->next;
192 }
193
194 switch (nmatches) {
195 case 0: fatal("\nSorry, emulation \"%s\"", stype);
196 if (ssubtype != NULL && ssubtype[0] != '\0')
197 fatal(" (subtype \"%s\")", ssubtype);
198 fatal(" is unknown.\n");
199 break;
200 case 1: return 1;
201 default:fatal("\nSorry, multiple matches for \"%s\"", stype);
202 if (ssubtype != NULL && ssubtype[0] != '\0')
203 fatal(" (subtype \"%s\")", ssubtype);
204 fatal(".\n");
205 }
206
207 *type = MACHINE_NONE;
208 *subtype = 0;
209
210 fatal("Use the -H command line option to get a list of "
211 "available types and subtypes.\n\n");
212
213 return 0;
214 }
215
216
217 /*
218 * machine_add_tickfunction():
219 *
220 * Adds a tick function (a function called every now and then, depending on
221 * clock cycle count) to a machine.
222 */
223 void machine_add_tickfunction(struct machine *machine, void (*func)
224 (struct cpu *, void *), void *extra, int clockshift)
225 {
226 int n = machine->n_tick_entries;
227
228 if (n >= MAX_TICK_FUNCTIONS) {
229 fprintf(stderr, "machine_add_tickfunction(): too "
230 "many tick functions\n");
231 exit(1);
232 }
233
234 /* Don't use too low clockshifts, that would be too inefficient
235 with bintrans. */
236 if (clockshift < N_SAFE_BINTRANS_LIMIT_SHIFT)
237 fatal("WARNING! clockshift = %i, less than "
238 "N_SAFE_BINTRANS_LIMIT_SHIFT (%i)\n",
239 clockshift, N_SAFE_BINTRANS_LIMIT_SHIFT);
240
241 machine->ticks_till_next[n] = 0;
242 machine->ticks_reset_value[n] = 1 << clockshift;
243 machine->tick_func[n] = func;
244 machine->tick_extra[n] = extra;
245
246 machine->n_tick_entries ++;
247 }
248
249
250 /*
251 * machine_bus_register():
252 *
253 * Registers a bus in a machine.
254 */
255 void machine_bus_register(struct machine *machine, char *busname,
256 void (*debug_dump)(void *), void *extra)
257 {
258 struct machine_bus *tmp, *last = NULL, *new;
259
260 new = zeroed_alloc(sizeof(struct machine_bus));
261 new->name = strdup(busname);
262 new->debug_dump = debug_dump;
263 new->extra = extra;
264
265 /* Register last in the bus list: */
266 tmp = machine->first_bus;
267 while (tmp != NULL) {
268 last = tmp;
269 tmp = tmp->next;
270 }
271
272 if (last == NULL)
273 machine->first_bus = new;
274 else
275 last->next = new;
276
277 machine->n_busses ++;
278 }
279
280
281 /*
282 * machine_dump_bus_info():
283 *
284 * Dumps info about registered busses.
285 */
286 void machine_dump_bus_info(struct machine *m)
287 {
288 struct machine_bus *bus = m->first_bus;
289 int iadd = DEBUG_INDENTATION;
290
291 if (m->n_busses > 0)
292 debug("busses:\n");
293 debug_indentation(iadd);
294 while (bus != NULL) {
295 bus->debug_dump(bus->extra);
296 bus = bus->next;
297 }
298 debug_indentation(-iadd);
299 }
300
301
302 /*
303 * machine_dumpinfo():
304 *
305 * Dumps info about a machine in some kind of readable format. (Used by
306 * the 'machine' debugger command.)
307 */
308 void machine_dumpinfo(struct machine *m)
309 {
310 int i;
311
312 debug("serial nr: %i", m->serial_nr);
313 if (m->nr_of_nics > 0)
314 debug(" (nr of NICs: %i)", m->nr_of_nics);
315 debug("\n");
316
317 debug("memory: %i MB", m->physical_ram_in_mb);
318 if (m->memory_offset_in_mb != 0)
319 debug(" (offset by %i MB)", m->memory_offset_in_mb);
320 if (m->random_mem_contents)
321 debug(", randomized contents");
322 if (m->dbe_on_nonexistant_memaccess)
323 debug(", dbe_on_nonexistant_memaccess");
324 debug("\n");
325
326 if (m->single_step_on_bad_addr)
327 debug("single-step on bad addresses\n");
328
329 if (m->arch == ARCH_MIPS) {
330 if (m->bintrans_enable)
331 debug("bintrans enabled (%i MB cache)\n",
332 (int) (m->bintrans_size / 1048576));
333 else
334 debug("bintrans disabled, other speedtricks %s\n",
335 m->speed_tricks? "enabled" : "disabled");
336 }
337
338 debug("clock: ");
339 if (m->automatic_clock_adjustment)
340 debug("adjusted automatically");
341 else
342 debug("fixed at %i Hz", m->emulated_hz);
343 debug("\n");
344
345 if (!m->prom_emulation)
346 debug("PROM emulation disabled\n");
347
348 for (i=0; i<m->ncpus; i++)
349 cpu_dumpinfo(m, m->cpus[i]);
350
351 if (m->ncpus > 1)
352 debug("Bootstrap cpu is nr %i\n", m->bootstrap_cpu);
353
354 if (m->slow_serial_interrupts_hack_for_linux)
355 debug("Using slow_serial_interrupts_hack_for_linux\n");
356
357 if (m->use_x11) {
358 debug("Using X11");
359 if (m->x11_scaledown > 1)
360 debug(", scaledown %i", m->x11_scaledown);
361 if (m->x11_scaleup > 1)
362 debug(", scaleup %i", m->x11_scaleup);
363 if (m->x11_n_display_names > 0) {
364 for (i=0; i<m->x11_n_display_names; i++) {
365 debug(i? ", " : " (");
366 debug("\"%s\"", m->x11_display_names[i]);
367 }
368 debug(")");
369 }
370 debug("\n");
371 }
372
373 machine_dump_bus_info(m);
374
375 diskimage_dump_info(m);
376
377 if (m->force_netboot)
378 debug("Forced netboot\n");
379 }
380
381
382 /*
383 * dump_mem_string():
384 *
385 * Dump the contents of emulated RAM as readable text. Bytes that aren't
386 * readable are dumped in [xx] notation, where xx is in hexadecimal.
387 * Dumping ends after DUMP_MEM_STRING_MAX bytes, or when a terminating
388 * zero byte is found.
389 */
390 #define DUMP_MEM_STRING_MAX 45
391 void dump_mem_string(struct cpu *cpu, uint64_t addr)
392 {
393 int i;
394 for (i=0; i<DUMP_MEM_STRING_MAX; i++) {
395 unsigned char ch = '\0';
396
397 cpu->memory_rw(cpu, cpu->mem, addr + i, &ch, sizeof(ch),
398 MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
399 if (ch == '\0')
400 return;
401 if (ch >= ' ' && ch < 126)
402 debug("%c", ch);
403 else
404 debug("[%02x]", ch);
405 }
406 }
407
408
409 /*
410 * store_byte():
411 *
412 * Stores a byte in emulated ram. (Helper function.)
413 */
414 void store_byte(struct cpu *cpu, uint64_t addr, uint8_t data)
415 {
416 if ((addr >> 32) == 0)
417 addr = (int64_t)(int32_t)addr;
418 cpu->memory_rw(cpu, cpu->mem,
419 addr, &data, sizeof(data), MEM_WRITE, CACHE_DATA);
420 }
421
422
423 /*
424 * store_string():
425 *
426 * Stores chars into emulated RAM until a zero byte (string terminating
427 * character) is found. The zero byte is also copied.
428 * (strcpy()-like helper function, host-RAM-to-emulated-RAM.)
429 */
430 void store_string(struct cpu *cpu, uint64_t addr, char *s)
431 {
432 do {
433 store_byte(cpu, addr++, *s);
434 } while (*s++);
435 }
436
437
438 /*
439 * add_environment_string():
440 *
441 * Like store_string(), but advances the pointer afterwards. The most
442 * obvious use is to place a number of strings (such as environment variable
443 * strings) after one-another in emulated memory.
444 */
445 void add_environment_string(struct cpu *cpu, char *s, uint64_t *addr)
446 {
447 store_string(cpu, *addr, s);
448 (*addr) += strlen(s) + 1;
449 }
450
451
452 /*
453 * add_environment_string_dual():
454 *
455 * Add "dual" environment strings, one for the variable name and one for the
456 * value, and update pointers afterwards.
457 */
458 void add_environment_string_dual(struct cpu *cpu,
459 uint64_t *ptrp, uint64_t *addrp, char *s1, char *s2)
460 {
461 uint64_t ptr = *ptrp, addr = *addrp;
462
463 store_32bit_word(cpu, ptr, addr);
464 ptr += sizeof(uint32_t);
465 if (addr != 0) {
466 store_string(cpu, addr, s1);
467 addr += strlen(s1) + 1;
468 }
469 store_32bit_word(cpu, ptr, addr);
470 ptr += sizeof(uint32_t);
471 if (addr != 0) {
472 store_string(cpu, addr, s2);
473 addr += strlen(s2) + 1;
474 }
475
476 *ptrp = ptr;
477 *addrp = addr;
478 }
479
480
481 /*
482 * store_64bit_word():
483 *
484 * Stores a 64-bit word in emulated RAM. Byte order is taken into account.
485 * Helper function.
486 */
487 int store_64bit_word(struct cpu *cpu, uint64_t addr, uint64_t data64)
488 {
489 unsigned char data[8];
490 if ((addr >> 32) == 0)
491 addr = (int64_t)(int32_t)addr;
492 data[0] = (data64 >> 56) & 255;
493 data[1] = (data64 >> 48) & 255;
494 data[2] = (data64 >> 40) & 255;
495 data[3] = (data64 >> 32) & 255;
496 data[4] = (data64 >> 24) & 255;
497 data[5] = (data64 >> 16) & 255;
498 data[6] = (data64 >> 8) & 255;
499 data[7] = (data64) & 255;
500 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
501 int tmp = data[0]; data[0] = data[7]; data[7] = tmp;
502 tmp = data[1]; data[1] = data[6]; data[6] = tmp;
503 tmp = data[2]; data[2] = data[5]; data[5] = tmp;
504 tmp = data[3]; data[3] = data[4]; data[4] = tmp;
505 }
506 return cpu->memory_rw(cpu, cpu->mem,
507 addr, data, sizeof(data), MEM_WRITE, CACHE_DATA);
508 }
509
510
511 /*
512 * store_32bit_word():
513 *
514 * Stores a 32-bit word in emulated RAM. Byte order is taken into account.
515 * (This function takes a 64-bit word as argument, to suppress some
516 * warnings, but only the lowest 32 bits are used.)
517 */
518 int store_32bit_word(struct cpu *cpu, uint64_t addr, uint64_t data32)
519 {
520 unsigned char data[4];
521 if (cpu->machine->arch == ARCH_MIPS && (addr >> 32) == 0)
522 addr = (int64_t)(int32_t)addr;
523 data[0] = (data32 >> 24) & 255;
524 data[1] = (data32 >> 16) & 255;
525 data[2] = (data32 >> 8) & 255;
526 data[3] = (data32) & 255;
527 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
528 int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
529 tmp = data[1]; data[1] = data[2]; data[2] = tmp;
530 }
531 return cpu->memory_rw(cpu, cpu->mem,
532 addr, data, sizeof(data), MEM_WRITE, CACHE_DATA);
533 }
534
535
536 /*
537 * store_16bit_word():
538 *
539 * Stores a 16-bit word in emulated RAM. Byte order is taken into account.
540 * (This function takes a 64-bit word as argument, to suppress some
541 * warnings, but only the lowest 16 bits are used.)
542 */
543 int store_16bit_word(struct cpu *cpu, uint64_t addr, uint64_t data16)
544 {
545 unsigned char data[2];
546 if (cpu->machine->arch == ARCH_MIPS && (addr >> 32) == 0)
547 addr = (int64_t)(int32_t)addr;
548 data[0] = (data16 >> 8) & 255;
549 data[1] = (data16) & 255;
550 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
551 int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
552 }
553 return cpu->memory_rw(cpu, cpu->mem,
554 addr, data, sizeof(data), MEM_WRITE, CACHE_DATA);
555 }
556
557
558 /*
559 * store_buf():
560 *
561 * memcpy()-like helper function, from host RAM to emulated RAM.
562 */
563 void store_buf(struct cpu *cpu, uint64_t addr, char *s, size_t len)
564 {
565 size_t psize = 1024; /* 1024 256 64 16 4 1 */
566
567 if (cpu->machine->arch == ARCH_MIPS && (addr >> 32) == 0)
568 addr = (int64_t)(int32_t)addr;
569
570 while (len != 0) {
571 if ((addr & (psize-1)) == 0) {
572 while (len >= psize) {
573 cpu->memory_rw(cpu, cpu->mem, addr,
574 (unsigned char *)s, psize, MEM_WRITE,
575 CACHE_DATA);
576 addr += psize;
577 s += psize;
578 len -= psize;
579 }
580 }
581 psize >>= 2;
582 }
583
584 while (len-- != 0)
585 store_byte(cpu, addr++, *s++);
586 }
587
588
589 /*
590 * store_pointer_and_advance():
591 *
592 * Stores a 32-bit or 64-bit pointer in emulated RAM, and advances the
593 * target address. (Useful for e.g. ARCBIOS environment initialization.)
594 */
595 void store_pointer_and_advance(struct cpu *cpu, uint64_t *addrp,
596 uint64_t data, int flag64)
597 {
598 uint64_t addr = *addrp;
599 if (flag64) {
600 store_64bit_word(cpu, addr, data);
601 addr += 8;
602 } else {
603 store_32bit_word(cpu, addr, data);
604 addr += 4;
605 }
606 *addrp = addr;
607 }
608
609
610 /*
611 * load_32bit_word():
612 *
613 * Helper function. Prints a warning and returns 0, if the read failed.
614 * Emulated byte order is taken into account.
615 */
616 uint32_t load_32bit_word(struct cpu *cpu, uint64_t addr)
617 {
618 unsigned char data[4];
619
620 if (cpu->machine->arch == ARCH_MIPS && (addr >> 32) == 0)
621 addr = (int64_t)(int32_t)addr;
622 cpu->memory_rw(cpu, cpu->mem,
623 addr, data, sizeof(data), MEM_READ, CACHE_DATA);
624
625 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
626 int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
627 tmp = data[1]; data[1] = data[2]; data[2] = tmp;
628 }
629
630 return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
631 }
632
633
634 /*
635 * load_16bit_word():
636 *
637 * Helper function. Prints a warning and returns 0, if the read failed.
638 * Emulated byte order is taken into account.
639 */
640 uint16_t load_16bit_word(struct cpu *cpu, uint64_t addr)
641 {
642 unsigned char data[2];
643
644 if (cpu->machine->arch == ARCH_MIPS && (addr >> 32) == 0)
645 addr = (int64_t)(int32_t)addr;
646 cpu->memory_rw(cpu, cpu->mem,
647 addr, data, sizeof(data), MEM_READ, CACHE_DATA);
648
649 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
650 int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
651 }
652
653 return (data[0] << 8) + data[1];
654 }
655
656
657 /*
658 * store_64bit_word_in_host():
659 *
660 * Stores a 64-bit word in the _host's_ RAM. Emulated byte order is taken
661 * into account. This is useful when building structs in the host's RAM
662 * which will later be copied into emulated RAM.
663 */
664 void store_64bit_word_in_host(struct cpu *cpu,
665 unsigned char *data, uint64_t data64)
666 {
667 data[0] = (data64 >> 56) & 255;
668 data[1] = (data64 >> 48) & 255;
669 data[2] = (data64 >> 40) & 255;
670 data[3] = (data64 >> 32) & 255;
671 data[4] = (data64 >> 24) & 255;
672 data[5] = (data64 >> 16) & 255;
673 data[6] = (data64 >> 8) & 255;
674 data[7] = (data64) & 255;
675 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
676 int tmp = data[0]; data[0] = data[7]; data[7] = tmp;
677 tmp = data[1]; data[1] = data[6]; data[6] = tmp;
678 tmp = data[2]; data[2] = data[5]; data[5] = tmp;
679 tmp = data[3]; data[3] = data[4]; data[4] = tmp;
680 }
681 }
682
683
684 /*
685 * store_32bit_word_in_host():
686 *
687 * See comment for store_64bit_word_in_host().
688 *
689 * (Note: The data32 parameter is a uint64_t. This is done to suppress
690 * some warnings.)
691 */
692 void store_32bit_word_in_host(struct cpu *cpu,
693 unsigned char *data, uint64_t data32)
694 {
695 data[0] = (data32 >> 24) & 255;
696 data[1] = (data32 >> 16) & 255;
697 data[2] = (data32 >> 8) & 255;
698 data[3] = (data32) & 255;
699 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
700 int tmp = data[0]; data[0] = data[3]; data[3] = tmp;
701 tmp = data[1]; data[1] = data[2]; data[2] = tmp;
702 }
703 }
704
705
706 /*
707 * store_16bit_word_in_host():
708 *
709 * See comment for store_64bit_word_in_host().
710 */
711 void store_16bit_word_in_host(struct cpu *cpu,
712 unsigned char *data, uint16_t data16)
713 {
714 data[0] = (data16 >> 8) & 255;
715 data[1] = (data16) & 255;
716 if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
717 int tmp = data[0]; data[0] = data[1]; data[1] = tmp;
718 }
719 }
720
721
722 /*
723 * machine_setup():
724 *
725 * This (rather large) function initializes memory, registers, and/or devices
726 * required by specific machine emulations.
727 */
728 void machine_setup(struct machine *machine)
729 {
730 struct memory *mem;
731 struct machine_entry *me;
732
733 /* Abreviation: :-) */
734 struct cpu *cpu = machine->cpus[machine->bootstrap_cpu];
735
736 machine->bootdev_id = diskimage_bootdev(machine,
737 &machine->bootdev_type);
738
739 mem = cpu->mem;
740 machine->machine_name = NULL;
741
742 /* TODO: Move this somewhere else? */
743 if (machine->boot_string_argument == NULL) {
744 switch (machine->machine_type) {
745 case MACHINE_ARC:
746 machine->boot_string_argument = "-aN";
747 break;
748 case MACHINE_CATS:
749 machine->boot_string_argument = "-A";
750 break;
751 case MACHINE_PMAX:
752 machine->boot_string_argument = "-a";
753 break;
754 default:
755 /* Important, because boot_string_argument should
756 not be set to NULL: */
757 machine->boot_string_argument = "";
758 }
759 }
760
761
762 /*
763 * If the machine has a setup function in src/machines/machine_*.c
764 * then use that one, otherwise use the old hardcoded stuff here:
765 */
766
767 me = first_machine_entry;
768 while (me != NULL) {
769 if (machine->machine_type == me->machine_type &&
770 me->setup != NULL) {
771 me->setup(machine, cpu);
772 break;
773 }
774 me = me->next;
775 }
776
777 if (me == NULL) {
778 fatal("Unknown emulation type %i\n", machine->machine_type);
779 exit(1);
780 }
781
782 if (machine->machine_name != NULL)
783 debug("machine: %s", machine->machine_name);
784
785 if (machine->emulated_hz > 0)
786 debug(" (%.2f MHz)", (float)machine->emulated_hz / 1000000);
787 debug("\n");
788
789 /* Default fake speed: 5 MHz */
790 if (machine->emulated_hz < 1)
791 machine->emulated_hz = 5000000;
792
793 if (machine->bootstr != NULL) {
794 debug("bootstring%s: %s", (machine->bootarg!=NULL &&
795 strlen(machine->bootarg) >= 1)? "(+bootarg)" : "",
796 machine->bootstr);
797 if (machine->bootarg != NULL && strlen(machine->bootarg) >= 1)
798 debug(" %s", machine->bootarg);
799 debug("\n");
800 }
801
802 if (verbose >= 2)
803 machine_dump_bus_info(machine);
804
805 if (!machine->stable)
806 fatal("!\n! NOTE: This machine type is not implemented well"
807 " enough yet to run\n! any real-world code!"
808 " (At least, it hasn't been verified to do so.)\n!\n"
809 "! Please read the GXemul documentation for information"
810 " about which\n! machine types that actually work.\n!\n");
811 }
812
813
814 /*
815 * machine_memsize_fix():
816 *
817 * Sets physical_ram_in_mb (if not already set), and memory_offset_in_mb,
818 * depending on machine type.
819 */
820 void machine_memsize_fix(struct machine *m)
821 {
822 if (m == NULL) {
823 fatal("machine_defaultmemsize(): m == NULL?\n");
824 exit(1);
825 }
826
827 if (m->physical_ram_in_mb == 0) {
828 struct machine_entry *me = first_machine_entry;
829 while (me != NULL) {
830 if (m->machine_type == me->machine_type &&
831 me->set_default_ram != NULL) {
832 me->set_default_ram(m);
833 break;
834 }
835 me = me->next;
836 }
837 }
838
839 /* Special hack for hpcmips machines: */
840 if (m->machine_type == MACHINE_HPCMIPS) {
841 m->dbe_on_nonexistant_memaccess = 0;
842 }
843
844 /* Special SGI memory offsets: (TODO: move this somewhere else) */
845 if (m->machine_type == MACHINE_SGI) {
846 switch (m->machine_subtype) {
847 case 20:
848 case 22:
849 case 24:
850 case 26:
851 m->memory_offset_in_mb = 128;
852 break;
853 case 28:
854 case 30:
855 m->memory_offset_in_mb = 512;
856 break;
857 }
858 }
859
860 if (m->physical_ram_in_mb == 0)
861 m->physical_ram_in_mb = DEFAULT_RAM_IN_MB;
862 }
863
864
865 /*
866 * machine_default_cputype():
867 *
868 * Sets m->cpu_name, if it isn't already set, depending on the machine type.
869 */
870 void machine_default_cputype(struct machine *m)
871 {
872 struct machine_entry *me;
873
874 if (m == NULL) {
875 fatal("machine_default_cputype(): m == NULL?\n");
876 exit(1);
877 }
878
879 /* Already set? Then return. */
880 if (m->cpu_name != NULL)
881 return;
882
883 me = first_machine_entry;
884 while (me != NULL) {
885 if (m->machine_type == me->machine_type &&
886 me->set_default_cpu != NULL) {
887 me->set_default_cpu(m);
888 break;
889 }
890 me = me->next;
891 }
892
893 if (m->cpu_name == NULL) {
894 fprintf(stderr, "machine_default_cputype(): no default"
895 " cpu for machine type %i subtype %i\n",
896 m->machine_type, m->machine_subtype);
897 exit(1);
898 }
899 }
900
901
902 /*
903 * machine_entry_new():
904 *
905 * This function creates a new machine_entry struct, and fills it with some
906 * valid data; it is up to the caller to add additional data that weren't
907 * passed as arguments to this function.
908 */
909 struct machine_entry *machine_entry_new(const char *name,
910 int arch, int oldstyle_type, int n_aliases, int n_subtypes)
911 {
912 struct machine_entry *me;
913
914 me = malloc(sizeof(struct machine_entry));
915 if (me == NULL) {
916 fprintf(stderr, "machine_entry_new(): out of memory (1)\n");
917 exit(1);
918 }
919
920 memset(me, 0, sizeof(struct machine_entry));
921
922 me->name = name;
923 me->arch = arch;
924 me->machine_type = oldstyle_type;
925 me->n_aliases = n_aliases;
926 me->aliases = malloc(sizeof(char *) * n_aliases);
927 if (me->aliases == NULL) {
928 fprintf(stderr, "machine_entry_new(): out of memory (2)\n");
929 exit(1);
930 }
931 me->n_subtypes = n_subtypes;
932 me->setup = NULL;
933
934 if (n_subtypes > 0) {
935 me->subtype = malloc(sizeof(struct machine_entry_subtype *) *
936 n_subtypes);
937 if (me->subtype == NULL) {
938 fprintf(stderr, "machine_entry_new(): out of "
939 "memory (3)\n");
940 exit(1);
941 }
942 }
943
944 return me;
945 }
946
947
948 /*
949 * machine_entry_subtype_new():
950 *
951 * This function creates a new machine_entry_subtype struct, and fills it with
952 * some valid data; it is up to the caller to add additional data that weren't
953 * passed as arguments to this function.
954 *
955 * For internal use.
956 */
957 struct machine_entry_subtype *machine_entry_subtype_new(
958 const char *name, int oldstyle_type, int n_aliases)
959 {
960 struct machine_entry_subtype *mes;
961
962 mes = malloc(sizeof(struct machine_entry_subtype));
963 if (mes == NULL) {
964 fprintf(stderr, "machine_entry_subtype_new(): out "
965 "of memory (1)\n");
966 exit(1);
967 }
968
969 memset(mes, 0, sizeof(struct machine_entry_subtype));
970 mes->name = name;
971 mes->machine_subtype = oldstyle_type;
972 mes->n_aliases = n_aliases;
973 mes->aliases = malloc(sizeof(char *) * n_aliases);
974 if (mes->aliases == NULL) {
975 fprintf(stderr, "machine_entry_subtype_new(): "
976 "out of memory (2)\n");
977 exit(1);
978 }
979
980 return mes;
981 }
982
983
984 /*
985 * machine_entry_add():
986 *
987 * Inserts a new machine_entry into the machine entries list.
988 */
989 void machine_entry_add(struct machine_entry *me, int arch)
990 {
991 struct machine_entry *prev, *next;
992
993 /* Only insert it if the architecture is implemented in this
994 emulator configuration: */
995 if (cpu_family_ptr_by_number(arch) == NULL)
996 return;
997
998 prev = NULL;
999 next = first_machine_entry;
1000
1001 for (;;) {
1002 if (next == NULL)
1003 break;
1004 if (strcasecmp(me->name, next->name) < 0)
1005 break;
1006
1007 prev = next;
1008 next = next->next;
1009 }
1010
1011 if (prev != NULL)
1012 prev->next = me;
1013 else
1014 first_machine_entry = me;
1015 me->next = next;
1016 }
1017
1018
1019 /*
1020 * machine_list_available_types_and_cpus():
1021 *
1022 * List all available machine types (for example when running the emulator
1023 * with just -H as command line argument).
1024 */
1025 void machine_list_available_types_and_cpus(void)
1026 {
1027 struct machine_entry *me;
1028 int iadd = DEBUG_INDENTATION * 2;
1029
1030 debug("Available CPU types:\n\n");
1031
1032 debug_indentation(iadd);
1033 cpu_list_available_types();
1034 debug_indentation(-iadd);
1035
1036 debug("\nMost of the CPU types are bogus, and not really implemented."
1037 " The main effect of\nselecting a specific CPU type is to choose "
1038 "what kind of 'id' it will have.\n\nAvailable machine types (with "
1039 "aliases) and their subtypes:\n\n");
1040
1041 debug_indentation(iadd);
1042 me = first_machine_entry;
1043
1044 if (me == NULL)
1045 fatal("No machines defined!\n");
1046
1047 while (me != NULL) {
1048 int i, j, iadd = DEBUG_INDENTATION;
1049
1050 debug("%s [%s] (", me->name,
1051 cpu_family_ptr_by_number(me->arch)->name);
1052 for (i=0; i<me->n_aliases; i++)
1053 debug("%s\"%s\"", i? ", " : "", me->aliases[i]);
1054 debug(")\n");
1055
1056 debug_indentation(iadd);
1057 for (i=0; i<me->n_subtypes; i++) {
1058 struct machine_entry_subtype *mes;
1059 mes = me->subtype[i];
1060 debug("- %s", mes->name);
1061 debug(" (");
1062 for (j=0; j<mes->n_aliases; j++)
1063 debug("%s\"%s\"", j? ", " : "",
1064 mes->aliases[j]);
1065 debug(")\n");
1066 }
1067 debug_indentation(-iadd);
1068
1069 me = me->next;
1070 }
1071 debug_indentation(-iadd);
1072
1073 debug("\nMost of the machine types are bogus too. Please read the "
1074 "GXemul documentation\nfor information about which machine types "
1075 "that actually work. Use the alias\nwhen selecting a machine type "
1076 "or subtype, not the real name.\n");
1077
1078 debug("\n");
1079
1080 useremul_list_emuls();
1081 debug("Userland emulation works for programs with the complexity"
1082 " of Hello World,\nbut not much more.\n");
1083 }
1084
1085
1086 /*
1087 * machine_init():
1088 *
1089 * This function should be called before any other machine_*() function
1090 * is used. automachine_init() registers all machines in src/machines/.
1091 */
1092 void machine_init(void)
1093 {
1094 if (first_machine_entry != NULL) {
1095 fatal("machine_init(): already called?\n");
1096 exit(1);
1097 }
1098
1099 automachine_init();
1100 }
1101

  ViewVC Help
Powered by ViewVC 1.1.26