/[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 24 - (hide annotations)
Mon Oct 8 16:19:56 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 22115 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1256 2006/06/23 20:43:44 debug Exp $
20060219	Various minor updates. Removing the old MIPS16 skeleton code,
		because it will need to be rewritten for dyntrans anyway.
20060220-22	Removing the non-working dyntrans backend support.
		Continuing on the 64-bit dyntrans virtual memory generalization.
20060223	More work on the 64-bit vm generalization.
20060225	Beginning on MIPS dyntrans load/store instructions.
		Minor PPC updates (64-bit load/store, etc).
		Fixes for the variable-instruction-length framework, some
		minor AVR updates (a simple Hello World program works!).
		Beginning on a skeleton for automatically generating documen-
		tation (for devices etc.).
20060226	PPC updates (adding some more 64-bit instructions, etc).
		AVR updates (more instructions).
		FINALLY found and fixed the zs bug, making NetBSD/macppc
		accept the serial console.
20060301	Adding more AVR instructions.
20060304	Continuing on AVR-related stuff. Beginning on a framework for
		cycle-accurate device emulation. Adding an experimental "PAL
		TV" device (just a dummy so far).
20060305	Adding more AVR instructions.
		Adding a dummy epcom serial controller (for TS7200 emulation).
20060310	Removing the emul() command from configuration files, so only
		net() and machine() are supported.
		Minor progress on the MIPS dyntrans rewrite.
20060311	Continuing on the MIPS dyntrans rewrite (adding more
		instructions, etc).
20060315	Adding more instructions (sllv, srav, srlv, bgtz[l], blez[l],
		beql, bnel, slti[u], various loads and stores).
20060316	Removing the ALWAYS_SIGNEXTEND_32 option, since it was rarely
		used.
		Adding more MIPS dyntrans instructions, and fixing bugs.
20060318	Implementing fast loads/stores for MIPS dyntrans (big/little
		endian, 32-bit and 64-bit modes).
20060320	Making MIPS dyntrans the default configure option; use
		"--enable-oldmips" to use the old bintrans system.
		Adding MIPS dyntrans dmult[u]; minor updates.
20060322	Continuing... adding some more instructions.
		Adding a simple skeleton for demangling C++ "_ZN" symbols.
20060323	Moving src/debugger.c into a new directory (src/debugger/).
20060324	Fixing the hack used to load PPC ELFs (useful for relocated
		Linux/ppc kernels), and adding a dummy G3 machine mode.
20060325-26	Beginning to experiment with GDB remote serial protocol
		connections; adding a -G command line option for selecting
		which TCP port to listen to.
20060330	Beginning a major cleanup to replace things like "0x%016llx"
		with more correct "0x%016"PRIx64, etc.
		Continuing on the GDB remote serial protocol support.
20060331	More cleanup, and some minor GDB remote progress.
20060402	Adding a hack to the configure script, to allow compilation
		on systems that lack PRIx64 etc.
20060406	Removing the temporary FreeBSD/arm hack in dev_ns16550.c and
		replacing it with a better fix from Olivier Houchard.
20060407	A remote debugger (gdb or ddd) can now start and stop the
		emulator using the GDB remote serial protocol, and registers
		and memory can be read. MIPS only for now.
20060408	More GDB progress: single-stepping also works, and also adding
		support for ARM, PowerPC, and Alpha targets.
		Continuing on the delay-slot-across-page-boundary issue.
20060412	Minor update: beginning to add support for the SPARC target
		to the remote GDB functionality.
20060414	Various MIPS updates: adding more instructions for dyntrans
		(eret, add), and making some exceptions work. Fixing a bug
		in dmult[u].
		Implementing the first SPARC instructions (sethi, or).
20060415	Adding "magic trap" instructions so that PROM calls can be
		software emulated in MIPS dyntrans.
		Adding more MIPS dyntrans instructions (ddiv, dadd) and
		fixing another bug in dmult.
20060416	More MIPS dyntrans progress: adding [d]addi, movn, movz, dsllv,
		rfi, an ugly hack for supporting R2000/R3000 style faked caches,
		preliminary interrupt support, and various other updates and
		bugfixes.
20060417	Adding more SPARC instructions (add, sub, sll[x], sra[x],
		srl[x]), and useful SPARC header definitions.
		Adding the first (trivial) x86/AMD64 dyntrans instructions (nop,
		cli/sti, stc/clc, std/cld, simple mov, inc ax). Various other
		x86 updates related to variable instruction length stuff.
		Adding unaligned loads/stores to the MIPS dyntrans mode (but
		still using the pre-dyntrans (slow) imlementation).
20060419	Fixing a MIPS dyntrans exception-in-delay-slot bug.
		Removing the old "show opcode statistics" functionality, since
		it wasn't really useful and isn't implemented for dyntrans.
		Single-stepping (or running with instruction trace) now looks
		ok with dyntrans with delay-slot architectures.
20060420	Minor hacks (removing the -B command line option when compiled
		for non-bintrans, and some other very minor updates).
		Adding (slow) MIPS dyntrans load-linked/store-conditional.
20060422	Applying fixes for bugs discovered by Nils Weller's nwcc
		(static DEC memmap => now per machine, and adding an extern
		keyword in cpu_arm_instr.c).
		Finally found one of the MIPS dyntrans bugs that I've been
		looking for (copy/paste spelling error BIG vs LITTLE endian in
		cpu_mips_instr_loadstore.c for 16-bit fast stores).
		FINALLY found the major MIPS dyntrans bug: slti vs sltiu
		signed/unsigned code in cpu_mips_instr.c. :-)
		Adding more MIPS dyntrans instructions (lwc1, swc1, bgezal[l],
		ctc1, tlt[u], tge[u], tne, beginning on rdhwr).
		NetBSD/hpcmips can now reach userland when using dyntrans :-)
		Adding some more x86 dyntrans instructions.
		Finally removed the old Alpha-specific virtual memory code,
		and replaced it with the generic 64-bit version.
		Beginning to add disassembly support for SPECIAL3 MIPS opcodes.
