/[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 43 by dpavlin, Mon Oct 8 16:22:32 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.297 2007/06/15 17:02:37 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 68  extern int old_show_trace_tree; Line 68  extern int old_show_trace_tree;
68  extern int old_instruction_trace;  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;
 extern int native_code_translation_enabled;  
71    
72    
73  /*  /*
# Line 121  static void add_breakpoints(struct machi Line 120  static void add_breakpoints(struct machi
120    
121                  m->breakpoints.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->breakpoints.string[i]);                          debug(" (%s)", m->breakpoints.string[i]);
126                  debug("\n");                  debug("\n");
# Line 143  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;
148    
149          CHECK_ALLOCATION(e = malloc(sizeof(struct emul)));          CHECK_ALLOCATION(e = malloc(sizeof(struct emul)));
150          memset(e, 0, sizeof(struct emul));          memset(e, 0, sizeof(struct emul));
151    
         CHECK_ALLOCATION(e->path = malloc(15));  
         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 365  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 554  void emul_machine_setup(struct machine * Line 554  void emul_machine_setup(struct machine *
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                                            char *tmpdir = getenv("TMPDIR");
558    
559                                            if (tmpdir == NULL)
560                                                    tmpdir = DEFAULT_TMP_DIR;
561    
562                                          CHECK_ALLOCATION(new_temp_name =                                          CHECK_ALLOCATION(new_temp_name =
563                                              strdup("/tmp/gxemul.XXXXXXXXXXXX"));                                              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 602  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_M32R:
614                            if (cpu->pc & 3) {
615                                    fatal("M32R: lowest bits of pc set: TODO\n");
616                                    exit(1);
617                            }
618                            cpu->pc &= 0xfffffffc;
619                            break;
620    
621                  case ARCH_M88K:                  case ARCH_M88K:
622                          if (cpu->pc & 3) {                          if (cpu->pc & 3) {
623                                  fatal("M88K: lowest bits of pc set: TODO\n");                                  fatal("M88K: lowest bits of pc set: TODO\n");
# Line 699  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) {  
719    
720          case ARCH_ARM:          switch (m->arch) {
                 /*  ARM cpus aren't 64-bit:  */  
                 debug("0x%08"PRIx32, (uint32_t) entrypoint);  
                 break;  
721    
722          case ARCH_MIPS:          case ARCH_MIPS:
723                  if (cpu->is_32bit) {                  if (cpu->is_32bit) {
# Line 724  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 750  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 816  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 834  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_line();                          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    
# Line 884  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 892  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 instructions from each           *  Run all emulations in parallel, running instructions from each
915           *  cpu in each machine in each emulation.           *  cpu in each machine.
916           */           */
917          while (go) {          while (go) {
918                  struct cpu *bootcpu = emuls[0]->machines[0]->cpus[                  struct cpu *bootcpu = emul->machines[0]->cpus[
919                      emuls[0]->machines[0]->bootstrap_cpu];                      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 (bootcpu->ninstrs > bootcpu->ninstrs_flush + (1<<19)) {                  if (bootcpu->ninstrs > bootcpu->ninstrs_flush + (1<<19)) {
925                          x11_check_event(emuls, n_emuls);                          x11_check_event(emul);
926                          console_flush();                          console_flush();
927                          bootcpu->ninstrs_flush = bootcpu->ninstrs;                          bootcpu->ninstrs_flush = bootcpu->ninstrs;
928                  }                  }
# Line 931  void emul_run(struct emul **emuls, int n Line 930  void emul_run(struct emul **emuls, int n
930                  if (bootcpu->ninstrs > bootcpu->ninstrs_show + (1<<25)) {                  if (bootcpu->ninstrs > bootcpu->ninstrs_show + (1<<25)) {
931                          bootcpu->ninstrs_since_gettimeofday +=                          bootcpu->ninstrs_since_gettimeofday +=
932                              (bootcpu->ninstrs - bootcpu->ninstrs_show);                              (bootcpu->ninstrs - bootcpu->ninstrs_show);
933                          cpu_show_cycles(emuls[0]->machines[0], 0);                          cpu_show_cycles(emul->machines[0], 0);
934                          bootcpu->ninstrs_show = bootcpu->ninstrs;                          bootcpu->ninstrs_show = bootcpu->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 951  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 983  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]->x11_md.in_use)                          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.43  
changed lines
  Added in v.44

  ViewVC Help
Powered by ViewVC 1.1.26