/[gxemul]/trunk/src/main.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

Annotation of /trunk/src/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20 - (hide annotations)
Mon Oct 8 16:19:23 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 21567 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1055 2005/11/25 22:48:36 debug Exp $
20051031	Adding disassembly support for more ARM instructions (clz,
		smul* etc), and adding a hack to support "new tiny" pages
		for StrongARM.
20051101	Minor documentation updates (NetBSD 2.0.2 -> 2.1, and OpenBSD
		3.7 -> 3.8, and lots of testing).
		Changing from 1-sector PIO mode 0 transfers to 128-sector PIO
		mode 3 (in dev_wdc).
		Various minor ARM dyntrans updates (pc-relative loads from
		within the same page as the instruction are now treated as
		constant "mov").
20051102	Re-enabling instruction combinations (they were accidentally
		disabled).
		Dyntrans TLB entries are now overwritten using a round-robin
		scheme instead of randomly. This increases performance.
		Fixing a typo in file.c (thanks to Chuan-Hua Chang for
		noticing it).
		Experimenting with adding ATAPI support to dev_wdc (to make
		emulated *BSD detect cdroms as cdroms, not harddisks).
20051104	Various minor updates.
20051105	Continuing on the ATAPI emulation. Seems to work well enough
		for a NetBSD/cats installation, but not OpenBSD/cats.
		Various other updates.
20051106	Modifying the -Y command line option to allow scaleup with
		certain graphic controllers (only dev_vga so far), not just
		scaledown.
		Some minor dyntrans cleanups.
20051107	Beginning a cleanup up the PCI subsystem (removing the
		read_register hack, etc).
20051108	Continuing the cleanup; splitting up some pci devices into a
		normal autodev device and some separate pci glue code.
20051109	Continuing on the PCI bus stuff; all old pci_*.c have been
		incorporated into normal devices and/or rewritten as glue code
		only, adding a dummy Intel 82371AB PIIX4 for Malta (not really
		tested yet).
		Minor pckbc fix so that Linux doesn't complain.
		Working on the DEC 21143 NIC (ethernet mac rom stuff mostly).
		Various other minor fixes.
20051110	Some more ARM dyntrans fine-tuning (e.g. some instruction
		combinations (cmps followed by conditional branch within the
		same page) and special cases for DPIs with regform when the
		shifter isn't used).
20051111	ARM dyntrans updates: O(n)->O(1) for just-mark-as-non-
		writable in the generic pc_to_pointers function, and some other
		minor hacks.
		Merging Cobalt and evbmips (Malta) ISA interrupt handling,
		and some minor fixes to allow Linux to accept harddisk irqs.
20051112	Minor device updates (pckbc, dec21143, lpt, ...), most
		importantly fixing the ALI M1543/M5229 so that harddisk irqs
		work with Linux/CATS.
20051113	Some more generalizations of the PCI subsystem.
		Finally took the time to add a hack for SCSI CDROM TOCs; this
		enables OpenBSD to use partition 'a' (as needed by the OpenBSD
		installer), and Windows NT's installer to get a bit further.
		Also fixing dev_wdc to allow Linux to detect ATAPI CDROMs.
		Continuing on the DEC 21143.
20051114	Minor ARM dyntrans tweaks; ARM cmps+branch optimization when
		comparing with 0, and generalizing the xchg instr. comb.
		Adding disassembly of ARM mrrc/mcrr and q{,d}{add,sub}.
20051115	Continuing on various PPC things (BATs, other address trans-
		lation things, various loads/stores, BeBox emulation, etc.).
		Beginning to work on PPC interrupt/exception support.
20051116	Factoring out some code which initializes legacy ISA devices
		from those machines that use them (bus_isa).
		Continuing on PPC interrupt/exception support.
20051117	Minor Malta fixes: RTC year offset = 80, disabling a speed hack
		which caused NetBSD to detect a too fast cpu, and adding a new
		hack to make Linux detect a faster cpu.
		Continuing on the Artesyn PM/PPC emulation mode.
		Adding an Algor emulation skeleton (P4032 and P5064);
		implementing some of the basics.
		Continuing on PPC emulation in general; usage of unimplemented
		SPRs is now easier to track, continuing on memory/exception
		related issues, etc.
20051118	More work on PPC emulation (tgpr0..3, exception handling,
		memory stuff, syscalls, etc.).
20051119	Changing the ARM dyntrans code to mostly use cpu->pc, and not
		necessarily use arm reg 15. Seems to work.
		Various PPC updates; continuing on the PReP emulation mode.
20051120	Adding a workaround/hack to dev_mc146818 to allow NetBSD/prep
		to detect the clock.
20051121	More cleanup of the PCI bus (memory and I/O bases, etc).
		Continuing on various PPC things (decrementer and timebase,
		WDCs on obio (on PReP) use irq 13, not 14/15).
20051122	Continuing on the CPC700 controller (interrupts etc) for PMPPC,
		and on PPC stuff in general.
		Finally! After some bug fixes to the virtual to physical addr
		translation, NetBSD/{prep,pmppc} 2.1 reach userland and are
		stable enough to be interacted with.
		More PCI updates; reverse-endian device access for PowerPC etc.
20051123	Generalizing the IEEE floating point subsystem (moving it out
		from src/cpus/cpu_mips_coproc.c into a new src/float_emul.c).
		Input via slave xterms was sometimes not really working; fixing
		this for ns16550, and a warning message is now displayed if
		multiple non-xterm consoles are active.
		Adding some PPC floating point support, etc.
		Various interrupt related updates (dev_wdc, _ns16550, _8259,
		and the isa32 common code in machine.c).
		NetBSD/prep can now be installed! :-) (Well, with some manual
		commands necessary before running sysinst.) Updating the
		documentation and various other things to reflect this.
