/[gxemul]/trunk/src/emul.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

Diff of /trunk/src/emul.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 38 by dpavlin, Mon Oct 8 16:21:53 2007 UTC revision 44 by dpavlin, Mon Oct 8 16:22:56 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: emul.c,v 1.282 2007/04/11 15:15:31 debug Exp $   *  $Id: emul.c,v 1.302 2007/08/29 20:36:49 debug Exp $
29   *   *
30   *  Emulation startup and misc. routines.   *  Emulation startup and misc. routines.
31   */   */
# Line 52  Line 52 
52  #include "misc.h"  #include "misc.h"
53  #include "net.h"  #include "net.h"
54  #include "settings.h"  #include "settings.h"
 #include "sgi_arcbios.h"  
55  #include "timer.h"  #include "timer.h"
56    #include "useremul.h"
57  #include "x11.h"  #include "x11.h"
58    
59    
# Line 69  extern int old_instruction_trace; Line 69  extern int old_instruction_trace;
69  extern int old_quiet_mode;  extern int old_quiet_mode;
70  extern int quiet_mode;  extern int quiet_mode;
71    
 extern struct emul *debugger_emul;  
 extern struct diskimage *diskimages[];  
   
   
 static void print_separator(void)  
 {  
         int i = 79;  
         while (i-- > 0)  
                 debug("-");  
         debug("\n");  
 }  
   
