main.cc Source File

Back to the index.

main.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2018 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * GXemul's main entry point.
29  */
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 "ComponentFactory.h"
39 #include "console.h"
40 #include "cpu.h"
41 #include "debugger.h"
42 #include "device.h"
43 #include "diskimage.h"
44 #include "emul.h"
45 #include "GXemul.h"
46 #include "machine.h"
47 #include "misc.h"
48 #include "settings.h"
49 #include "timer.h"
50 #include "UnitTest.h"
51 
52 
53 extern int single_step;
54 extern int force_debugger_at_exit;
55 
56 extern int optind;
57 extern char *optarg;
58 
60 
62 char **extra_argv;
63 char *progname;
64 
66 static int skip_srandom_call = 0;
67 
68 
69 /*****************************************************************************
70  *
71  * NOTE: debug(), fatal(), and debug_indentation() are not re-entrant.
72  * The global variable quiet_mode can be used to suppress the output
73  * of debug(), but not the output of fatal().
74  *
75  *****************************************************************************/
76 
77 int verbose = 0;
78 int quiet_mode = 0;
79 
80 static int debug_indent = 0;
81 static int debug_currently_at_start_of_line = 1;
82 
83 
84 /*
85  * va_debug():
86  *
87  * Used internally by debug() and fatal().
88  */
89 static void va_debug(va_list argp, const char *fmt)
90 {
91  char buf[DEBUG_BUFSIZE + 1];
92  char *s;
93  int i;
94 
95  buf[0] = buf[DEBUG_BUFSIZE] = 0;
96  vsnprintf(buf, DEBUG_BUFSIZE, fmt, argp);
97 
98  s = buf;
99  while (*s) {
100  if (debug_currently_at_start_of_line) {
101  for (i=0; i<debug_indent; i++)
102  printf(" ");
103  }
104 
105  printf("%c", *s);
106 
107  debug_currently_at_start_of_line = 0;
108  if (*s == '\n' || *s == '\r')
109  debug_currently_at_start_of_line = 1;
110  s++;
111  }
112 }
113 
114 
115 /*
116  * debug_indentation():
117  *
118  * Modify the debug indentation.
119  */
120 void debug_indentation(int diff)
121 {
122  debug_indent += diff;
123  if (debug_indent < 0)
124  fprintf(stderr, "WARNING: debug_indent less than 0!\n");
125 }
126 
127 
128 /*
129  * debug():
130  *
131  * Debug output (ignored if quiet_mode is set).
132  */
133 void debug(const char *fmt, ...)
134 {
135  va_list argp;
136 
137  if (quiet_mode)
138  return;
139 
140  va_start(argp, fmt);
141  va_debug(argp, fmt);
142  va_end(argp);
143 }
144 
145 
146 /*
147  * fatal():
148  *
149  * Fatal works like debug(), but doesn't care about the quiet_mode
150  * setting.
151  */
152 void fatal(const char *fmt, ...)
153 {
154  va_list argp;
155 
156  va_start(argp, fmt);
157  va_debug(argp, fmt);
158  va_end(argp);
159 }
160 
161 
162 /*****************************************************************************/
163 
164 
165 /*
166  * internal_w():
167  *
168  * For internal use by gxemul itself.
169  */
170 void internal_w(char *arg)
171 {
172  if (arg == NULL || strncmp(arg, "W@", 2) != 0) {
173  fprintf(stderr, "-W is for internal use by gxemul,"
174  " not for manual use.\n");
175  exit(1);
176  }
177 
178  arg += 2;
179 
180  switch (arg[0]) {
181  case 'C':
183  exit(0);
184  break;
185  case 'D':
186  GXemul::DumpMachineAsHTML(arg + 1);
187  break;
188  case 'S':
189  console_slave(arg + 1);
190  break;
191  case 'M':
193  exit(0);
194  break;
195  case 'U':
196  {
197  int result = UnitTest::RunTests();
198 
199  // Hack to prevent leaks:
201 
202 #ifndef NDEBUG
203  int leaks = check_leaks();
204  if (leaks > 0) {
205  cerr << "Having memory leaks counts as failure to run the tests!\n";
206  exit(1);
207  }
208 #endif
209 
210  exit(result);
211  }
212  break;
213  default:
214  fprintf(stderr, "internal_w(): UNIMPLEMENTED arg = '%s'\n",
215  arg);
216  }
217 }
218 
219 
220 /*****************************************************************************/
221 
222 
223 /*
224  * usage():
225  *
226  * Prints program usage to stdout.
227  */
228 static void usage(int longusage)
229 {
230 
231  printf("GXemul " VERSION" " COPYRIGHT_MSG"\n" SECONDARY_MSG);
232  printf("Read the source code and/or documentation for "
233  "other Copyright messages.\n");
234 
235  printf("\nUsage: %s [options] -e name [additional components and files [...]]\n", progname);
236  printf(" or %s [options] configfile\n", progname);
237  printf(" or %s -H\n", progname);
238  printf(" or %s -V\n", progname);
239 
240  if (longusage) {
241  printf("\nOptions:\n");
242  printf(" -B Enable snapshotting (reverse stepping support).\n");
243  printf(" -H Display a list of available machine templates.\n");
244  printf(" -e name Start with a machine based on template 'name'.\n");
245  printf(" -q Quiet mode (suppress debug messages).\n");
246  printf(" -V Start up in interactive debugging mode, paused.\n");
247  printf("\n");
248  }
249 
250  if (!longusage) {
251  printf("\nLegacy usage: %s [machine, other, and general options] [file "
252  "[...]]\n", progname);
253  printf(" or %s [general options] @configfile\n", progname);
254 
255  printf("\nRun %s -h for help on command line options.\n",
256  progname);
257  return;
258  }
259 
260  printf("\nThe following are options for the Old framework:\n");
261 
262  printf("\nLegacy usage: %s [machine, other, and general options] [file "
263  "[...]]\n", progname);
264  printf(" or %s [general options] @configfile\n", progname);
265 
266  printf("\nMachine selection options:\n");
267  printf(" -E t try to emulate machine type t. (Use -H to get "
268  "a list of types.)\n");
269  printf(" -e st try to emulate machine subtype st. (Use this "
270  "with -E.)\n");
271 
272  printf("\nOther options:\n");
273  printf(" -C x try to emulate a specific CPU. (Use -H to get a "
274  "list of types.)\n");
275  printf(" -d fname add fname as a disk image. You can add \"xxx:\""
276  " as a prefix\n");
277  printf(" where xxx is one or more of the following:\n");
278  printf(" b specifies that this is the boot"
279  " device\n");
280  printf(" c CD-ROM\n");
281  printf(" d DISK\n");
282  printf(" f FLOPPY\n");
283  printf(" gH;S; set geometry to H heads and S"
284  " sectors-per-track\n");
285  printf(" i IDE\n");
286  printf(" oOFS; set base offset to OFS (for ISO9660"
287  " filesystems)\n");
288  printf(" r read-only (don't allow changes to the"
289  " file)\n");
290  printf(" s SCSI\n");
291  printf(" t tape\n");
292  printf(" V add an overlay\n");
293  printf(" 0-7 force a specific ID\n");
294  printf(" -I hz set the main cpu frequency to hz (not used by "
295  "all combinations\n of machines and guest OSes)\n");
296  printf(" -i display each instruction as it is executed\n");
297  printf(" -J disable dyntrans instruction combinations\n");
298  printf(" -j name set the name of the kernel; for DECstation "
299  "emulation, this passes\n the name to the bootloader,"
300  " for example:\n");
301  printf(" -j netbsd (NetBSD/pmax) "
302  "-j bsd (OpenBSD/pmax)\n");
303  printf(" -j vmsprite (Sprite/pmax) "
304  "-j vmunix (Ultrix/RISC)\n");
305  printf(" For other emulation modes, if the boot disk is an"
306  " ISO9660\n filesystem, -j sets the name of the"
307  " kernel to load.\n");
308  printf(" -M m emulate m MBs of physical RAM\n");
309  printf(" -N display nr of instructions/second average, at"
310  " regular intervals\n");
311  printf(" -n nr set nr of CPUs (for SMP experiments)\n");
312  printf(" -O force netboot (tftp instead of disk), even when"
313  " a disk image is\n"
314  " present (for DECstation, SGI, and ARC emulation)\n");
315  printf(" -o arg set the boot argument, for DEC, ARC, or SGI"
316  " emulation\n");
317  printf(" (default arg for DEC is -a, for ARC/SGI -aN)\n");
318  printf(" -p pc add a breakpoint (remember to use the '0x' "
319  "prefix for hex!)\n");
320  printf(" -Q no built-in PROM emulation (use this for "
321  "running ROM images)\n");
322  printf(" -R use random bootstrap cpu, instead of nr 0\n");
323  printf(" -r register dumps before every instruction\n");
324  printf(" -S initialize emulated RAM to random bytes, "
325  "instead of zeroes\n");
326  printf(" -s f:name write statistics to file 'name', "
327  "f is one or more of the following:\n");
328  printf(" v virtual program counter\n");
329  printf(" p physical equivalent of program counter\n");
330  printf(" i internal ic->f representation of "
331  "the program counter\n");
332  printf(" and optionally:\n");
333  printf(" d disable statistics gathering at "
334  "startup\n");
335  printf(" o overwrite instead of append\n");
336  printf(" -T halt on non-existant memory accesses\n");
337  printf(" -t show function trace tree\n");
338  printf(" -U enable slow_serial_interrupts_hack_for_linux\n");
339 #ifdef WITH_X11
340  printf(" -X use X11\n");
341  printf(" -x open up new xterms for emulated serial ports "
342  "(default is on when\n using configuration files or"
343  " when X11 is used, off otherwise)\n");
344  printf(" -Y n scale down framebuffer windows by n x n times\n");
345 #endif /* WITH_X11 */
346  printf(" -Z n set nr of graphics cards, for emulating a "
347  "dual-head or tripple-head\n"
348  " environment (only for DECstation emulation)\n");
349  printf(" -z disp add disp as an X11 display to use for "
350  "framebuffers\n");
351 
352  printf("\nGeneral options:\n");
353  printf(" -c cmd add cmd as a command to run before starting "
354  "the simulation\n");
355  printf(" -D skip the srandom call at startup\n");
356  printf(" -H display a list of possible CPU and "
357  "machine types\n");
358  printf(" -h display this help message\n");
359  printf(" -k n set dyntrans translation caches to n MB (default"
360  " size is %i MB)\n", DEFAULT_DYNTRANS_CACHE_SIZE / 1048576);
361  printf(" -K force the debugger to be entered at the end "
362  "of a simulation\n");
363  printf(" -q quiet mode (don't print startup messages)\n");
364  printf(" -V start up in the single-step debugger, paused\n");
365  printf(" -v increase debug message verbosity\n");
366  printf("\n");
367  printf("If you are selecting a machine type to emulate directly "
368  "on the command line,\nthen you must specify one or more names"
369  " of files that you wish to load into\n"
370  "memory. Supported formats are: ELF a.out ecoff srec syms raw\n"
371  "where syms is the text produced by running 'nm' (or 'nm -S') "
372  "on a binary.\n"
373  "To load a raw binary into memory, add \"address:\" in front "
374  "of the filename,\n"
375  "or \"address:skiplen:\" or \"address:skiplen:initialpc:\".\n"
376  "\nExamples:\n"
377  " 0xbfc00000:rom.bin for a raw ROM image\n"
378  " 0xbfc00000:0x100:rom.bin for an image with "
379  "0x100 bytes header\n"
380  " 0xbfc00000:0x100:0xbfc00884:rom.bin "
381  "start with pc=0xbfc00884\n\n");
382 }
383 
384 
385 /*
386  * get_cmd_args():
387  *
388  * Reads command line arguments.
389  */
390 int get_cmd_args(int argc, char *argv[], struct emul *emul,
391  char ***diskimagesp, int *n_diskimagesp)
392 {
393  int ch, res, using_switch_d = 0, using_switch_Z = 0;
394  int using_switch_e = 0, using_switch_E = 0;
395  bool using_switch_B = false;
396  char *type = NULL, *subtype = NULL;
397  int n_cpus_set = 0;
398  int msopts = 0; /* Machine-specific options used */
399  struct machine *m = emul_add_machine(emul, NULL);
400 
401  const char *opts =
402  "BC:c:Dd:E:e:HhI:iJj:k:KM:Nn:Oo:p:QqRrSs:TtUVvW:"
403 #ifdef WITH_X11
404  "XxY:"
405 #endif
406  "Z:z:";
407 
408  while ((ch = getopt(argc, argv, opts)) != -1) {
409  switch (ch) {
410  case 'B':
411  using_switch_B = true;
412  break;
413  case 'C':
414  CHECK_ALLOCATION(m->cpu_name = strdup(optarg));
415  msopts = 1;
416  break;
417  case 'c':
418  emul->n_debugger_cmds ++;
419  CHECK_ALLOCATION(emul->debugger_cmds = (char **)
420  realloc(emul->debugger_cmds,
421  emul->n_debugger_cmds * sizeof(char *)));
423  n_debugger_cmds-1] = strdup(optarg));
424  break;
425  case 'D':
426  skip_srandom_call = 1;
427  break;
428  case 'd':
429  /* diskimage_add() is called further down */
430  (*n_diskimagesp) ++;
431  CHECK_ALLOCATION( (*diskimagesp) = (char **)
432  realloc(*diskimagesp,
433  sizeof(char *) * (*n_diskimagesp)) );
434  CHECK_ALLOCATION( (*diskimagesp)[(*n_diskimagesp) - 1] =
435  strdup(optarg) );
436  using_switch_d = 1;
437  msopts = 1;
438  break;
439  case 'E':
440  if (using_switch_E ++ > 0) {
441  fprintf(stderr, "-E already used.\n");
442  exit(1);
443  }
444  type = optarg;
445  msopts = 1;
446  break;
447  case 'e':
448  if (using_switch_e ++ > 0) {
449  fprintf(stderr, "-e already used.\n");
450  exit(1);
451  }
452  subtype = optarg;
453  msopts = 1;
454  break;
455  case 'H':
457  printf("--------------------------------------------------------------------------\n\n");
458  printf("The following applies to the LEGACY modes only:\n\n");
460  exit(1);
461  case 'h':
462  usage(1);
463  exit(1);
464  case 'I':
465  m->emulated_hz = atoi(optarg);
466  msopts = 1;
467  break;
468  case 'i':
469  m->instruction_trace = 1;
470  msopts = 1;
471  break;
472  case 'J':
474  msopts = 1;
475  break;
476  case 'j':
478  strdup(optarg));
479  msopts = 1;
480  break;
481  case 'k':
482  dyntrans_cache_size = atoi(optarg) * 1048576;
483  if (dyntrans_cache_size < 1) {
484  fprintf(stderr, "The dyntrans cache size must"
485  " be at least 1 MB.\n");
486  exit(1);
487  }
488  break;
489  case 'K':
491  break;
492  case 'M':
493  m->physical_ram_in_mb = atoi(optarg);
494  msopts = 1;
495  break;
496  case 'N':
498  msopts = 1;
499  break;
500  case 'n':
501  m->ncpus = atoi(optarg);
502  n_cpus_set = 1;
503  msopts = 1;
504  break;
505  case 'O':
506  m->force_netboot = 1;
507  msopts = 1;
508  break;
509  case 'o':
511  strdup(optarg));
512  msopts = 1;
513  break;
514  case 'p':
516  msopts = 1;
517  break;
518  case 'Q':
519  m->prom_emulation = 0;
520  msopts = 1;
521  break;
522  case 'q':
523  quiet_mode = 1;
524  break;
525  case 'R':
527  msopts = 1;
528  break;
529  case 'r':
530  m->register_dump = 1;
531  msopts = 1;
532  break;
533  case 'S':
534  m->random_mem_contents = 1;
535  msopts = 1;
536  break;
537  case 's':
539  msopts = 1;
540  break;
541  case 'T':
543  msopts = 1;
544  break;
545  case 't':
546  m->show_trace_tree = 1;
547  msopts = 1;
548  break;
549  case 'U':
551  msopts = 1;
552  break;
553  case 'V':
555  break;
556  case 'v':
557  verbose ++;
558  break;
559  case 'W':
561  exit(0);
562  case 'X':
563  m->x11_md.in_use = 1;
564  msopts = 1;
565  /* FALL-THROUGH */
566  case 'x':
568  break;
569  case 'Y':
570  m->x11_md.scaledown = atoi(optarg);
571  if (m->x11_md.scaledown < -1) {
572  m->x11_md.scaleup = - m->x11_md.scaledown;
573  m->x11_md.scaledown = 1;
574  }
575  if (m->x11_md.scaledown < 1) {
576  fprintf(stderr, "Invalid scaledown value.\n");
577  exit(1);
578  }
579  msopts = 1;
580  break;
581  case 'Z':
582  m->n_gfx_cards = atoi(optarg);
583  using_switch_Z = 1;
584  msopts = 1;
585  break;
586  case 'z':
587  m->x11_md.n_display_names ++;
588  CHECK_ALLOCATION(m->x11_md.display_names = (char **) realloc(
590  m->x11_md.n_display_names * sizeof(char *)));
592  m->x11_md.n_display_names-1] = strdup(optarg));
593  msopts = 1;
594  break;
595  default:
596  fprintf(stderr, "Run %s -h for help on command "
597  "line options.\n", progname);
598  exit(1);
599  }
600  }
601 
602  argc -= optind;
603  argv += optind;
604 
605  extra_argc = argc;
606  extra_argv = argv;
607 
608  // If -V is used, -q is ignored.
610  quiet_mode = 0;
611 
612  if (type == NULL && subtype == NULL &&
613  (single_step == ENTER_SINGLE_STEPPING || (argc > 0 && argv[0][0] != '@'))) {
614  int res2 = 0;
615  {
616  GXemul gxemul;
617  gxemul.InitUI();
618 
620  gxemul.SetRunState(GXemul::Paused);
621  else
623 
624  gxemul.SetSnapshottingEnabled(using_switch_B);
625 
626  if (quiet_mode)
627  gxemul.SetQuietMode(true);
628 
629  if (argc > 0 && !gxemul.ParseFilenames("", argc, argv))
630  res = 1;
631 
632  if (res2 == 0)
633  res2 = gxemul.Run();
634  }
635 
636  // Note: exit() is outside the GXemul scope, so that GXemul's
637  // destructor runs.
638  exit(res2);
639  }
640 
641  if (type != NULL || subtype != NULL) {
642  if (type == NULL)
643  type = strdup("");
644  if (subtype == NULL)
645  subtype = strdup("");
646 
647  /* Is it a new machine mode? */
648  if (subtype[0] != '\0') {
649  int res2 = 0;
650  bool doExit = false;
651 
652  {
653  GXemul gxemul;
654  gxemul.InitUI();
655 
657  gxemul.SetRunState(GXemul::Paused);
658  else
660 
661  gxemul.SetSnapshottingEnabled(using_switch_B);
662 
663  if (quiet_mode)
664  gxemul.SetQuietMode(true);
665 
666  if (gxemul.IsTemplateMachine(subtype)) {
667  if (!gxemul.ParseFilenames(subtype, argc, argv))
668  res2 = 1;
669 
670  if (res2 == 0)
671  res2 = gxemul.Run();
672 
673  doExit = true;
674  }
675  }
676 
677  if (doExit)
678  exit(res2);
679  }
680 
681  /* Legacy mode? */
682  res = machine_name_to_type(type, subtype,
683  &m->machine_type, &m->machine_subtype, &m->arch);
684  if (!res)
685  exit(1);
686  }
687 
688  if (m->machine_type == MACHINE_NONE && msopts) {
689  fprintf(stderr, "Machine specific options used directly on "
690  "the command line, but no machine\nemulation specified?\n");
691  exit(1);
692  }
693 
694 
695  /* -i and -r are pretty verbose: */
696 
697  if (m->instruction_trace && !verbose) {
698  fprintf(stderr, "Implicitly %sturning on -v, because"
699  " of -i\n", quiet_mode? "turning off -q and " : "");
700  verbose = 1;
701  quiet_mode = 0;
702  }
703 
704  if (m->register_dump && !verbose) {
705  fprintf(stderr, "Implicitly %sturning on -v, because"
706  " of -r\n", quiet_mode? "turning off -q and " : "");
707  verbose = 1;
708  quiet_mode = 0;
709  }
710 
711 
712  /*
713  * Usually, an executable filename must be supplied.
714  *
715  * However, it is possible to boot directly from a harddisk image
716  * file. If no kernel is supplied, but a diskimage is being used,
717  * then try to boot from disk.
718  */
719  if (extra_argc == 0) {
720  if (using_switch_d) {
721  /* Booting directly from a disk image... */
722  } else {
723  usage(0);
724  fprintf(stderr, "\nNo filename given. Aborting.\n");
725  exit(1);
726  }
727  } else if (m->boot_kernel_filename[0] == '\0') {
728  /*
729  * Default boot_kernel_filename is "", which can be overriden
730  * by the -j command line option. If it is still "" here,
731  * and we're not booting directly from a disk image, then
732  * try to set it to the last part of the last file name
733  * given on the command line. (Last part = the stuff after
734  * the last slash.)
735  */
736  char *s = extra_argv[extra_argc - 1];
737  char *s2;
738 
739  s2 = strrchr(s, '/');
740  if (s2 == NULL)
741  s2 = s;
742  else
743  s2 ++;
744 
745  CHECK_ALLOCATION(m->boot_kernel_filename = strdup(s2));
746  }
747 
748  if (m->n_gfx_cards < 0 || m->n_gfx_cards > 3) {
749  fprintf(stderr, "Bad number of gfx cards (-Z).\n");
750  exit(1);
751  }
752 
753  if (!using_switch_Z && !m->x11_md.in_use)
754  m->n_gfx_cards = 0;
755 
756  return 0;
757 }
758 
759 
760 /*
761  * main():
762  *
763  * Two kinds of emulations are started from here:
764  *
765  * o) Simple emulations, using command line arguments, compatible with
766  * earlier version of GXemul/mips64emul.
767  *
768  * o) Emulations set up by parsing special config files. (0 or more.)
769  */
770 int main(int argc, char *argv[])
771 {
772  /* Setting constants: */
773  int constant_yes = 1;
774  int constant_true = 1;
775  int constant_no = 0;
776  int constant_false = 0;
777 
778  struct emul *emul;
779  int config_file = 0;
780 
781  char **diskimages = NULL;
782  int n_diskimages = 0;
783  int i;
784 
785 
786  progname = argv[0];
787 
788 
789  /*
790  * Create the settings object, and add global settings to it:
791  *
792  * Read-only "constants": yes, no, true, false.
793  * Global emulator settings: verbose, single_step, ...
794  */
796 
798  SETTINGS_FORMAT_YESNO, (void *)&constant_yes);
800  SETTINGS_FORMAT_YESNO, (void *)&constant_no);
802  SETTINGS_FORMAT_BOOL, (void *)&constant_true);
804  SETTINGS_FORMAT_BOOL, (void *)&constant_false);
805 
806  /* Read-only settings: */
807  settings_add(global_settings, "single_step", 0,
809 
810  /* Read/write settings: */
811  settings_add(global_settings, "force_debugger_at_exit", 1,
813  (void *)&force_debugger_at_exit);
814  settings_add(global_settings, "verbose", 1,
816  settings_add(global_settings, "quiet_mode", 1,
818 
819  /* Initialize all emulator subsystems: */
820  console_init();
821  cpu_init();
822  device_init();
823  machine_init();
824  timer_init();
825 
826  /* Create a simple emulation setup: */
827  emul = emul_new(NULL);
828  settings_add(global_settings, "emul", 1,
830 
831  get_cmd_args(argc, argv, emul, &diskimages, &n_diskimages);
832 
833  if (!skip_srandom_call) {
834  struct timeval tv;
835  gettimeofday(&tv, NULL);
836  srandom(tv.tv_sec ^ getpid() ^ tv.tv_usec);
837  }
838 
839  /* Print startup message: */
840  debug("GXemul " VERSION" " COPYRIGHT_MSG"\n" SECONDARY_MSG
841  "Read the source code and/or documentation for other Copyright "
842  "messages.\n\n");
843 
844  /* Simple initialization, from command line arguments: */
845  if (emul->machines[0]->machine_type != MACHINE_NONE) {
846  for (i=0; i<n_diskimages; i++)
847  diskimage_add(emul->machines[0], diskimages[i]);
848 
849  /* Make sure that there are no configuration files as well: */
850  for (i=1; i<argc; i++)
851  if (argv[i][0] == '@') {
852  fprintf(stderr, "You can either start one "
853  "emulation with one machine directly from "
854  "the command\nline, or start one or more "
855  "emulations using configuration files."
856  " Not both.\n");
857  exit(1);
858  }
859 
860  /* Initialize one emul: */
862  }
863 
864  /* Initialize an emulation from a config file: */
865  for (i=1; i<argc; i++) {
866  if (argv[i][0] == '@') {
867  char *s = argv[i] + 1;
868 
869  if (config_file) {
870  fprintf(stderr, "More than one configuration "
871  "file cannot be used.\n");
872  exit(1);
873  }
874 
875  if (strlen(s) == 0 && i+1 < argc && *argv[i+1] != '@')
876  s = argv[++i];
877 
878  /* Always allow slave xterms: */
880 
881  /* Destroy the temporary emul, since it will
882  be overwritten: */
883  if (emul != NULL) {
886  emul = NULL;
887  }
888 
890 
891  settings_add(global_settings, "emul", 1,
893 
894  config_file = 1;
895  }
896  }
897 
898  if (emul->n_machines == 0) {
899  fprintf(stderr, "No emulations defined. Maybe you forgot to "
900  "use -E xx and/or -e yy, to specify\nthe machine type."
901  " For example:\n\n %s -e 3max -d disk.img\n\n"
902  "to boot an emulated DECstation 5000/200 with a disk "
903  "image.\n", progname);
904  exit(1);
905  }
906 
907  if (emul->machines[0]->machine_type == MACHINE_NONE) {
908  printf("No machine type specified? Run gxemul -H for a list\n"
909  "of available machine types. Use the -e or -E option(s)\n"
910  "to specify the machine type.\n");
911  exit(1);
912  }
913 
916 
917 
918  /* Run the emulation: */
919  emul_run(emul);
920 
921 
922  /*
923  * Deinitialize everything:
924  */
925 
926  console_deinit();
927 
929 
932 
933  return 0;
934 }
935 
force_debugger_at_exit
int force_debugger_at_exit
Definition: debugger.cc:70
verbose
int verbose
Definition: main.cc:77
extra_argv
char ** extra_argv
Definition: main.cc:62
console_warn_if_slaves_are_needed
int console_warn_if_slaves_are_needed(int init)
Definition: console.cc:912
optind
int optind
machine::machine_subtype
int machine_subtype
Definition: machine.h:112
timer_init
void timer_init(void)
Definition: timer.cc:281
GXemul::SetSnapshottingEnabled
void SetSnapshottingEnabled(bool enabled)
Sets whether or not to use snapshots.
Definition: GXemul.cc:778
GXemul::Running
@ Running
Definition: GXemul.h:61
debug
void debug(const char *fmt,...)
Definition: main.cc:133
emul::settings
struct settings * settings
Definition: emul.h:38
single_step
int single_step
Definition: debugger.cc:68
ComponentFactory.h
machine::register_dump
int register_dump
Definition: machine.h:150
diskimage.h
emul::n_debugger_cmds
int n_debugger_cmds
Definition: emul.h:50
check_leaks
int check_leaks()
Definition: debug_new.cc:497
settings.h
GXemul::ParseFilenames
bool ParseFilenames(string templateMachine, int filenameCount, char *filenames[])
Parses command line arguments (file names).
Definition: GXemul.cc:427
settings_remove
void settings_remove(struct settings *settings, const char *name)
Definition: settings.cc:383
GXemul
The main emulator class.
Definition: GXemul.h:54
internal_w
void internal_w(char *arg)
Definition: main.cc:170
device_init
void device_init(void)
Definition: device.cc:447
machine::show_nr_of_instructions
int show_nr_of_instructions
Definition: machine.h:163
settings_add
void settings_add(struct settings *settings, const char *name, int writable, int type, int format, void *ptr)
Definition: settings.cc:334
machine::physical_ram_in_mb
int physical_ram_in_mb
Definition: machine.h:147
DEBUG_BUFSIZE
#define DEBUG_BUFSIZE
Definition: misc.h:211
machine::show_trace_tree
int show_trace_tree
Definition: machine.h:164
machine_list_available_types_and_cpus
void machine_list_available_types_and_cpus(void)
Definition: machine.cc:802
device_set_exit_on_error
void device_set_exit_on_error(int exit_on_error)
Definition: device.cc:433
emul_simple_init
void emul_simple_init(struct emul *emul)
Definition: emul.cc:728
console_init
void console_init(void)
Definition: console.cc:953
emul::n_machines
int n_machines
Definition: emul.h:45
machine::use_random_bootstrap_cpu
int use_random_bootstrap_cpu
Definition: machine.h:137
machine::allow_instruction_combinations
int allow_instruction_combinations
Definition: machine.h:166
extra_argc
int extra_argc
Definition: main.cc:61
MACHINE_NONE
#define MACHINE_NONE
Definition: machine.h:262
console.h
machine::prom_emulation
int prom_emulation
Definition: machine.h:149
GXemul::Run
int Run()
Runs GXemul's main loop.
Definition: GXemul.cc:557
emul_new
struct emul * emul_new(char *name)
Definition: emul.cc:143
device.h
GXemul::InitUI
void InitUI()
Initializes the UI.
Definition: GXemul.cc:545
machine::boot_string_argument
char * boot_string_argument
Definition: machine.h:171
emul_run
void emul_run(struct emul *emul)
Definition: emul.cc:785
GXemul::IsTemplateMachine
bool IsTemplateMachine(const string &templateName) const
Definition: GXemul.cc:204
machine_add_breakpoint_string
void machine_add_breakpoint_string(struct machine *machine, char *str)
Definition: machine.cc:252
machine::slow_serial_interrupts_hack_for_linux
int slow_serial_interrupts_hack_for_linux
Definition: machine.h:168
console_allow_slaves
void console_allow_slaves(int allow)
Definition: console.cc:880
progname
char * progname
Definition: main.cc:63
machine::instruction_trace
int instruction_trace
Definition: machine.h:162
debugger.h
ComponentFactory::UnregisterAllComponentClasses
static void UnregisterAllComponentClasses()
Unregisters all manually registered component classes.
Definition: ComponentFactory.cc:80
ENTER_SINGLE_STEPPING
#define ENTER_SINGLE_STEPPING
Definition: debugger.h:48
strlen
void COMBINE() strlen(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
Definition: cpu_arm_instr.cc:2333
machine::cpu_name
char * cpu_name
Definition: machine.h:133
x11_md::scaledown
int scaledown
Definition: machine.h:83
x11_md::in_use
int in_use
Definition: machine.h:82
GXemul::SetRunState
void SetRunState(RunState newState)
Sets the RunState.
Definition: GXemul.cc:741
misc.h
settings_remove_all
void settings_remove_all(struct settings *settings)
Definition: settings.cc:441
dyntrans_cache_size
size_t dyntrans_cache_size
Definition: main.cc:65
machine::halt_on_nonexistant_memaccess
int halt_on_nonexistant_memaccess
Definition: machine.h:161
emul_add_machine
struct machine * emul_add_machine(struct emul *e, char *name)
Definition: emul.cc:209
machine.h
machine
Definition: machine.h:97
timer.h
machine::force_netboot
int force_netboot
Definition: machine.h:167
emul.h
emul::debugger_cmds
char ** debugger_cmds
Definition: emul.h:51
UnitTest.h
main
int main(int argc, char *argv[])
Definition: main.cc:770
machine::x11_md
struct x11_md x11_md
Definition: machine.h:179
x11_md::display_names
char ** display_names
Definition: machine.h:86
console_slave
void console_slave(const char *arg)
Definition: console.cc:544
fatal
void fatal(const char *fmt,...)
Definition: main.cc:152
x11_md::n_display_names
int n_display_names
Definition: machine.h:85
COPYRIGHT_MSG
#define COPYRIGHT_MSG
Definition: misc.h:46
cpu.h
diskimage_add
int diskimage_add(struct machine *machine, char *fname)
Definition: diskimage.cc:659
global_settings
struct settings * global_settings
Definition: main.cc:59
get_cmd_args
int get_cmd_args(int argc, char *argv[], struct emul *emul, char ***diskimagesp, int *n_diskimagesp)
Definition: main.cc:390
SETTINGS_TYPE_SUBSETTINGS
#define SETTINGS_TYPE_SUBSETTINGS
Definition: settings.h:38
optarg
char * optarg
x11_md::scaleup
int scaleup
Definition: machine.h:84
settings
Definition: settings.cc:57
machine::boot_kernel_filename
char * boot_kernel_filename
Definition: machine.h:170
machine::random_mem_contents
int random_mem_contents
Definition: machine.h:146
GXemul::ListTemplates
static void ListTemplates()
Dump a list to stdout with all available machine templates.
Definition: GXemul.cc:239
settings_destroy
void settings_destroy(struct settings *settings)
Definition: settings.cc:105
SECONDARY_MSG
#define SECONDARY_MSG
Definition: misc.h:54
GXemul::SetQuietMode
void SetQuietMode(bool quietMode)
Sets whether or not to run in quiet mode.
Definition: GXemul.cc:794
GXemul::GenerateHTMLListOfComponents
static void GenerateHTMLListOfComponents(bool machines)
Definition: GXemul.cc:279
SETTINGS_FORMAT_BOOL
#define SETTINGS_FORMAT_BOOL
Definition: settings.h:57
machine_init
void machine_init(void)
Definition: machine.cc:865
DEFAULT_DYNTRANS_CACHE_SIZE
#define DEFAULT_DYNTRANS_CACHE_SIZE
Definition: cpu.h:315
GXemul::Paused
@ Paused
Definition: GXemul.h:59
machine::machine_type
int machine_type
Definition: machine.h:111
machine::emulated_hz
int emulated_hz
Definition: machine.h:165
emul_destroy
void emul_destroy(struct emul *emul)
Definition: emul.cc:178
emul
Definition: emul.h:37
debug_indentation
void debug_indentation(int diff)
Definition: main.cc:120
emul_create_from_configfile
struct emul * emul_create_from_configfile(char *fname)
Definition: emul.cc:761
GXemul::DumpMachineAsHTML
static void DumpMachineAsHTML(const string &machineName)
Definition: GXemul.cc:266
emul::machines
struct machine ** machines
Definition: emul.h:46
quiet_mode
int quiet_mode
Definition: main.cc:78
settings_new
struct settings * settings_new(void)
Definition: settings.cc:88
machine::n_gfx_cards
int n_gfx_cards
Definition: machine.h:173
console_deinit
void console_deinit(void)
Definition: console.cc:982
cpu_init
void cpu_init(void)
Definition: cpu.cc:567
machine::arch
int arch
Definition: machine.h:110
machine_statistics_init
void machine_statistics_init(struct machine *, char *fname)
Definition: machine.cc:323
machine_name_to_type
int machine_name_to_type(char *stype, char *ssubtype, int *type, int *subtype, int *arch)
Definition: machine.cc:156
GXemul.h
SETTINGS_FORMAT_YESNO
#define SETTINGS_FORMAT_YESNO
Definition: settings.h:58
SETTINGS_TYPE_INT
#define SETTINGS_TYPE_INT
Definition: settings.h:40
UnitTest::RunTests
static int RunTests()
Runs all unit tests in GXemul.
Definition: UnitTest.cc:89
machine::ncpus
int ncpus
Definition: machine.h:139
CHECK_ALLOCATION
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239

Generated on Tue Mar 24 2020 14:04:48 for GXemul by doxygen 1.8.17