20051124	Various minor documentation updates.
		Continuing the work on the DEC 21143 NIC.
20051125	LOTS of work on the 21143. Both OpenBSD and NetBSD work fine
		with it now, except that OpenBSD sometimes gives a time-out
		warning.
		Minor documentation updates.

==============  RELEASE 0.3.7  ==============


1 dpavlin 2 /*
2     * Copyright (C) 2003-2005 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 dpavlin 20 * $Id: main.c,v 1.248 2005/11/23 02:17:00 debug Exp $
29 dpavlin 2 */
30    
31     #include <stdio.h>
32     #include <stdlib.h>
33     #include <stdarg.h>
34     #include <string.h>
35     #include <time.h>
36     #include <unistd.h>
37    
38     #include "console.h"
39     #include "cpu.h"
40     #include "device.h"
41     #include "diskimage.h"
42     #include "emul.h"
43     #include "machine.h"
44     #include "misc.h"
45    
46    
47     extern volatile int single_step;
48     extern int force_debugger_at_exit;
49     extern int show_opcode_statistics;
50    
51     extern int optind;
52     extern char *optarg;
53    
54     int extra_argc;
55     char **extra_argv;
56     char *progname;
57    
58     int fully_deterministic = 0;
59    
60    
61     /*****************************************************************************
62     *
63     * NOTE: debug(), fatal(), and debug_indentation() are not re-entrant.
64     * The global variable quiet_mode can be used to suppress the output
65     * of debug(), but not the output of fatal().
66     *
67     *****************************************************************************/
68    
69     int verbose = 0;
70     int quiet_mode = 0;
71    
72     static int debug_indent = 0;
73     static int debug_currently_at_start_of_line = 1;
74    
75    
76     /*
77     * va_debug():
78     *
79     * Used internally by debug() and fatal().
80     */
81     static void va_debug(va_list argp, char *fmt)
82     {
83     char buf[DEBUG_BUFSIZE + 1];
84     char *s;
85     int i;
86    
87     buf[0] = buf[DEBUG_BUFSIZE] = 0;
88     vsnprintf(buf, DEBUG_BUFSIZE, fmt, argp);
89    
90     s = buf;
91     while (*s) {
92     if (debug_currently_at_start_of_line) {
93     for (i=0; i<debug_indent; i++)
94     printf(" ");
95     }
96    
97     printf("%c", *s);
98    
99     debug_currently_at_start_of_line = 0;
100     if (*s == '\n' || *s == '\r')
101     debug_currently_at_start_of_line = 1;
102     s++;
103     }
104     }
105    
106    
107     /*
108     * debug_indentation():
109     *
110     * Modify the debug indentation.
111     */
112     void debug_indentation(int diff)
113     {
114     debug_indent += diff;
115     if (debug_indent < 0)
116     fprintf(stderr, "WARNING: debug_indent less than 0!\n");
117     }
118    
119    
120     /*
121     * debug():
122     *
123     * Debug output (ignored if quiet_mode is set).
124     */
125     void debug(char *fmt, ...)
126     {
127     va_list argp;
128    
129     if (quiet_mode)
130     return;
131    
132     va_start(argp, fmt);
133     va_debug(argp, fmt);
134     va_end(argp);
135     }
136    
137    
138     /*
139     * fatal():
140     *
141     * Fatal works like debug(), but doesn't care about the quiet_mode
142     * setting.
143     */
144     void fatal(char *fmt, ...)
145     {
146     va_list argp;
147    
148     va_start(argp, fmt);
149     va_debug(argp, fmt);
150     va_end(argp);
151     }
152    
153    
154     /*****************************************************************************/
155    
156    
157     /*
158     * internal_w():
159     *
160     * For internal use by gxemul itself.
161     */
162     void internal_w(char *arg)
163     {
164     if (arg == NULL || strncmp(arg, "W@", 2) != 0) {
165     fprintf(stderr, "-W is for internal use by gxemul,"
166     " not for manual use.\n");
167     exit(1);
168     }
169    
170     arg += 2;
171    
172     switch (arg[0]) {
173     case 'S':
174     console_slave(arg + 1);
175     break;
176     default:
177     fprintf(stderr, "internal_w(): UNIMPLEMENTED arg = '%s'\n",
178     arg);
179     }
180     }
181    
182    
183     /*****************************************************************************/
184    
185    
186     /*
187     * usage():
188     *
189     * Prints program usage to stdout.
190     */
191     static void usage(int longusage)
192     {
193     printf("GXemul");
194     #ifdef VERSION
195     printf("-" VERSION);
196     #endif
197     printf(" Copyright (C) 2003-2005 Anders Gavare\n");
198     printf("Read the source code and/or documentation for "
199     "other Copyright messages.\n");
200    
201     printf("\nusage: %s [machine, other, and general options] [file "
202     "[...]]\n", progname);
203 dpavlin 14 printf(" or %s [general options] @configfile\n", progname);
204 dpavlin 2 printf(" or %s [userland, other, and general options] file "
205     "[args ...]\n", progname);
206    
207     if (!longusage) {
208     printf("\nRun %s -h for help on command line options.\n",
209     progname);
210     return;
211     }
212    
213     printf("\nMachine selection options:\n");
214     printf(" -E t try to emulate machine type t. (Use -H to get "
215     "a list of types.)\n");
216     printf(" -e st try to emulate machine subtype st. (Use this "
217     "with -E.)\n");
218    
219     printf("\nOther options:\n");
220 dpavlin 12 printf(" -A disable alignment checks in some cases (for higher"
221     " speed)\n");
222 dpavlin 2 #ifdef BINTRANS
223 dpavlin 10 printf(" -B disable dynamic binary translation. (translation"
224     " is turned on\n by default, if the host "
225     "supports it)\n");
226 dpavlin 2 #endif
227     printf(" -C x try to emulate a specific CPU. (Use -H to get a "
228     "list of types.)\n");
229     printf(" -d fname add fname as a disk image. You can add \"xxx:\""
230     " as a prefix\n");
231     printf(" where xxx is one or more of the following:\n");
232 dpavlin 6 printf(" b specifies that this is the boot"
233 dpavlin 2 " device\n");
234 dpavlin 6 printf(" c CD-ROM\n");
235     printf(" d DISK\n");
236     printf(" f FLOPPY\n");
237     printf(" gH;S; set geometry to H heads and S"
238     " sectors-per-track\n");
239     printf(" i IDE\n");
240     printf(" r read-only (don't allow changes to the"
241 dpavlin 2 " file)\n");
242 dpavlin 6 printf(" s SCSI\n");
243     printf(" t tape\n");
244     printf(" 0-7 force a specific ID\n");
245 dpavlin 2 printf(" -I x emulate clock interrupts at x Hz (affects"
246     " rtc devices only, not\n");
247     printf(" actual runtime speed) (this disables automatic"
248     " clock adjustments)\n");
249     printf(" -i display each instruction as it is executed\n");
250     printf(" -J disable some speed tricks\n");
251     printf(" -j name set the name of the kernel, for example:\n");
252     printf(" -j netbsd for NetBSD/pmax\n");
253     printf(" -j bsd for OpenBSD/pmax\n");
254     printf(" -j vmunix for Ultrix/RISC\n");
255     printf(" -M m emulate m MBs of physical RAM\n");
256     printf(" -m nr run at most nr instructions (on any cpu)\n");
257     printf(" -N display nr of instructions/second average, at"
258     " regular intervals\n");
259     printf(" -n nr set nr of CPUs (for SMP experiments)\n");
260     printf(" -O force netboot (tftp instead of disk), even when"
261     " a disk image is\n"
262     " present (for DECstation, SGI, and ARC emulation)\n");
263     printf(" -o arg set the boot argument (for DEC, ARC, or SGI"
264     " emulation).\n");
265     printf(" Default arg for DEC is '-a', for ARC '-aN'.\n");
266     printf(" -p pc add a breakpoint (remember to use the '0x' "
267     "prefix for hex!)\n");
268     printf(" -Q no built-in PROM emulation (use this for "
269     "running ROM images)\n");
270     printf(" -R use random bootstrap cpu, instead of nr 0\n");
271     printf(" -r register dumps before every instruction\n");
272     printf(" -S initialize emulated RAM to random bytes, "
273     "instead of zeroes\n");
274     printf(" -T enter the single-step debugger on "
275     "unimplemented memory accesses\n");
276     printf(" -t show function trace tree\n");
277     printf(" -U enable slow_serial_interrupts_hack_for_linux\n");
278     #ifdef WITH_X11
279     printf(" -X use X11\n");
280     #endif /* WITH_X11 */
281     printf(" -x open up new xterms for emulated serial ports "
282     "(default is on when\n using configuration files, off"
283     " otherwise)\n");
284     #ifdef WITH_X11
285     printf(" -Y n scale down framebuffer windows by n x n times\n");
286     #endif /* WITH_X11 */
287     printf(" -y x set max_random_cycles_per_chunk to x"
288     " (experimental)\n");
289     printf(" -Z n set nr of graphics cards, for emulating a "
290     "dual-head or tripple-head\n"
291     " environment (only for DECstation emulation)\n");
292     printf(" -z disp add disp as an X11 display to use for "
293     "framebuffers\n");
294    
295     printf("\nUserland options:\n");
296     printf(" -u emul userland-only (syscall) emulation (use -H to"
297     " get a list of\n available emulation modes)\n");
298    
299     printf("\nGeneral options:\n");
300     printf(" -D guarantee fully deterministic behaviour\n");
301     printf(" -H display a list of possible CPU and "
302     "machine types\n");
303     printf(" -h display this help message\n");
304     printf(" -K force the debugger to be entered at the end "
305     "of a simulation\n");
306     printf(" -q quiet mode (don't print startup messages)\n");
307     printf(" -s show opcode usage statistics after simulation\n");
308     printf(" -V start up in the single-step debugger, paused\n");
309     printf(" -v verbose debug messages\n");
310     printf("\n");
311     printf("If you are selecting a machine type to emulate directly "
312     "on the command line,\nthen you must specify one or more names"
313     " of files that you wish to load into\n"
314     "memory. Supported formats are: ELF a.out ecoff srec syms raw\n"
315     "where syms is the text produced by running 'nm' (or 'nm -S') "
316     "on a binary.\n"
317     "To load a raw binary into memory, add \"address:\" in front "
318     "of the filename,\n"
319 dpavlin 4 "or \"address:skiplen:\" or \"address:skiplen:initialpc:\".\n"
320 dpavlin 2 "Examples:\n"
321 dpavlin 4 " 0xbfc00000:rom.bin for a raw ROM image\n"
322     " 0xbfc00000:0x100:rom.bin for an image with "
323 dpavlin 2 "0x100 bytes header\n"
324 dpavlin 4 " 0xbfc00000:0x100:0xbfc00884:rom.bin "
325 dpavlin 2 "start with pc=0xbfc00884\n");
326     }
327    
328    
329     /*
330     * get_cmd_args():
331     *
332     * Reads command line arguments.
333     */
334 dpavlin 4 int get_cmd_args(int argc, char *argv[], struct emul *emul,
335     char ***diskimagesp, int *n_diskimagesp)
336 dpavlin 2 {
337     int ch, res, using_switch_d = 0, using_switch_Z = 0;
338     char *type = NULL, *subtype = NULL;
339     int n_cpus_set = 0;
340     int msopts = 0; /* Machine-specific options used */
341     struct machine *m = emul_add_machine(emul, "default");
342    
343 dpavlin 12 while ((ch = getopt(argc, argv, "ABC:Dd:E:e:HhI:iJj:KM:m:"
344 dpavlin 2 "Nn:Oo:p:QqRrSsTtUu:VvW:XxY:y:Z:z:")) != -1) {
345     switch (ch) {
346 dpavlin 12 case 'A':
347     m->dyntrans_alignment_check = 0;
348     msopts = 1;
349     break;
350 dpavlin 2 case 'B':
351     m->bintrans_enable = 0;
352     msopts = 1;
353     break;
354     case 'C':
355     m->cpu_name = strdup(optarg);
356     msopts = 1;
357     break;
358     case 'D':
359     fully_deterministic = 1;
360     break;
361     case 'd':
362 dpavlin 4 /* diskimage_add() is called further down */
363     (*n_diskimagesp) ++;
364     (*diskimagesp) = realloc(*diskimagesp,
365     sizeof(char *) * (*n_diskimagesp));
366     if (*diskimagesp == NULL) {
367     fprintf(stderr, "out of memory\n");
368     exit(1);
369     }
370     (*diskimagesp)[(*n_diskimagesp) - 1] = strdup(optarg);
371 dpavlin 2 using_switch_d = 1;
372     msopts = 1;
373     break;
374     case 'E':
375     type = optarg;
376     msopts = 1;
377     break;
378     case 'e':
379     subtype = optarg;
380     msopts = 1;
381     break;
382     case 'H':
383     machine_list_available_types_and_cpus();
384     exit(1);
385     case 'h':
386     usage(1);
387     exit(1);
388     case 'I':
389     m->emulated_hz = atoi(optarg);
390     m->automatic_clock_adjustment = 0;
391     msopts = 1;
392     break;
393     case 'i':
394     m->instruction_trace = 1;
395     msopts = 1;
396     break;
397     case 'J':
398     m->speed_tricks = 0;
399     msopts = 1;
400     break;
401     case 'j':
402     m->boot_kernel_filename = strdup(optarg);
403     if (m->boot_kernel_filename == NULL) {
404     fprintf(stderr, "out of memory\n");
405     exit(1);
406     }
407     msopts = 1;
408     break;
409     case 'K':
410     force_debugger_at_exit = 1;
411     break;
412     case 'M':
413     m->physical_ram_in_mb = atoi(optarg);
414     msopts = 1;
415     break;
416     case 'm':
417     m->max_instructions = atoi(optarg);
418     msopts = 1;
419     break;
420     case 'N':
421     m->show_nr_of_instructions = 1;
422     msopts = 1;
423     break;
424     case 'n':
425     m->ncpus = atoi(optarg);
426     n_cpus_set = 1;
427     msopts = 1;
428     break;
429     case 'O':
430     m->force_netboot = 1;
431     msopts = 1;
432     break;
433     case 'o':
434     m->boot_string_argument = strdup(optarg);
435     if (m->boot_string_argument == NULL) {
436     fprintf(stderr, "out of memory\n");
437     exit(1);
438     }
439     msopts = 1;
440     break;
441     case 'p':
442     if (m->n_breakpoints >= MAX_BREAKPOINTS) {
443     fprintf(stderr, "too many breakpoints\n");
444     exit(1);
445     }
446     m->breakpoint_string[m->n_breakpoints] = strdup(optarg);
447     if (m->breakpoint_string[m->n_breakpoints] == NULL) {
448     fprintf(stderr, "out of memory\n");
449     exit(1);
450     }
451     m->breakpoint_flags[m->n_breakpoints] = 0;
452     m->n_breakpoints ++;
453     msopts = 1;
454     break;
455     case 'Q':
456     m->prom_emulation = 0;
457     msopts = 1;
458     break;
459     case 'q':
460     quiet_mode = 1;
461     break;
462     case 'R':
463     m->use_random_bootstrap_cpu = 1;
464     msopts = 1;
465     break;
466     case 'r':
467     m->register_dump = 1;
468     msopts = 1;
469     break;
470     case 'S':
471     m->random_mem_contents = 1;
472     msopts = 1;
473     break;
474     case 's':
475     show_opcode_statistics = 1;
476     break;
477     case 'T':
478     m->single_step_on_bad_addr = 1;
479     msopts = 1;
480     break;
481     case 't':
482     m->show_trace_tree = 1;
483     msopts = 1;
484     break;
485     case 'U':
486     m->slow_serial_interrupts_hack_for_linux = 1;
487     msopts = 1;
488     break;
489     case 'u':
490     m->userland_emul = strdup(optarg);
491     if (m->userland_emul == NULL) {
492     fprintf(stderr, "out of memory\n");
493     exit(1);
494     }
495     m->machine_type = MACHINE_USERLAND;
496     msopts = 1;
497     break;
498     case 'V':
499     single_step = 1;
500     break;
501     case 'v':
502     verbose ++;
503     break;
504     case 'W':
505     internal_w(optarg);
506     exit(0);
507     case 'X':
508     m->use_x11 = 1;
509     msopts = 1;
510     break;
511     case 'x':
512     console_allow_slaves(1);
513     break;
514     case 'Y':
515     m->x11_scaledown = atoi(optarg);
516 dpavlin 20 if (m->x11_scaledown < -1) {
517     m->x11_scaleup = - m->x11_scaledown;
518     m->x11_scaledown = 1;
519     }
520 dpavlin 4 if (m->x11_scaledown < 1) {
521     fprintf(stderr, "Invalid scaledown value.\n");
522     exit(1);
523     }
524 dpavlin 2 msopts = 1;
525     break;
526     case 'y':
527     m->max_random_cycles_per_chunk = atoi(optarg);
528     msopts = 1;
529     break;
530     case 'Z':
531     m->n_gfx_cards = atoi(optarg);
532     using_switch_Z = 1;
533     msopts = 1;
534     break;
535     case 'z':
536     m->x11_n_display_names ++;
537     m->x11_display_names = realloc(
538     m->x11_display_names,
539     m->x11_n_display_names * sizeof(char *));
540     if (m->x11_display_names == NULL) {
541     fprintf(stderr, "out of memory\n");
542     exit(1);
543     }
544     m->x11_display_names[m->x11_n_display_names-1] =
545     strdup(optarg);
546     if (m->x11_display_names
547     [m->x11_n_display_names-1] == NULL) {
548     fprintf(stderr, "out of memory\n");
549     exit(1);
550     }
551     msopts = 1;
552     break;
553     default:
554 dpavlin 10 fprintf(stderr, "Run %s -h for help on command "
555     "line options.\n", progname);
556 dpavlin 2 exit(1);
557     }
558     }
559    
560 dpavlin 12 if (type != NULL || subtype != NULL) {
561     if (type == NULL)
562     type = "";
563 dpavlin 2 if (subtype == NULL)
564     subtype = "";
565     res = machine_name_to_type(type, subtype,
566     &m->machine_type, &m->machine_subtype, &m->arch);
567     if (!res)
568     exit(1);
569     }
570    
571     argc -= optind;
572     argv += optind;
573    
574     extra_argc = argc;
575     extra_argv = argv;
576    
577    
578     if (m->machine_type == MACHINE_NONE && msopts) {
579     fprintf(stderr, "Machine specific options used directly on "
580     "the command line, but no machine\nemulation specified?\n");
581     exit(1);
582     }
583    
584    
585 dpavlin 12 /* -i and -r are pretty verbose: */
586 dpavlin 2
587     if (m->instruction_trace && !verbose) {
588 dpavlin 4 fprintf(stderr, "Implicitly %sturning on -v, because"
589     " of -i\n", quiet_mode? "turning off -q and " : "");
590 dpavlin 2 verbose = 1;
591     quiet_mode = 0;
592     }
593    
594     if (m->register_dump && !verbose) {
595 dpavlin 4 fprintf(stderr, "Implicitly %sturning on -v, because"
596     " of -r\n", quiet_mode? "turning off -q and " : "");
597 dpavlin 2 verbose = 1;
598     quiet_mode = 0;
599     }
600    
601 dpavlin 10 if ((m->instruction_trace || m->register_dump || m->show_trace_tree)
602     && m->bintrans_enable) {
603 dpavlin 20 if (m->arch == ARCH_MIPS)
604     fprintf(stderr, "Implicitly turning off bintrans.\n");
605 dpavlin 10 m->bintrans_enable = 0;
606     }
607 dpavlin 2
608 dpavlin 10
609 dpavlin 2 /*
610     * Usually, an executable filename must be supplied.
611     *
612     * However, it is possible to boot directly from a harddisk image
613 dpavlin 4 * file. If no kernel is supplied, but a diskimage is being used,
614     * then try to boot from disk.
615 dpavlin 2 */
616     if (extra_argc == 0) {
617     if (using_switch_d) {
618     /* Booting directly from a disk image... */
619     } else {
620     usage(0);
621     fprintf(stderr, "\nNo filename given. Aborting.\n");
622     exit(1);
623     }
624     } else if (m->boot_kernel_filename[0] == '\0') {
625     /*
626     * Default boot_kernel_filename is "", which can be overriden
627     * by the -j command line option. If it is still "" here,
628     * and we're not booting directly from a disk image, then
629     * try to set it to the last part of the last file name
630     * given on the command line. (Last part = the stuff after
631     * the last slash.)
632     */
633     char *s = extra_argv[extra_argc - 1];
634     char *s2;
635    
636     s2 = strrchr(s, '/');
637     if (s2 == NULL)
638     s2 = s;
639     else
640     s2 ++;
641    
642     m->boot_kernel_filename = strdup(s2);
643     if (m->boot_kernel_filename == NULL) {
644     fprintf(stderr, "out of memory\n");
645     exit(1);
646     }
647     }
648    
649     if (m->n_gfx_cards < 0 || m->n_gfx_cards > 3) {
650     fprintf(stderr, "Bad number of gfx cards (-Z).\n");
651     exit(1);
652     }
653    
654 dpavlin 20 if (m->bintrans_enable && m->arch == ARCH_MIPS) {
655 dpavlin 2 m->speed_tricks = 0;
656     /* TODO: Print a warning about this? */
657     }
658    
659 dpavlin 12 if (m->n_breakpoints > 0 &&
660     m->bintrans_enable && m->arch == ARCH_MIPS) {
661     fprintf(stderr, "Breakpoints and MIPS binary translation "
662 dpavlin 2 "don't work too well together right now.\n");
663     exit(1);
664     }
665    
666     #ifndef BINTRANS
667     if (m->bintrans_enable) {
668     fprintf(stderr, "WARNING: %s was compiled without "
669     "bintrans support. Ignoring -b.\n", progname);
670     m->bintrans_enable = 0;
671     }
672     #endif
673    
674     #ifndef WITH_X11
675     if (m->use_x11) {
676     fprintf(stderr, "WARNING: %s was compiled without "
677     "X11 support. Ignoring -X.\n", progname);
678     m->use_x11 = 0;
679     }
680     #endif
681    
682     if (!using_switch_Z && !m->use_x11)
683     m->n_gfx_cards = 0;
684    
685     m->bintrans_enabled_from_start = m->bintrans_enable;
686    
687     return 0;
688     }
689    
690    
691     /*
692     * main():
693     *
694     * Two kinds of emulations are started from here:
695     *
696     * o) Simple emulations, using command line arguments, compatible with
697     * earlier version of GXemul/mips64emul.
698     *
699     * o) Emulations set up by parsing special config files. (0 or more.)
700     */
701     int main(int argc, char *argv[])
702     {
703     struct emul **emuls;
704 dpavlin 4 char **diskimages = NULL;
705     int n_diskimages = 0;
706 dpavlin 2 int n_emuls;
707     int i;
708    
709     progname = argv[0];
710    
711     console_init();
712     cpu_init();
713     device_init();
714     machine_init();
715     useremul_init();
716    
717     emuls = malloc(sizeof(struct emul *));
718     if (emuls == NULL) {
719     fprintf(stderr, "out of memory\n");
720     exit(1);
721     }
722    
723     /* Allocate space for a simple emul setup: */
724     n_emuls = 1;
725     emuls[0] = emul_new(NULL);
726     if (emuls[0] == NULL) {
727     fprintf(stderr, "out of memory\n");
728     exit(1);
729     }
730    
731 dpavlin 4 get_cmd_args(argc, argv, emuls[0], &diskimages, &n_diskimages);
732 dpavlin 2
733     if (!fully_deterministic) {
734     /* TODO: More than just time(). Use gettimeofday(). */
735     srandom(time(NULL) ^ (getpid() << 12));
736     } else {
737     /* Fully deterministic. -I must have been supplied. */
738     if (emuls[0]->machines[0]->automatic_clock_adjustment) {
739     fatal("Cannot have -D without -I.\n");
740     exit(1);
741     }
742     }
743    
744     /* Print startup message: */
745     debug("GXemul");
746     #ifdef VERSION
747     debug("-" VERSION);
748     #endif
749     debug(" Copyright (C) 2003-2005 Anders Gavare\n");
750     debug("Read the source code and/or documentation for "
751     "other Copyright messages.\n\n");
752    
753     if (emuls[0]->machines[0]->machine_type == MACHINE_NONE)
754     n_emuls --;
755 dpavlin 4 else {
756     for (i=0; i<n_diskimages; i++)
757     diskimage_add(emuls[0]->machines[0], diskimages[i]);
758     }
759 dpavlin 2
760     /* Simple initialization, from command line arguments: */
761     if (n_emuls > 0) {
762     /* Make sure that there are no configuration files as well: */
763     for (i=1; i<argc; i++)
764     if (argv[i][0] == '@') {
765     fprintf(stderr, "You can either start one "
766     "emulation with one machine directly from "
767     "the command\nline, or start one or more "
768     "emulations using configuration files."
769     " Not both.\n");
770     exit(1);
771     }
772    
773     /* Initialize one emul: */
774     emul_simple_init(emuls[0]);
775     }
776    
777     /* Initialize emulations from config files: */
778     for (i=1; i<argc; i++) {
779     if (argv[i][0] == '@') {
780     char *s = argv[i] + 1;
781     if (strlen(s) == 0 && i+1 < argc &&
782     argv[i+1][0] != '@') {
783     i++;
784     s = argv[i];
785     }
786     n_emuls ++;
787     emuls = realloc(emuls, sizeof(struct emul *) * n_emuls);
788     if (emuls == NULL) {
789     fprintf(stderr, "out of memory\n");
790     exit(1);
791     }
792     emuls[n_emuls - 1] =
793     emul_create_from_configfile(s);
794    
795     /* Always allow slave xterms when using multiple
796     emulations: */
797     console_allow_slaves(1);
798     }
799     }
800    
801     if (n_emuls == 0) {
802 dpavlin 6 fprintf(stderr, "No emulations defined. Maybe you forgot to "
803 dpavlin 12 "use -E xx and/or -e yy, to specify\nthe machine type."
804     " For example:\n\n %s -e 3max -d disk.img\n\n"
805 dpavlin 6 "to boot an emulated DECstation 5000/200 with a disk "
806     "image.\n", progname);
807 dpavlin 2 exit(1);
808     }
809    
810     device_set_exit_on_error(0);
811 dpavlin 20 console_warn_if_slaves_are_needed();
812 dpavlin 2
813     /* Run all emulations: */
814     emul_run(emuls, n_emuls);
815    
816     return 0;
817     }
818    

  ViewVC Help
Powered by ViewVC 1.1.26