main.cc Source File

Back to the index.

main.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2019 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 other Copyright messages.\n");
233 
234  printf("\nUsage: %s [machine, other, and general options] [file [...]]\n", progname);
235  printf(" or %s [general options] @configfile\n", progname);
236 
237  if (!longusage) {
238  printf("\nRun %s -h for help on command line options.\n", progname);
239  return;
240  }
241 
242  printf("\nMachine selection options:\n");
243  printf(" -E t try to emulate machine type t. (Use -H to get "
244  "a list of types.)\n");
245  printf(" -e st try to emulate machine subtype st. (Use this "
246  "with -E.)\n");
247 
248  printf("\nOther options:\n");
249  printf(" -C x try to emulate a specific CPU. (Use -H to get a "
250  "list of types.)\n");
251  printf(" -d fname add fname as a disk image. You can add \"xxx:\""
252  " as a prefix\n");
253  printf(" where xxx is one or more of the following:\n");
254  printf(" b specifies that this is the boot"
255  " device\n");
256  printf(" c CD-ROM\n");
257  printf(" d DISK\n");
258  printf(" f FLOPPY\n");
259  printf(" gH;S; set geometry to H heads and S"
260  " sectors-per-track\n");
261  printf(" i IDE\n");
262  printf(" oOFS; set base offset to OFS (for ISO9660"
263  " filesystems)\n");
264  printf(" r read-only (don't allow changes to the"
265  " file)\n");
266  printf(" s SCSI\n");
267  printf(" t tape\n");
268  printf(" V add an overlay\n");
269  printf(" 0-7 force a specific ID\n");
270  printf(" -I hz set the main cpu frequency to hz (not used by "
271  "all combinations\n of machines and guest OSes)\n");
272  printf(" -i display each instruction as it is executed\n");
273  printf(" -J disable dyntrans instruction combinations\n");
274  printf(" -j name set the name of the kernel; for DECstation "
275  "emulation, this passes\n the name to the bootloader,"
276  " for example:\n");
277  printf(" -j netbsd (NetBSD/pmax) "
278  "-j bsd (OpenBSD/pmax)\n");
279  printf(" -j vmsprite (Sprite/pmax) "
280  "-j vmunix (Ultrix/RISC)\n");
281  printf(" For other emulation modes, if the boot disk is an"
282  " ISO9660\n filesystem, -j sets the name of the"
283  " kernel to load.\n");
284  printf(" -M m emulate m MBs of physical RAM\n");
285  printf(" -N display nr of instructions/second average, at"
286  " regular intervals\n");
287  printf(" -n nr set nr of CPUs (for SMP experiments)\n");
288  printf(" -O force netboot (tftp instead of disk), even when"
289  " a disk image is\n"
290  " present (for DECstation, SGI, and ARC emulation)\n");
291  printf(" -o arg set the boot argument, for DEC, ARC, or SGI"
292  " emulation\n");
293  printf(" (default arg for DEC is -a, for ARC/SGI -aN)\n");
294  printf(" -p pc add a breakpoint (remember to use the '0x' "
295  "prefix for hex!)\n");
296  printf(" -Q no built-in PROM emulation (use this for "
297  "running ROM images)\n");
298  printf(" -R use random bootstrap cpu, instead of nr 0\n");
299  printf(" -r register dumps before every instruction\n");
300  printf(" -S initialize emulated RAM to random bytes, "
301  "instead of zeroes\n");
302  printf(" -s f:name write statistics to file 'name', "
303  "f is one or more of the following:\n");
304  printf(" v virtual program counter\n");
305  printf(" p physical equivalent of program counter\n");
306  printf(" i internal ic->f representation of "
307  "the program counter\n");
308  printf(" and optionally:\n");
309  printf(" d disable statistics gathering at "
310  "startup\n");
311  printf(" o overwrite instead of append\n");
312  printf(" -T halt on non-existant memory accesses\n");
313  printf(" -t show function trace tree\n");
314  printf(" -U enable slow_serial_interrupts_hack_for_linux\n");
315 #ifdef WITH_X11
316  printf(" -X use X11\n");
317  printf(" -x open up new xterms for emulated serial ports "
318  "(default is on when\n using configuration files or"
319  " when X11 is used, off otherwise)\n");
320  printf(" -Y n scale down framebuffer windows by n x n times\n");
321 #endif /* WITH_X11 */
322  printf(" -Z n set nr of graphics cards, for emulating a "
323  "dual-head or tripple-head\n"
324  " environment (only for DECstation emulation)\n");
325  printf(" -z disp add disp as an X11 display to use for "
326  "framebuffers\n");
327 
328  printf("\nGeneral options:\n");
329  printf(" -c cmd add cmd as a command to run before starting "
330  "the simulation\n");
331  printf(" -D skip the srandom call at startup\n");
332  printf(" -H display a list of possible CPU and "
333  "machine types\n");
334  printf(" -h display this help message\n");
335  printf(" -k n set dyntrans translation caches to n MB (default"
336  " size is %i MB)\n", DEFAULT_DYNTRANS_CACHE_SIZE / 1048576);
337  printf(" -K force the debugger to be entered at the end "
338  "of a simulation\n");
339  printf(" -q quiet mode (don't print startup messages)\n");
340  printf(" -V start up in the single-step debugger, paused\n");
341  printf(" -v increase debug message verbosity\n");
342  printf("\n");
343  printf("If you are selecting a machine type to emulate directly "
344  "on the command line,\nthen you must specify one or more names"
345  " of files that you wish to load into\n"
346  "memory. Supported formats are: ELF a.out ecoff srec syms raw\n"
347  "where syms is the text produced by running 'nm' (or 'nm -S') "
348  "on a binary.\n"
349  "To load a raw binary into memory, add \"address:\" in front "
350  "of the filename,\n"
351  "or \"address:skiplen:\" or \"address:skiplen:initialpc:\".\n"
352  "\nExamples:\n"
353  " 0xbfc00000:rom.bin for a raw ROM image\n"
354  " 0xbfc00000:0x100:rom.bin for an image with "
355  "0x100 bytes header\n"
356  " 0xbfc00000:0x100:0xbfc00884:rom.bin "
357  "start with pc=0xbfc00884\n\n");
358 
359  printf("\n\"New framework\" options (experimental):\n");
360  printf("\nUsage: %s [options] -e name [additional components and files [...]]\n", progname);
361  printf(" or %s [options] configfile\n", progname);
362  printf(" or %s -H\n", progname);
363  printf(" or %s -V\n", progname);
364  printf("\n");
365  printf(" -B Enable snapshotting (reverse stepping support).\n");
366  printf(" -H Display a list of available machine templates.\n");
367  printf(" -e name Start with a machine based on template 'name'.\n");
368  printf(" -q Quiet mode (suppress debug messages).\n");
369  printf(" -V Start up in interactive debugging mode, paused.\n");
370  printf("\n");
371 }
372 
373 
374 /*
375  * get_cmd_args():
376  *
377  * Reads command line arguments.
378  */
379 int get_cmd_args(int argc, char *argv[], struct emul *emul,
380  char ***diskimagesp, int *n_diskimagesp)
381 {
382  int ch, res, using_switch_d = 0, using_switch_Z = 0;
383  int using_switch_e = 0, using_switch_E = 0;
384  bool using_switch_B = false;
385  char *type = NULL, *subtype = NULL;
386  int n_cpus_set = 0;
387  int msopts = 0; /* Machine-specific options used */
388  struct machine *m = emul_add_machine(emul, NULL);
389 
390  const char *opts =
391  "BC:c:Dd:E:e:HhI:iJj:k:KM:Nn:Oo:p:QqRrSs:TtUVvW:"
392 #ifdef WITH_X11
393  "XxY:"
394 #endif
395  "Z:z:";
396 
397  while ((ch = getopt(argc, argv, opts)) != -1) {
398  switch (ch) {
399  case 'B':
400  using_switch_B = true;
401  break;
402  case 'C':
403  CHECK_ALLOCATION(m->cpu_name = strdup(optarg));
404  msopts = 1;
405  break;
406  case 'c':
407  emul->n_debugger_cmds ++;
408  CHECK_ALLOCATION(emul->debugger_cmds = (char **)
409  realloc(emul->debugger_cmds,
410  emul->n_debugger_cmds * sizeof(char *)));
412  n_debugger_cmds-1] = strdup(optarg));
413  break;
414  case 'D':
415  skip_srandom_call = 1;
416  break;
417  case 'd':
418  /* diskimage_add() is called further down */
419  (*n_diskimagesp) ++;
420  CHECK_ALLOCATION( (*diskimagesp) = (char **)
421  realloc(*diskimagesp,
422  sizeof(char *) * (*n_diskimagesp)) );
423  CHECK_ALLOCATION( (*diskimagesp)[(*n_diskimagesp) - 1] =
424  strdup(optarg) );
425  using_switch_d = 1;
426  msopts = 1;
427  break;
428  case 'E':
429  if (using_switch_E ++ > 0) {
430  fprintf(stderr, "-E already used.\n");
431  exit(1);
432  }
433  type = optarg;
434  msopts = 1;
435  break;
436  case 'e':
437  if (using_switch_e ++ > 0) {
438  fprintf(stderr, "-e already used.\n");
439  exit(1);
440  }
441  subtype = optarg;
442  msopts = 1;
443  break;
444  case 'H':
446  printf("--------------------------------------------------------------------------\n\n");
447  printf("The following applies to the LEGACY modes only:\n\n");
449  exit(1);
450  case 'h':
451  usage(1);
452  exit(1);
453  case 'I':
454  m->emulated_hz = atoi(optarg);
455  msopts = 1;
456  break;
457  case 'i':
458  m->instruction_trace = 1;
459  msopts = 1;
460  break;
461  case 'J':
463  msopts = 1;
464  break;
465  case 'j':
467  strdup(optarg));
468  msopts = 1;
469  break;
470  case 'k':
471  dyntrans_cache_size = atoi(optarg) * 1048576;
472  if (dyntrans_cache_size < 1) {
473  fprintf(stderr, "The dyntrans cache size must"
474  " be at least 1 MB.\n");
475  exit(1);
476  }
477  break;
478  case 'K':
480  break;
481  case 'M':
482  m->physical_ram_in_mb = atoi(optarg);
483  msopts = 1;
484  break;
485  case 'N':
487  msopts = 1;
488  break;
489  case 'n':
490  m->ncpus = atoi(optarg);
491  n_cpus_set = 1;
492  msopts = 1;
493  break;
494  case 'O':
495  m->force_netboot = 1;
496  msopts = 1;
497  break;
498  case 'o':
500  strdup(optarg));
501  msopts = 1;
502  break;
503  case 'p':
505  msopts = 1;
506  break;
507  case 'Q':
508  m->prom_emulation = 0;
509  msopts = 1;
510  break;
511  case 'q':
512  quiet_mode = 1;
513  break;
514  case 'R':
516  msopts = 1;
517  break;
518  case 'r':
519  m->register_dump = 1;
520  msopts = 1;
521  break;
522  case 'S':
523  m->random_mem_contents = 1;
524  msopts = 1;
525  break;
526  case 's':
528  msopts = 1;
529  break;
530  case 'T':
532  msopts = 1;
533  break;
534  case 't':
535  m->show_trace_tree = 1;
536  msopts = 1;
537  break;
538  case 'U':
540  msopts = 1;
541  break;
542  case 'V':
544  break;
545  case 'v':
546  verbose ++;
547  break;
548  case 'W':
550  exit(0);
551  case 'X':
552  m->x11_md.in_use = 1;
553  msopts = 1;
554  /* FALL-THROUGH */
555  case 'x':
557  break;
558  case 'Y':
559  m->x11_md.scaledown = atoi(optarg);
560  if (m->x11_md.scaledown < -1) {
561  m->x11_md.scaleup = - m->x11_md.scaledown;
562  m->x11_md.scaledown = 1;
563  }
564  if (m->x11_md.scaledown < 1) {
565  fprintf(stderr, "Invalid scaledown value.\n");
566  exit(1);
567  }
568  msopts = 1;
569  break;
570  case 'Z':
571  m->n_gfx_cards = atoi(optarg);
572  using_switch_Z = 1;
573  msopts = 1;
574  break;
575  case 'z':
576  m->x11_md.n_display_names ++;
577  CHECK_ALLOCATION(m->x11_md.display_names = (char **) realloc(
579  m->x11_md.n_display_names * sizeof(char *)));
581  m->x11_md.n_display_names-1] = strdup(optarg));
582  msopts = 1;
583  break;
584  default:
585  fprintf(stderr, "Run %s -h for help on command "
586  "line options.\n", progname);
587  exit(1);
588  }
589  }
590 
591  argc -= optind;
592  argv += optind;
593 
594  extra_argc = argc;
595  extra_argv = argv;
596 
597  // If -V is used, -q is ignored.
599  quiet_mode = 0;
600 
601  if (type == NULL && subtype == NULL &&
602  (single_step == ENTER_SINGLE_STEPPING || (argc > 0 && argv[0][0] != '@'))) {
603  int res2 = 0;
604  {
605  GXemul gxemul;
606  gxemul.InitUI();
607 
609  gxemul.SetRunState(GXemul::Paused);
610  else
612 
613  gxemul.SetSnapshottingEnabled(using_switch_B);
614 
615  if (quiet_mode)
616  gxemul.SetQuietMode(true);
617 
618  if (argc > 0 && !gxemul.ParseFilenames("", argc, argv))
619  res = 1;
620 
621  if (res2 == 0)
622  res2 = gxemul.Run();
623  }
624 
625  // Note: exit() is outside the GXemul scope, so that GXemul's
626  // destructor runs.
627  exit(res2);
628  }
629 
630  if (type != NULL || subtype != NULL) {
631  if (type == NULL)
632  type = strdup("");
633  if (subtype == NULL)
634  subtype = strdup("");
635 
636  /* Is it a new machine mode? */
637  if (subtype[0] != '\0') {
638  int res2 = 0;
639  bool doExit = false;
640 
641  {
642  GXemul gxemul;
643  gxemul.InitUI();
644 
646  gxemul.SetRunState(GXemul::Paused);
647  else
649 
650  gxemul.SetSnapshottingEnabled(using_switch_B);
651 
652  if (quiet_mode)
653  gxemul.SetQuietMode(true);
654 
655  if (gxemul.IsTemplateMachine(subtype)) {
656  if (!gxemul.ParseFilenames(subtype, argc, argv))
657  res2 = 1;
658 
659  if (res2 == 0)
660  res2 = gxemul.Run();
661 
662  doExit = true;
663  }
664  }
665 
666  if (doExit)
667  exit(res2);
668  }
669 
670  /* Legacy mode? */
671  res = machine_name_to_type(type, subtype,
672  &m->machine_type, &m->machine_subtype, &m->arch);
673  if (!res)
674  exit(1);
675  }
676 
677  if (m->machine_type == MACHINE_NONE && msopts) {
678  fprintf(stderr, "Machine specific options used directly on "
679  "the command line, but no machine\nemulation specified?\n");
680  exit(1);
681  }
682 
683 
684  /* -i and -r are pretty verbose: */
685 
686  if (m->instruction_trace && !verbose) {
687  fprintf(stderr, "Implicitly %sturning on -v, because"
688  " of -i\n", quiet_mode? "turning off -q and " : "");
689  verbose = 1;
690  quiet_mode = 0;
691  }
692 
693  if (m->register_dump && !verbose) {
694  fprintf(stderr, "Implicitly %sturning on -v, because"
695  " of -r\n", quiet_mode? "turning off -q and " : "");
696  verbose = 1;
697  quiet_mode = 0;
698  }
699 
700 
701  /*
702  * Usually, an executable filename must be supplied.
703  *
704  * However, it is possible to boot directly from a harddisk image
705  * file. If no kernel is supplied, but a diskimage is being used,
706  * then try to boot from disk.
707  */
708  if (extra_argc == 0) {
709  if (using_switch_d) {
710  /* Booting directly from a disk image... */
711  } else {
712  usage(0);
713  fprintf(stderr, "\nNo filename given. Aborting.\n");
714  exit(1);
715  }
716  } else if (m->boot_kernel_filename[0] == '\0') {
717  /*
718  * Default boot_kernel_filename is "", which can be overriden
719  * by the -j command line option. If it is still "" here,
720  * and we're not booting directly from a disk image, then
721  * try to set it to the last part of the last file name
722  * given on the command line. (Last part = the stuff after
723  * the last slash.)
724  */
725  char *s = extra_argv[extra_argc - 1];
726  char *s2;
727 
728  s2 = strrchr(s, '/');
729  if (s2 == NULL)
730  s2 = s;
731  else
732  s2 ++;
733 
734  CHECK_ALLOCATION(m->boot_kernel_filename = strdup(s2));
735  }
736 
737  if (m->n_gfx_cards < 0 || m->n_gfx_cards > 3) {
738  fprintf(stderr, "Bad number of gfx cards (-Z).\n");
739  exit(1);
740  }
741 
742  if (!using_switch_Z && !m->x11_md.in_use)
743  m->n_gfx_cards = 0;
744 
745  return 0;
746 }
747 
748 
749 /*
750  * main():
751  *
752  * Two kinds of emulations are started from here:
753  *
754  * o) Simple emulations, using command line arguments, compatible with
755  * earlier version of GXemul/mips64emul.
756  *
757  * o) Emulations set up by parsing special config files. (0 or more.)
758  */
759 int main(int argc, char *argv[])
760 {
761  /* Setting constants: */
762  int constant_yes = 1;
763  int constant_true = 1;
764  int constant_no = 0;
765  int constant_false = 0;
766 
767  struct emul *emul;
768  int config_file = 0;
769 
770  char **diskimages = NULL;
771  int n_diskimages = 0;
772  int i;
773 
774 
775  progname = argv[0];
776 
777 
778  /*
779  * Create the settings object, and add global settings to it:
780  *
781  * Read-only "constants": yes, no, true, false.
782  * Global emulator settings: verbose, single_step, ...
783  */
785 
787  SETTINGS_FORMAT_YESNO, (void *)&constant_yes);
789  SETTINGS_FORMAT_YESNO, (void *)&constant_no);
791  SETTINGS_FORMAT_BOOL, (void *)&constant_true);
793  SETTINGS_FORMAT_BOOL, (void *)&constant_false);
794 
795  /* Read-only settings: */
796  settings_add(global_settings, "single_step", 0,
798 
799  /* Read/write settings: */
800  settings_add(global_settings, "force_debugger_at_exit", 1,
802  (void *)&force_debugger_at_exit);
803  settings_add(global_settings, "verbose", 1,
805  settings_add(global_settings, "quiet_mode", 1,
807 
808  /* Initialize all emulator subsystems: */
809  console_init();
810  cpu_init();
811  device_init();
812  machine_init();
813  timer_init();
814 
815  /* Create a simple emulation setup: */
816  emul = emul_new(NULL);
817  settings_add(global_settings, "emul", 1,
819 
820  get_cmd_args(argc, argv, emul, &diskimages, &n_diskimages);
821 
822  if (!skip_srandom_call) {
823  struct timeval tv;
824  gettimeofday(&tv, NULL);
825  srandom(tv.tv_sec ^ getpid() ^ tv.tv_usec);
826  }
827 
828  /* Print startup message: */
829  debug("GXemul " VERSION" " COPYRIGHT_MSG"\n" SECONDARY_MSG
830  "Read the source code and/or documentation for other Copyright "
831  "messages.\n\n");
832 
833  /* Simple initialization, from command line arguments: */
834  if (emul->machines[0]->machine_type != MACHINE_NONE) {
835  for (i=0; i<n_diskimages; i++)
836  diskimage_add(emul->machines[0], diskimages[i]);
837 
838  /* Make sure that there are no configuration files as well: */
839  for (i=1; i<argc; i++)
840  if (argv[i][0] == '@') {
841  fprintf(stderr, "You can either start one "
842  "emulation with one machine directly from "
843  "the command\nline, or start one or more "
844  "emulations using configuration files."
845  " Not both.\n");
846  exit(1);
847  }
848 
849  /* Initialize one emul: */
851  }
852 
853  /* Initialize an emulation from a config file: */
854  for (i=1; i<argc; i++) {
855  if (argv[i][0] == '@') {
856  char *s = argv[i] + 1;
857 
858  if (config_file) {
859  fprintf(stderr, "More than one configuration "
860  "file cannot be used.\n");
861  exit(1);
862  }
863 
864  if (strlen(s) == 0 && i+1 < argc && *argv[i+1] != '@')
865  s = argv[++i];
866 
867  /* Always allow slave xterms: */
869 
870  /* Destroy the temporary emul, since it will
871  be overwritten: */
872  if (emul != NULL) {
875  emul = NULL;
876  }
877 
879 
880  settings_add(global_settings, "emul", 1,
882 
883  config_file = 1;
884  }
885  }
886 
887  if (emul->n_machines == 0) {
888  fprintf(stderr, "No emulations defined. Maybe you forgot to "
889  "use -E xx and/or -e yy, to specify\nthe machine type."
890  " For example:\n\n %s -e 3max -d disk.img\n\n"
891  "to boot an emulated DECstation 5000/200 with a disk "
892  "image.\n", progname);
893  exit(1);
894  }
895 
896  if (emul->machines[0]->machine_type == MACHINE_NONE) {
897  printf("No machine type specified? Run gxemul -H for a list\n"
898  "of available machine types. Use the -e or -E option(s)\n"
899  "to specify the machine type.\n");
900  exit(1);
901  }
902 
905 
906 
907  /* Run the emulation: */
908  emul_run(emul);
909 
910 
911  /*
912  * Deinitialize everything:
913  */
914 
915  console_deinit();
916 
918 
921 
922  return 0;
923 }
924 
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:917
optind
int optind
machine::machine_subtype
int machine_subtype
Definition: machine.h:112
timer_init
void timer_init(void)
Definition: timer.cc:282
GXemul::SetSnapshottingEnabled
void SetSnapshottingEnabled(bool enabled)
Sets whether or not to use snapshots.
Definition: GXemul.cc:770
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:419
settings_remove
void settings_remove(struct settings *settings, const char *name)
Definition: settings.cc:383
GXemul
The main emulator class.
Definition: GXemul.h:55
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
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:734
console_init
void console_init(void)
Definition: console.cc:958
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:261
console.h
machine::prom_emulation
int prom_emulation
Definition: machine.h:149
GXemul::Run
int Run()
Runs GXemul's main loop.
Definition: GXemul.cc:549
emul_new
struct emul * emul_new(char *name)
Definition: emul.cc:143
device.h
GXemul::InitUI
void InitUI()
Initializes the UI.
Definition: GXemul.cc:537
machine::boot_string_argument
char * boot_string_argument
Definition: machine.h:171
emul_run
void emul_run(struct emul *emul)
Definition: emul.cc:791
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:885
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:2686
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:733
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:759
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:549
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:671
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:379
SETTINGS_TYPE_SUBSETTINGS
#define SETTINGS_TYPE_SUBSETTINGS
Definition: settings.h:38
machine::physical_ram_in_mb
uint32_t physical_ram_in_mb
Definition: machine.h:147
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:786
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:767
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:987
cpu_init
void cpu_init(void)
Definition: cpu.cc:576
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 Aug 25 2020 19:25:06 for GXemul by doxygen 1.8.18