/[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 42 - (hide annotations)
Mon Oct 8 16:22:32 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 23321 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1613 2007/06/15 20:11:26 debug Exp $
20070501	Continuing a little on m88k disassembly (control registers,
		more instructions).
		Adding a dummy mvme88k machine mode.
20070502	Re-adding MIPS load/store alignment exceptions.
20070503	Implementing more of the M88K disassembly code.
20070504	Adding disassembly of some more M88K load/store instructions.
		Implementing some relatively simple M88K instructions (br.n,
		xor[.u] imm, and[.u] imm).
20070505	Implementing M88K three-register and, or, xor, and jmp[.n],
		bsr[.n] including function call trace stuff.
		Applying a patch from Bruce M. Simpson which implements the
		SYSCON_BOARD_CPU_CLOCK_FREQ_ID object of the syscon call in
		the yamon PROM emulation.
20070506	Implementing M88K bb0[.n] and bb1[.n], and skeletons for
		ldcr and stcr (although no control regs are implemented yet).
20070509	Found and fixed the bug which caused Linux for QEMU_MIPS to
		stop working in 0.4.5.1: It was a faulty change to the MIPS
		'sc' and 'scd' instructions I made while going through gcc -W
		warnings on 20070428.
20070510	Updating the Linux/QEMU_MIPS section in guestoses.html to
		use mips-test-0.2.tar.gz instead of 0.1.
		A big thank you to Miod Vallat for sending me M88K manuals.
		Implementing more M88K instructions (addu, subu, div[u], mulu,
		ext[u], clr, set, cmp).
20070511	Fixing bugs in the M88K "and" and "and.u" instructions (found
		by comparing against the manual).
		Implementing more M88K instructions (mask[.u], mak, bcnd (auto-
		generated)) and some more control register details.
		Cleanup: Removing the experimental AVR emulation mode and
		corresponding devices; AVR emulation wasn't really meaningful.
		Implementing autogeneration of most M88K loads/stores. The
		rectangle drawing demo (with -O0) for M88K runs :-)
		Beginning on M88K exception handling.
		More M88K instructions: tb0, tb1, rte, sub, jsr[.n].
		Adding some skeleton MVME PROM ("BUG") emulation.
20070512	Fixing a bug in the M88K cmp instruction.
		Adding the M88K lda (scaled register) instruction.
		Fixing bugs in 64-bit (32-bit pairs) M88K loads/stores.
		Removing the unused tick_hz stuff from the machine struct.
		Implementing the M88K xmem instruction. OpenBSD/mvme88k gets
		far enough to display the Copyright banner :-)
		Implementing subu.co (guess), addu.co, addu.ci, ff0, and ff1.
		Adding a dev_mvme187, for MVME187-specific devices/registers.
		OpenBSD/mvme88k prints more boot messages. :)
20070515	Continuing on MVME187 emulation (adding more devices, beginning
		on the CMMUs, etc).
		Adding the M88K and.c, xor.c, and or.c instructions, and making
		sure that mul, div, etc cause exceptions if executed when SFD1
		is disabled.
20070517	Continuing on M88K and MVME187 emulation in general; moving
		the CMMU registers to the CPU struct, separating dev_pcc2 from
		dev_mvme187, and beginning on memory_m88k.c (BATC and PATC).
		Fixing a bug in 64-bit (32-bit pairs) M88K fast stores.
		Implementing the clock part of dev_mk48txx.
		Implementing the M88K fstcr and xcr instructions.
		Implementing m88k_cpu_tlbdump().
		Beginning on the implementation of a separate address space
		for M88K .usr loads/stores.
20070520	Removing the non-working (skeleton) Sandpoint, SonyNEWS, SHARK
		Dnard, and Zaurus machine modes.
		Experimenting with dyntrans to_be_translated read-ahead. It
		seems to give a very small performance increase for MIPS
		emulation, but a large performance degradation for SuperH. Hm.
20070522	Disabling correct SuperH ITLB emulation; it does not seem to be
		necessary in order to let SH4 guest OSes run, and it slows down
		userspace code.
		Implementing "samepage" branches for SuperH emulation, and some
		other minor speed hacks.