72    
73  /*  /*
74   *  add_dump_points():   *  add_breakpoints():
75   *   *
76   *  Take the strings breakpoint_string[] and convert to addresses   *  Take the strings breakpoint_string[] and convert to addresses
77   *  (and store them in breakpoint_addr[]).   *  (and store them in breakpoint_addr[]).
78   *   *
79   *  TODO: This function should be moved elsewhere.   *  TODO: This function should be moved elsewhere.
80   */   */
81  static void add_dump_points(struct machine *m)  static void add_breakpoints(struct machine *m)
82  {  {
83          int i;          int i;
84          int string_flag;          int string_flag;
85          uint64_t dp;          uint64_t dp;
86    
87          for (i=0; i<m->n_breakpoints; i++) {          for (i=0; i<m->breakpoints.n; i++) {
88                  string_flag = 0;                  string_flag = 0;
89                  dp = strtoull(m->breakpoint_string[i], NULL, 0);                  dp = strtoull(m->breakpoints.string[i], NULL, 0);
90    
91                  /*                  /*
92                   *  If conversion resulted in 0, then perhaps it is a                   *  If conversion resulted in 0, then perhaps it is a
# Line 107  static void add_dump_points(struct machi Line 95  static void add_dump_points(struct machi
95                  if (dp == 0) {                  if (dp == 0) {
96                          uint64_t addr;                          uint64_t addr;
97                          int res = get_symbol_addr(&m->symbol_context,                          int res = get_symbol_addr(&m->symbol_context,
98                              m->breakpoint_string[i], &addr);                              m->breakpoints.string[i], &addr);
99                          if (!res) {                          if (!res) {
100                                  fprintf(stderr,                                  fprintf(stderr,
101                                      "ERROR! Breakpoint '%s' could not be"                                      "ERROR! Breakpoint '%s' could not be"
102                                          " parsed\n",                                          " parsed\n",
103                                      m->breakpoint_string[i]);                                      m->breakpoints.string[i]);
104                                    exit(1);
105                          } else {                          } else {
106                                  dp = addr;                                  dp = addr;
107                                  string_flag = 1;                                  string_flag = 1;
# Line 129  static void add_dump_points(struct machi Line 118  static void add_dump_points(struct machi
118                                  dp |= 0xffffffff00000000ULL;                                  dp |= 0xffffffff00000000ULL;
119                  }                  }
120    
121                  m->breakpoint_addr[i] = dp;                  m->breakpoints.addr[i] = dp;
122    
123                  debug("breakpoint %i: 0x%llx", i, (long long)dp);                  debug("breakpoint %i: 0x%"PRIx64, i, dp);
124                  if (string_flag)                  if (string_flag)
125                          debug(" (%s)", m->breakpoint_string[i]);                          debug(" (%s)", m->breakpoints.string[i]);
126                  debug("\n");                  debug("\n");
127          }          }
128  }  }
# Line 153  static void fix_console(void) Line 142  static void fix_console(void)
142   *   *
143   *  Returns a reasonably initialized struct emul.   *  Returns a reasonably initialized struct emul.
144   */   */
145  struct emul *emul_new(char *name, int id)  struct emul *emul_new(char *name)
146  {  {
147          struct emul *e;          struct emul *e;
         e = malloc(sizeof(struct emul));  
         if (e == NULL) {  
                 fprintf(stderr, "out of memory in emul_new()\n");  
                 exit(1);  
         }  
148    
149            CHECK_ALLOCATION(e = malloc(sizeof(struct emul)));
150          memset(e, 0, sizeof(struct emul));          memset(e, 0, sizeof(struct emul));
151    
         e->path = malloc(15);  
         if (e->path == NULL) {  
                 fprintf(stderr, "out of memory\n");  
                 exit(1);  
         }  
         snprintf(e->path, 15, "emul[%i]", id);  
   
152          e->settings = settings_new();          e->settings = settings_new();
153    
154          settings_add(e->settings, "n_machines", 0,          settings_add(e->settings, "n_machines", 0,
# Line 184  struct emul *emul_new(char *name, int id Line 162  struct emul *emul_new(char *name, int id
162          e->next_serial_nr = 1;          e->next_serial_nr = 1;
163    
164          if (name != NULL) {          if (name != NULL) {
165                  e->name = strdup(name);                  CHECK_ALLOCATION(e->name = strdup(name));
                 if (e->name == NULL) {  
                         fprintf(stderr, "out of memory in emul_new()\n");  
                         exit(1);  
                 }  
   
166                  settings_add(e->settings, "name", 0,                  settings_add(e->settings, "name", 0,
167                      SETTINGS_TYPE_STRING, SETTINGS_FORMAT_STRING,                      SETTINGS_TYPE_STRING, SETTINGS_FORMAT_STRING,
168                      (void *) &e->name);                      (void *) &e->name);
# Line 244  struct machine *emul_add_machine(struct Line 217  struct machine *emul_add_machine(struct
217          m = machine_new(name, e, e->n_machines);          m = machine_new(name, e, e->n_machines);
218          m->serial_nr = (e->next_serial_nr ++);          m->serial_nr = (e->next_serial_nr ++);
219    
220          i = e->n_machines;          i = e->n_machines ++;
221    
222          e->n_machines ++;          CHECK_ALLOCATION(e->machines = realloc(e->machines,
223          e->machines = realloc(e->machines,              sizeof(struct machine *) * e->n_machines));
             sizeof(struct machine *) * e->n_machines);  
         if (e->machines == NULL) {  
                 fprintf(stderr, "emul_add_machine(): out of memory\n");  
                 exit(1);  
         }  
224    
225          e->machines[i] = m;          e->machines[i] = m;
226    
# Line 393  void emul_machine_setup(struct machine * Line 361  void emul_machine_setup(struct machine *
361          uint64_t memory_amount, entrypoint = 0, gp = 0, toc = 0;          uint64_t memory_amount, entrypoint = 0, gp = 0, toc = 0;
362          int byte_order;          int byte_order;
363    
364          debug("machine \"%s\":\n", m->name);          if (m->name != NULL)
365                    debug("machine \"%s\":\n", m->name);
366            else
367                    debug("machine:\n");
368    
369          debug_indentation(iadd);          debug_indentation(iadd);
370    
371          /*  For userland-only, this decides which ARCH/cpu_name to use:  */          /*  For userland-only, this decides which ARCH/cpu_name to use:  */
# Line 447  void emul_machine_setup(struct machine * Line 419  void emul_machine_setup(struct machine *
419                  /*  TODO: This should be moved elsewhere...  */                  /*  TODO: This should be moved elsewhere...  */
420                  if (m->machine_type == MACHINE_BEBOX)                  if (m->machine_type == MACHINE_BEBOX)
421                          m->ncpus = 2;                          m->ncpus = 2;
                 else if (m->machine_type == MACHINE_ARC &&  
                     m->machine_subtype == MACHINE_ARC_NEC_R96)  
                         m->ncpus = 2;  
                 else if (m->machine_type == MACHINE_ARC &&  
                     m->machine_subtype == MACHINE_ARC_NEC_R98)  
                         m->ncpus = 4;  
422                  else                  else
423                          m->ncpus = 1;                          m->ncpus = 1;
424          }          }
425          m->cpus = malloc(sizeof(struct cpu *) * m->ncpus);  
426          if (m->cpus == NULL) {          CHECK_ALLOCATION(m->cpus = malloc(sizeof(struct cpu *) * m->ncpus));
                 fprintf(stderr, "out of memory\n");  
                 exit(1);  
         }  
427          memset(m->cpus, 0, sizeof(struct cpu *) * m->ncpus);          memset(m->cpus, 0, sizeof(struct cpu *) * m->ncpus);
428    
429          debug("cpu0");          debug("cpu0");
# Line 477  void emul_machine_setup(struct machine * Line 440  void emul_machine_setup(struct machine *
440          }          }
441          debug("\n");          debug("\n");
442    
 #if 0  
         /*  Special case: The Playstation Portable has an additional CPU:  */  
         if (m->machine_type == MACHINE_PSP) {  
                 debug("cpu%i: ", m->ncpus);  
                 m->cpus[m->ncpus] = cpu_new(m->memory, m,  
                     0  /*  use 0 here to show info with debug()  */,  
                     "Allegrex" /*  TODO  */);  
                 debug("\n");  
                 m->ncpus ++;  
         }  
 #endif  
   
443          if (m->use_random_bootstrap_cpu)          if (m->use_random_bootstrap_cpu)
444                  m->bootstrap_cpu = random() % m->ncpus;                  m->bootstrap_cpu = random() % m->ncpus;
445          else          else
# Line 502  void emul_machine_setup(struct machine * Line 453  void emul_machine_setup(struct machine *
453                      m->userland_emul, NULL, NULL, NULL);                      m->userland_emul, NULL, NULL, NULL);
454    
455                  switch (m->arch) {                  switch (m->arch) {
456  #ifdef ENABLE_ALPHA  
457                  case ARCH_ALPHA:                  case ARCH_ALPHA:
458                          cpu->memory_rw = alpha_userland_memory_rw;                          cpu->memory_rw = alpha_userland_memory_rw;
459                          break;                          break;
460  #endif  
461                  default:cpu->memory_rw = userland_memory_rw;                  default:
462                            cpu->memory_rw = userland_memory_rw;
463                  }                  }
464          }          }
465    
466          if (m->use_x11)          if (m->x11_md.in_use)
467                  x11_init(m);                  x11_init(m);
468    
469          /*  Fill memory with random bytes:  */          /*  Fill memory with random bytes:  */
# Line 580  void emul_machine_setup(struct machine * Line 532  void emul_machine_setup(struct machine *
532                          fread(buf, 1, sizeof(buf), tmp_f);                          fread(buf, 1, sizeof(buf), tmp_f);
533                          if (buf[0]==0x1f && buf[1]==0x8b) {                          if (buf[0]==0x1f && buf[1]==0x8b) {
534                                  size_t zzlen = strlen(name_to_load)*2 + 100;                                  size_t zzlen = strlen(name_to_load)*2 + 100;
535                                  char *zz = malloc(zzlen);                                  char *zz;
536    
537                                    CHECK_ALLOCATION(zz = malloc(zzlen));
538                                  debug("gunziping %s\n", name_to_load);                                  debug("gunziping %s\n", name_to_load);
539    
540                                  /*                                  /*
541                                   *  gzip header found.  If this was a file                                   *  gzip header found.  If this was a file
542                                   *  extracted from, say, a CDROM image, then it                                   *  extracted from, say, a CDROM image, then it
# Line 598  void emul_machine_setup(struct machine * Line 553  void emul_machine_setup(struct machine *
553                                  } else {                                  } else {
554                                          /*  gunzip into new temp file:  */                                          /*  gunzip into new temp file:  */
555                                          int tmpfile_handle;                                          int tmpfile_handle;
556                                          char *new_temp_name =                                          char *new_temp_name;
557                                              strdup("/tmp/gxemul.XXXXXXXXXXXX");                                          char *tmpdir = getenv("TMPDIR");
558    
559                                            if (tmpdir == NULL)
560                                                    tmpdir = DEFAULT_TMP_DIR;
561    
562                                            CHECK_ALLOCATION(new_temp_name =
563                                                malloc(300));
564                                            snprintf(new_temp_name, 300,
565                                                "%s/gxemul.XXXXXXXXXXXX", tmpdir);
566    
567                                          tmpfile_handle = mkstemp(new_temp_name);                                          tmpfile_handle = mkstemp(new_temp_name);
568                                          close(tmpfile_handle);                                          close(tmpfile_handle);
569                                          snprintf(zz, zzlen, "gunzip -c '%s' > "                                          snprintf(zz, zzlen, "gunzip -c '%s' > "
# Line 613  void emul_machine_setup(struct machine * Line 577  void emul_machine_setup(struct machine *
577                          fclose(tmp_f);                          fclose(tmp_f);
578                  }                  }
579    
                 /*  
                  *  Ugly (but usable) hack for Playstation Portable:  If the  
                  *  filename ends with ".pbp" and the file contains an ELF  
                  *  header, then extract the ELF file into a temporary file.  
                  */  
                 if (strlen(name_to_load) > 4 && strcasecmp(name_to_load +  
                     strlen(name_to_load) - 4, ".pbp") == 0 &&  
                     (tmp_f = fopen(name_to_load, "r")) != NULL) {  
                         off_t filesize, j, found=0;  
                         unsigned char *buf;  
                         fseek(tmp_f, 0, SEEK_END);  
                         filesize = ftello(tmp_f);  
                         fseek(tmp_f, 0, SEEK_SET);  
                         buf = malloc(filesize);  
                         if (buf == NULL) {  
                                 fprintf(stderr, "out of memory while trying"  
                                     " to read %s\n", name_to_load);  
                                 exit(1);  
                         }  
                         fread(buf, 1, filesize, tmp_f);  
                         fclose(tmp_f);  
                         /*  Search for the ELF header, from offset 1 (!):  */  
                         for (j=1; j<filesize - 4; j++)  
                                 if (memcmp(buf + j, ELFMAG, SELFMAG) == 0) {  
                                         found = j;  
                                         break;  
                                 }  
                         if (found != 0) {  
                                 int tmpfile_handle;  
                                 char *new_temp_name =  
                                     strdup("/tmp/gxemul.XXXXXXXXXXXX");  
                                 debug("extracting ELF from %s (offset 0x%x)\n",  
                                     name_to_load, (int)found);  
                                 tmpfile_handle = mkstemp(new_temp_name);  
                                 write(tmpfile_handle, buf + found,  
                                     filesize - found);  
                                 close(tmpfile_handle);  
                                 name_to_load = new_temp_name;  
                                 remove_after_load = 1;  
                         }  
                 }  
   
580                  byte_order = NO_BYTE_ORDER_OVERRIDE;                  byte_order = NO_BYTE_ORDER_OVERRIDE;
581    
582                  /*                  /*
# Line 688  void emul_machine_setup(struct machine * Line 610  void emul_machine_setup(struct machine *
610                          cpu->pc &= 0xfffffffc;                          cpu->pc &= 0xfffffffc;
611                          break;                          break;
612    
613                  case ARCH_AVR:                  case ARCH_M32R:
614                          cpu->pc &= 0xfffff;                          if (cpu->pc & 3) {
615                          if (cpu->pc & 1) {                                  fatal("M32R: lowest bits of pc set: TODO\n");
                                 fatal("AVR: lowest bit of pc set: TODO\n");  
616                                  exit(1);                                  exit(1);
617                          }                          }
618                            cpu->pc &= 0xfffffffc;
619                          break;                          break;
620    
621                  case ARCH_M68K:                  case ARCH_M88K:
622                            if (cpu->pc & 3) {
623                                    fatal("M88K: lowest bits of pc set: TODO\n");
624                                    exit(1);
625                            }
626                            cpu->pc &= 0xfffffffc;
627                          break;                          break;
628    
629                  case ARCH_MIPS:                  case ARCH_MIPS:
# Line 772  void emul_machine_setup(struct machine * Line 699  void emul_machine_setup(struct machine *
699                          m->cpus[i]->running = 0;                          m->cpus[i]->running = 0;
700          }          }
701    
702          /*  Add PC dump points:  */          /*  Parse and add breakpoints:  */
703          add_dump_points(m);          add_breakpoints(m);
704    
705          /*  TODO: This is MIPS-specific!  */          /*  TODO: This is MIPS-specific!  */
706          if (m->machine_type == MACHINE_PMAX &&          if (m->machine_type == MACHINE_PMAX &&
# Line 788  void emul_machine_setup(struct machine * Line 715  void emul_machine_setup(struct machine *
715              m->machine_type == MACHINE_SGI) && m->prom_emulation)              m->machine_type == MACHINE_SGI) && m->prom_emulation)
716                  add_arc_components(m);                  add_arc_components(m);
717    
718          debug("starting cpu%i at ", m->bootstrap_cpu);          debug("cpu%i: starting at ", m->bootstrap_cpu);
         switch (m->arch) {  
   
         case ARCH_ARM:  
                 /*  ARM cpus aren't 64-bit:  */  
                 debug("0x%08"PRIx32, (uint32_t) entrypoint);  
                 break;  
719    
720          case ARCH_AVR:          switch (m->arch) {
                 /*  Atmel AVR uses a 16-bit or 22-bit program counter:  */  
                 debug("0x%04x", (int) entrypoint);  
                 break;  
721    
722          case ARCH_MIPS:          case ARCH_MIPS:
723                  if (cpu->is_32bit) {                  if (cpu->is_32bit) {
# Line 818  void emul_machine_setup(struct machine * Line 736  void emul_machine_setup(struct machine *
736                  }                  }
737                  break;                  break;
738    
         case ARCH_PPC:  
                 if (cpu->cd.ppc.bits == 32)  
                         debug("0x%08"PRIx32, (uint32_t) entrypoint);  
                 else  
                         debug("0x%016"PRIx64, (uint64_t) entrypoint);  
                 break;  
   
739          default:          default:
740                  if (cpu->is_32bit)                  if (cpu->is_32bit)
741                          debug("0x%08"PRIx32, (uint32_t) cpu->pc);                          debug("0x%08"PRIx32, (uint32_t) cpu->pc);
# Line 844  void emul_machine_setup(struct machine * Line 755  void emul_machine_setup(struct machine *
755   */   */
756  void emul_dumpinfo(struct emul *e)  void emul_dumpinfo(struct emul *e)
757  {  {
758          int j, nm, iadd = DEBUG_INDENTATION;          int i;
759    
760          if (e->net != NULL)          if (e->net != NULL)
761                  net_dumpinfo(e->net);                  net_dumpinfo(e->net);
762    
763          nm = e->n_machines;          for (i = 0; i < e->n_machines; i++) {
764          for (j=0; j<nm; j++) {                  if (e->n_machines > 1)
765                  debug("machine %i: \"%s\"\n", j, e->machines[j]->name);                          debug("machine %i: \"%s\"\n", i, e->machines[i]->name);
766                  debug_indentation(iadd);                  else
767                  machine_dumpinfo(e->machines[j]);                          debug("machine:\n");
768                  debug_indentation(-iadd);  
769                    debug_indentation(DEBUG_INDENTATION);
770    
771                    machine_dumpinfo(e->machines[i]);
772    
773                    debug_indentation(-DEBUG_INDENTATION);
774          }          }
775  }  }
776    
# Line 910  void emul_simple_init(struct emul *emul) Line 826  void emul_simple_init(struct emul *emul)
826   *   *
827   *  Create an emul struct by reading settings from a configuration file.   *  Create an emul struct by reading settings from a configuration file.
828   */   */
829  struct emul *emul_create_from_configfile(char *fname, int id)  struct emul *emul_create_from_configfile(char *fname)
830  {  {
831          int iadd = DEBUG_INDENTATION;          int iadd = DEBUG_INDENTATION;
832          struct emul *e = emul_new(fname, id);          struct emul *e = emul_new(fname);
833    
834          debug("Creating emulation from configfile \"%s\":\n", fname);          debug("Creating emulation from configfile \"%s\":\n", fname);
835          debug_indentation(iadd);          debug_indentation(iadd);
# Line 928  struct emul *emul_create_from_configfile Line 844  struct emul *emul_create_from_configfile
844  /*  /*
845   *  emul_run():   *  emul_run():
846   *   *
847   *      o)  Set up things needed before running emulations.   *      o)  Set up things needed before running an emulation.
848   *   *
849   *      o)  Run emulations (one or more, in parallel).   *      o)  Run instructions in all machines.
850   *   *
851   *      o)  De-initialize things.   *      o)  De-initialize things.
852   */   */
853  void emul_run(struct emul **emuls, int n_emuls)  void emul_run(struct emul *emul)
854  {  {
         struct emul *e;  
855          int i = 0, j, go = 1, n, anything;          int i = 0, j, go = 1, n, anything;
856    
         if (n_emuls < 1) {  
                 fprintf(stderr, "emul_run(): no thing to do\n");  
                 return;  
         }  
   
857          atexit(fix_console);          atexit(fix_console);
858    
859          /*  Initialize the interactive debugger:  */          /*  Initialize the interactive debugger:  */
860          debugger_init(emuls, n_emuls);          debugger_init(emul);
861    
862          /*  Run any additional debugger commands before starting:  */          /*  Run any additional debugger commands before starting:  */
863          for (i=0; i<n_emuls; i++) {          if (emul->n_debugger_cmds > 0) {
864                  struct emul *emul = emuls[i];                  int j;
865                  if (emul->n_debugger_cmds > 0) {                  if (i == 0)
866                          int j;                          print_separator_line();
867                          if (i == 0)                  for (j = 0; j < emul->n_debugger_cmds; j ++) {
868                                  print_separator();                          debug("> %s\n", emul->debugger_cmds[j]);
869                          for (j = 0; j < emul->n_debugger_cmds; j ++) {                          debugger_execute_cmd(emul->debugger_cmds[j],
870                                  debug("> %s\n", emul->debugger_cmds[j]);                              strlen(emul->debugger_cmds[j]));
                                 debugger_execute_cmd(emul->debugger_cmds[j],  
                                     strlen(emul->debugger_cmds[j]));  
                         }  
871                  }                  }
872          }          }
873    
874          print_separator();          print_separator_line();
875          debug("\n");          debug("\n");
876    
877    
# Line 978  void emul_run(struct emul **emuls, int n Line 885  void emul_run(struct emul **emuls, int n
885           *  (or sends SIGSTOP) and then continues. It makes sure that the           *  (or sends SIGSTOP) and then continues. It makes sure that the
886           *  terminal is in an expected state.           *  terminal is in an expected state.
887           */           */
888          console_init_main(emuls[0]);    /*  TODO: what is a good argument?  */          console_init_main(emul);
889    
890          signal(SIGINT, debugger_activate);          signal(SIGINT, debugger_activate);
891          signal(SIGCONT, console_sigcont);          signal(SIGCONT, console_sigcont);
892    
# Line 986  void emul_run(struct emul **emuls, int n Line 894  void emul_run(struct emul **emuls, int n
894          if (!verbose)          if (!verbose)
895                  quiet_mode = 1;                  quiet_mode = 1;
896    
897          /*  Initialize all CPUs in all machines in all emulations:  */  
898          for (i=0; i<n_emuls; i++) {          /*  Initialize all CPUs in all machines:  */
899                  e = emuls[i];          for (j=0; j<emul->n_machines; j++)
900                  if (e == NULL)                  cpu_run_init(emul->machines[j]);
                         continue;  
                 for (j=0; j<e->n_machines; j++)  
                         cpu_run_init(e->machines[j]);  
         }  
901    
902          /*  TODO: Generalize:  */          /*  TODO: Generalize:  */
903          if (emuls[0]->machines[0]->show_trace_tree)          if (emul->machines[0]->show_trace_tree)
904                  cpu_functioncall_trace(emuls[0]->machines[0]->cpus[0],                  cpu_functioncall_trace(emul->machines[0]->cpus[0],
905                      emuls[0]->machines[0]->cpus[0]->pc);                      emul->machines[0]->cpus[0]->pc);
906    
907          /*  Start emulated clocks:  */          /*  Start emulated clocks:  */
908          timer_start();          timer_start();
909    
910    
911          /*          /*
912           *  MAIN LOOP:           *  MAIN LOOP:
913           *           *
914           *  Run all emulations in parallel, running each machine in           *  Run all emulations in parallel, running instructions from each
915           *  each emulation.           *  cpu in each machine.
916           */           */
917          while (go) {          while (go) {
918                    struct cpu *bootcpu = emul->machines[0]->cpus[
919                        emul->machines[0]->bootstrap_cpu];
920    
921                  go = 0;                  go = 0;
922    
923                  /*  Flush X11 and serial console output every now and then:  */                  /*  Flush X11 and serial console output every now and then:  */
924                  if (emuls[0]->machines[0]->ninstrs >                  if (bootcpu->ninstrs > bootcpu->ninstrs_flush + (1<<19)) {
925                      emuls[0]->machines[0]->ninstrs_flush + (1<<19)) {                          x11_check_event(emul);
                         x11_check_event(emuls, n_emuls);  
926                          console_flush();                          console_flush();
927                          emuls[0]->machines[0]->ninstrs_flush =                          bootcpu->ninstrs_flush = bootcpu->ninstrs;
                             emuls[0]->machines[0]->ninstrs;  
928                  }                  }
929    
930                  if (emuls[0]->machines[0]->ninstrs >                  if (bootcpu->ninstrs > bootcpu->ninstrs_show + (1<<25)) {
931                      emuls[0]->machines[0]->ninstrs_show + (1<<25)) {                          bootcpu->ninstrs_since_gettimeofday +=
932                          emuls[0]->machines[0]->ninstrs_since_gettimeofday +=                              (bootcpu->ninstrs - bootcpu->ninstrs_show);
933                              (emuls[0]->machines[0]->ninstrs -                          cpu_show_cycles(emul->machines[0], 0);
934                               emuls[0]->machines[0]->ninstrs_show);                          bootcpu->ninstrs_show = bootcpu->ninstrs;
                         cpu_show_cycles(emuls[0]->machines[0], 0);  
                         emuls[0]->machines[0]->ninstrs_show =  
                             emuls[0]->machines[0]->ninstrs;  
935                  }                  }
936    
937                  if (single_step == ENTER_SINGLE_STEPPING) {                  if (single_step == ENTER_SINGLE_STEPPING) {
938                          /*  TODO: Cleanup!  */                          /*  TODO: Cleanup!  */
939                          old_instruction_trace =                          old_instruction_trace =
940                              emuls[0]->machines[0]->instruction_trace;                              emul->machines[0]->instruction_trace;
941                          old_quiet_mode = quiet_mode;                          old_quiet_mode = quiet_mode;
942                          old_show_trace_tree =                          old_show_trace_tree =
943                              emuls[0]->machines[0]->show_trace_tree;                              emul->machines[0]->show_trace_tree;
944                          emuls[0]->machines[0]->instruction_trace = 1;                          emul->machines[0]->instruction_trace = 1;
945                          emuls[0]->machines[0]->show_trace_tree = 1;                          emul->machines[0]->show_trace_tree = 1;
946                          quiet_mode = 0;                          quiet_mode = 0;
947                          single_step = SINGLE_STEPPING;                          single_step = SINGLE_STEPPING;
948                  }                  }
# Line 1047  void emul_run(struct emul **emuls, int n Line 950  void emul_run(struct emul **emuls, int n
950                  if (single_step == SINGLE_STEPPING)                  if (single_step == SINGLE_STEPPING)
951                          debugger();                          debugger();
952    
953                  for (i=0; i<n_emuls; i++) {                  for (j=0; j<emul->n_machines; j++) {
954                          e = emuls[i];                          anything = machine_run(emul->machines[j]);
955                            if (anything)
956                          for (j=0; j<e->n_machines; j++) {                                  go = 1;
                                 anything = machine_run(e->machines[j]);  
                                 if (anything)  
                                         go = 1;  
                         }  
957                  }                  }
958          }          }
959    
960          /*  Stop any running timers:  */          /*  Stop any running timers:  */
961          timer_stop();          timer_stop();
962    
963          /*  Deinitialize all CPUs in all machines in all emulations:  */          /*  Deinitialize all CPUs in all machines:  */
964          for (i=0; i<n_emuls; i++) {          for (j=0; j<emul->n_machines; j++)
965                  e = emuls[i];                  cpu_run_deinit(emul->machines[j]);
                 if (e == NULL)  
                         continue;  
                 for (j=0; j<e->n_machines; j++)  
                         cpu_run_deinit(e->machines[j]);  
         }  
966    
967          /*  force_debugger_at_exit flag set? Then enter the debugger:  */          /*  force_debugger_at_exit flag set? Then enter the debugger:  */
968          if (force_debugger_at_exit) {          if (force_debugger_at_exit) {
# Line 1079  void emul_run(struct emul **emuls, int n Line 973  void emul_run(struct emul **emuls, int n
973    
974          /*  Any machine using X11? Then wait before exiting:  */          /*  Any machine using X11? Then wait before exiting:  */
975          n = 0;          n = 0;
976          for (i=0; i<n_emuls; i++)          for (j=0; j<emul->n_machines; j++)
977                  for (j=0; j<emuls[i]->n_machines; j++)                  if (emul->machines[j]->x11_md.in_use)
978                          if (emuls[i]->machines[j]->use_x11)                          n++;
979                                  n++;  
980          if (n > 0) {          if (n > 0) {
981                  printf("Press enter to quit.\n");                  printf("Press enter to quit.\n");
982                  while (!console_charavail(MAIN_CONSOLE)) {                  while (!console_charavail(MAIN_CONSOLE)) {
983                          x11_check_event(emuls, n_emuls);                          x11_check_event(emul);
984                          usleep(10000);                          usleep(10000);
985                  }                  }
986                  console_readchar(MAIN_CONSOLE);                  console_readchar(MAIN_CONSOLE);

Legend:
Removed from v.38  
changed lines
  Added in v.44

  ViewVC Help
Powered by ViewVC 1.1.26