20060423	Continuing on the delay-slot-across-page-boundary issue;
		adding an end_of_page2 ic slot (like I had planned before, but
		had removed for some reason).
		Adding a quick-and-dirty fallback to legacy coprocessor 1
		code (i.e. skipping dyntrans implementation for now).
		NetBSD/hpcmips and NetBSD/pmax (when running on an emulated
		R4400) can now be installed and run. :-)  (Many bugs left
		to fix, though.)
		Adding more MIPS dyntrans instructions: madd[u], msub[u].
		Cleaning up the SPECIAL2 vs R5900/TX79/C790 "MMI" opcode
		maps somewhat (disassembly and dyntrans instruction decoding).
20060424	Adding an isa_revision field to mips_cpu_types.h, and making
		sure that SPECIAL3 opcodes cause Reserved Instruction
		exceptions on MIPS32/64 revisions lower than 2.
		Adding the SPARC 'ba', 'call', 'jmpl/retl', 'and', and 'xor'
		instructions.
20060425	Removing the -m command line option ("run at most x 
		instructions") and -T ("single_step_on_bad_addr"), because
		they never worked correctly with dyntrans anyway.
		Freshening up the man page.
20060428	Adding more MIPS dyntrans instructions: bltzal[l], idle.
		Enabling MIPS dyntrans compare interrupts.
20060429	FINALLY found the weird dyntrans bug, causing NetBSD etc. to
		behave strangely: some floating point code (conditional
		coprocessor branches) could not be reused from the old
		non-dyntrans code. The "quick-and-dirty fallback" only appeared
		to work. Fixing by implementing bc1* for MIPS dyntrans.
		More MIPS instructions: [d]sub, sdc1, ldc1, dmtc1, dmfc1, cfc0.
		Freshening up MIPS floating point disassembly appearance.
20060430	Continuing on C790/R5900/TX79 disassembly; implementing 128-bit
		"por" and "pextlw".
20060504	Disabling -u (userland emulation) unless compiled as unstable
		development version.
		Beginning on freshening up the testmachine include files,
		to make it easier to reuse those files (placing them in
		src/include/testmachine/), and beginning on a set of "demos"
		or "tutorials" for the testmachine functionality.
		Minor updates to the MIPS GDB remote protocol stub.
		Refreshing doc/experiments.html and gdb_remote.html.
		Enabling Alpha emulation in the stable release configuration,
		even though no guest OSes for Alpha can run yet.
20060505	Adding a generic 'settings' object, which will contain
		references to settable variables (which will later be possible
		to access using the debugger).
20060506	Updating dev_disk and corresponding demo/documentation (and
		switching from SCSI to IDE disk types, so it actually works
		with current test machines :-).
20060510	Adding a -D_LARGEFILE_SOURCE hack for 64-bit Linux hosts,
		so that fseeko() doesn't give a warning.
		Updating the section about how dyntrans works (the "runnable
		IR") in doc/intro.html.
		Instruction updates (some x64=1 checks, some more R5900
		dyntrans stuff: better mul/mult separation from MIPS32/64,
		adding ei and di).
		Updating MIPS cpuregs.h to a newer one (from NetBSD).
		Adding more MIPS dyntrans instructions: deret, ehb.
20060514	Adding disassembly and beginning implementation of SPARC wr
		and wrpr instructions.
20060515	Adding a SUN SPARC machine mode, with dummy SS20 and Ultra1
		machines. Adding the 32-bit "rd psr" instruction.
20060517	Disassembly support for the general SPARC rd instruction.
		Partial implementation of the cmp (subcc) instruction.
		Some other minor updates (making sure that R5900 processors
		start up with the EIE bit enabled, otherwise Linux/playstation2
		receives no interrupts).
20060519	Minor MIPS updates/cleanups.
20060521	Moving the MeshCube machine into evbmips; this seems to work
		reasonably well with a snapshot of a NetBSD MeshCube kernel.
		Cleanup/fix of MIPS config0 register initialization.
20060529	Minor MIPS fixes, including a sign-extension fix to the
		unaligned load/store code, which makes NetBSD/pmax on R3000
		work better with dyntrans. (Ultrix and Linux/DECstation still
		don't work, though.)
20060530	Minor updates to the Alpha machine mode: adding an AlphaBook
		mode, an LCA bus (forwarding accesses to an ISA bus), etc.
20060531	Applying a bugfix for the MIPS dyntrans sc[d] instruction from
		Ondrej Palkovsky. (Many thanks.)
20060601	Minifix to allow ARM immediate msr instruction to not give
		an error for some valid values.
		More Alpha updates.
20060602	Some minor Alpha updates.
20060603	Adding the Alpha cmpbge instruction. NetBSD/alpha prints its
		first boot messages :-) on an emulated Alphabook 1.
20060612	Minor updates; adding a dev_ether.h include file for the
		testmachine ether device. Continuing the hunt for the dyntrans
		bug which makes Linux and Ultrix on DECstation behave
		strangely... FINALLY found it! It seems to be related to
		invalidation of the translation cache, on tlbw{r,i}. There
		also seems to be some remaining interrupt-related problems.
20060614	Correcting the implementation of ldc1/sdc1 for MIPS dyntrans
		(so that it uses 16 32-bit registers if the FR bit in the
		status register is not set).
20060616	REMOVING BINTRANS COMPLETELY!
		Removing the old MIPS interpretation mode.
		Removing the MFHILO_DELAY and instruction delay stuff, because
		they wouldn't work with dyntrans anyway.
20060617	Some documentation updates (adding "NetBSD-archive" to some
		URLs, and new Debian/DECstation installation screenshots).
		Removing the "tracenull" and "enable-caches" configure options.
		Improving MIPS dyntrans performance somewhat (only invalidate
		translations if necessary, on writes to the entryhi register,
		instead of doing it for all cop0 writes).
20060618	More cleanup after the removal of the old MIPS emulation.
		Trying to fix the MIPS dyntrans performance bugs/bottlenecks;
		only semi-successful so far (for R3000).
20060620	Minor update to allow clean compilation again on Tru64/Alpha.
20060622	MIPS cleanup and fixes (removing the pc_last stuff, which
		doesn't make sense with dyntrans anyway, and fixing a cross-
		page-delay-slot-with-exception case in end_of_page).
		Removing the old max_random_cycles_per_chunk stuff, and the
		concept of cycles vs instructions for MIPS emulation.
		FINALLY found and fixed the bug which caused NetBSD/pmax
		clocks to behave strangely (it was a load to the zero register,
		which was treated as a NOP; now it is treated as a load to a
		dummy scratch register).
20060623	Increasing the dyntrans chunk size back to
		N_SAFE_DYNTRANS_LIMIT, instead of N_SAFE_DYNTRANS_LIMIT/2.
		Preparing for a quick release, even though there are known
		bugs, and performance for non-R3000 MIPS emulation is very
		poor. :-/
		Reverting to half the dyntrans chunk size again, because
		NetBSD/cats seemed less stable with full size chunks. :(
		NetBSD/sgimips 3.0 can now run :-)  (With release 0.3.8, only
		NetBSD/sgimips 2.1 worked, not 3.0.)

==============  RELEASE 0.4.0  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26