20070525	Continuing on M88K memory-related stuff: exceptions, memory
		transaction register contents, etc.
		Implementing the M88K subu.ci instruction.
		Removing the non-working (skeleton) Iyonix machine mode.
		OpenBSD/mvme88k reaches userland :-), starts executing
		/sbin/init's instructions, and issues a few syscalls, before
		crashing.
20070526	Fixing bugs in dev_mk48txx, so that OpenBSD/mvme88k detects
		the correct time-of-day.
		Implementing a generic IRQ controller for the test machines
		(dev_irqc), similar to a proposed patch from Petr Stepan.
		Experimenting some more with translation read-ahead.
		Adding an "expect" script for automated OpenBSD/landisk
		install regression/performance tests.
20070527	Adding a dummy mmEye (SH3) machine mode skeleton.
		FINALLY found the strange M88K bug I have been hunting: I had
		not emulated the SNIP value for exceptions occurring in
		branch delay slots correctly.
		Implementing correct exceptions for 64-bit M88K loads/stores.
		Address to symbol lookups are now disabled when M88K is
		running in usermode (because usermode addresses don't have
		anything to do with supervisor addresses).
20070531	Removing the mmEye machine mode skeleton.
20070604	Some minor code cleanup.
20070605	Moving src/useremul.c into a subdir (src/useremul/), and
		cleaning up some more legacy constructs.
		Adding -Wstrict-aliasing and -fstrict-aliasing detection to
		the configure script.
20070606	Adding a check for broken GCC on Solaris to the configure
		script. (GCC 3.4.3 on Solaris cannot handle static variables
		which are initialized to 0 or NULL. :-/)
		Removing the old (non-working) ARC emulation modes: NEC RD94,
		R94, R96, and R98, and the last traces of Olivetti M700 and
		Deskstation Tyne.
		Removing the non-working skeleton WDSC device (dev_wdsc).
20070607	Thinking about how to use the host's cc + ld at runtime to
		generate native code. (See experiments/native_cc_ld_test.i
		for an example.)
20070608	Adding a program counter sampling timer, which could be useful
		for native code generation experiments.
		The KN02_CSR_NRMMOD bit in the DECstation 5000/200 (KN02) CSR
		should always be set, to allow a 5000/200 PROM to boot.
20070609	Moving out breakpoint details from the machine struct into
		a helper struct, and removing the limit on max nr of
		breakpoints.
20070610	Moving out tick functions into a helper struct as well (which
		also gets rid of the max limit).
20070612	FINALLY figured out why Debian/DECstation stopped working when
		translation read-ahead was enabled: in src/memory_rw.c, the
		call to invalidate_code_translation was made also if the
		memory access was an instruction load (if the page was mapped
		as writable); it shouldn't be called in that case.
20070613	Implementing some more MIPS32/64 revision 2 instructions: di,
		ei, ext, dext, dextm, dextu, and ins.
20070614	Implementing an instruction combination for the NetBSD/arm
		idle loop (making the host not use any cpu if NetBSD/arm
		inside the emulator is not using any cpu).
		Increasing the nr of ARM VPH entries from 128 to 384.
20070615	Removing the ENABLE_arch stuff from the configure script, so
		that all included architectures are included in both release
		and development builds.
		Moving memory related helper functions from misc.c to memory.c.
		Adding preliminary instructions for netbooting NetBSD/pmppc to
		guestoses.html; it doesn't work yet, there are weird timeouts.
		Beginning a total rewrite of the userland emulation modes
		(removing all emulation modes, beginning from scratch with
		NetBSD/MIPS and FreeBSD/Alpha only).
20070616	After fixing a bug in the DEC21143 NIC (the TDSTAT_OWN bit was
		only cleared for the last segment when transmitting, not all
		segments), NetBSD/pmppc boots with root-on-nfs without the
		timeouts. Updating guestoses.html.
		Removing the skeleton PSP (Playstation Portable) mode.
		Moving X11-related stuff in the machine struct into a helper
		struct.
		Cleanup of out-of-memory checks, to use a new CHECK_ALLOCATION
		macro (which prints a meaningful error message).
		Adding a COMMENT to each machine and device (for automagic
		.index comment generation).
		Doing regression testing for the next release.

==============  RELEASE 0.4.6  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26