/[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 22 - (hide annotations)
Mon Oct 8 16:19:37 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 22228 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1121 2006/02/18 21:03:08 debug Exp $
20051126	Cobalt and PReP now work with the 21143 NIC.
		Continuing on Alpha dyntrans things.
		Fixing some more left-shift-by-24 to unsigned.
20051127	Working on OpenFirmware emulation; major cleanup/redesign.
		Progress on MacPPC emulation: NetBSD detects two CPUs (when
		running with -n 2), framebuffer output (for text) works.
		Adding quick-hack Bandit PCI controller and "gc" interrupt
		controller for MacPPC.
20051128	Changing from a Bandit to a Uni-North controller for macppc.
		Continuing on OpenFirmware and MacPPC emulation in general
		(obio controller, and wdc attached to the obio seems to work).
20051129	More work on MacPPC emulation (adding a dummy ADB controller).
		Continuing the PCI bus cleanup (endianness and tag composition)
		and rewriting all PCI controllers' access functions.
20051130	Various minor PPC dyntrans optimizations.
		Manually inlining some parts of the framebuffer redraw routine.
		Slowly beginning the conversion of the old MIPS emulation into
		dyntrans (but this will take quite some time to get right).
		Generalizing quick_pc_to_pointers.
20051201	Documentation update (David Muse has made available a kernel
		which simplifies Debian/DECstation installation).
		Continuing on the ADB bus controller.
20051202	Beginning a rewrite of the Zilog serial controller (dev_zs).
20051203	Continuing on the zs rewrite (now called dev_z8530); conversion
		to devinit style.
		Reworking some of the input-only vs output-only vs input-output
		details of src/console.c, better warning messages, and adding
		a debug dump.
		Removing the concept of "device state"; it wasn't really used.
		Changing some debug output (-vv should now be used to show all
		details about devices and busses; not shown during normal
		startup anymore).
		Beginning on some SPARC instruction disassembly support.
20051204	Minor PPC updates (WALNUT skeleton stuff).
		Continuing on the MIPS dyntrans rewrite.
		More progress on the ADB controller (a keyboard is "detected"
		by NetBSD and OpenBSD).
		Downgrading OpenBSD/arc as a guest OS from "working" to
		"almost working" in the documentation.
		Progress on Algor emulation ("v3" PCI controller).
20051205	Minor updates.
20051207	Sorting devices according to address; this reduces complexity
		of device lookups from O(n) to O(log n) in memory_rw (but no
		real performance increase (yet) in experiments).
20051210	Beginning the work on native dyntrans backends (by making a
		simple skeleton; so far only for Alpha hosts).
20051211	Some very minor SPARC updates.
20051215	Fixing a bug in the MIPS mul (note: not mult) instruction,
		so it also works with non-64-bit emulation. (Thanks to Alec
		Voropay for noticing the problem.)
20051216	More work on the fake/empty/simple/skeleton/whatever backend;
		performance doesn't increase, so this isn't really worth it,
		but it was probably worth it to prepare for a real backend
		later.
20051219	More instr call statistics gathering and analysis stuff.
20051220	Another fix for MIPS 'mul'. Also converting mul and {d,}cl{o,z}
		to dyntrans.
		memory_ppc.c syntax error fix (noticed by Peter Valchev).
		Beginning to move out machines from src/machine.c into
		individual files in src/machines (in a way similar to the
		autodev system for devices).
20051222	Updating the documentation regarding NetBSD/pmax 3.0.
20051223	- " - NetBSD/cats 3.0.
20051225	- " - NetBSD/hpcmips 3.0.
20051226	Continuing on the machine registry redesign.
		Adding support for ARM rrx (33-bit rotate).
		Fixing some signed/unsigned issues (exposed by gcc -W).
20051227	Fixing the bug which prevented a NetBSD/prep 3.0 install kernel
		from starting (triggered when an mtmsr was the last instruction
		on a page). Unfortunately not enough to get the kernel to run
		as well as the 2.1 kernels did.
20051230	Some dyntrans refactoring.
20051231	Continuing on the machine registry redesign.
20060101-10	Continuing... moving more machines. Moving MD interrupt stuff
		from machine.c into a new src/machines/interrupts.c.
20060114	Adding various mvmeppc machine skeletons.
20060115	Continuing on mvme* stuff. NetBSD/mvmeppc prints boot messages
		(for MVME1600) and reaches the root device prompt, but no
		specific hardware devices are emulated yet.
20060116	Minor updates to the mvme1600 emulation mode; the Eagle PCI bus
		seems to work without much modification, and a 21143 can be
		detected, interrupts might work (but untested so far).
		Adding a fake MK48Txx (mkclock) device, for NetBSD/mvmeppc.
20060121	Adding an aux control register for ARM. (A BIG thank you to
		Olivier Houchard for tracking down this bug.)
20060122	Adding more ARM instructions (smulXY), and dev_iq80321_7seg.
20060124	Adding disassembly of more ARM instructions (mia*, mra/mar),
		and some semi-bogus XScale and i80321 registers.
20060201-02	Various minor updates. Moving the last machines out of
		machine.c.
20060204	Adding a -c command line option, for running debugger commands
		before the simulation starts, but after all files have been
		loaded.
		Minor iq80321-related updates.
20060209	Minor hacks (DEVINIT macro, etc).
		Preparing for the generalization of the 64-bit dyntrans address
		translation subsystem.
20060216	Adding ARM ldrd (double-register load).
20060217	Continuing on various ARM-related stuff.
20060218	More progress on the ATA/wdc emulation for NetBSD/iq80321.
		NetBSD/evbarm can now be installed :-)  Updating the docs, etc.
		Continuing on Algor emulation.

==============  RELEASE 0.3.8  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26