/[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 18 by dpavlin, Mon Oct 8 16:19:11 2007 UTC revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: emul.c,v 1.235 2005/10/26 14:37:02 debug Exp $   *  $Id: emul.c,v 1.272 2006/10/31 08:26:56 debug Exp $
29   *   *
30   *  Emulation startup and misc. routines.   *  Emulation startup and misc. routines.
31   */   */
# Line 39  Line 39 
39  #include <unistd.h>  #include <unistd.h>
40    
41  #include "arcbios.h"  #include "arcbios.h"
 #include "bintrans.h"  
42  #include "cpu.h"  #include "cpu.h"
43  #include "emul.h"  #include "emul.h"
44  #include "console.h"  #include "console.h"
# Line 52  Line 51 
51  #include "mips_cpu_types.h"  #include "mips_cpu_types.h"
52  #include "misc.h"  #include "misc.h"
53  #include "net.h"  #include "net.h"
54    #include "settings.h"
55  #include "sgi_arcbios.h"  #include "sgi_arcbios.h"
56    #include "timer.h"
57  #include "x11.h"  #include "x11.h"
58    
59    
 extern int force_debugger_at_exit;  
   
60  extern int extra_argc;  extern int extra_argc;
61  extern char **extra_argv;  extern char **extra_argv;
62    
63  extern int verbose;  extern int verbose;
64  extern int quiet_mode;  extern int quiet_mode;
65    extern int force_debugger_at_exit;
66    extern int single_step;
67    extern int old_show_trace_tree;
68    extern int old_instruction_trace;
69    extern int old_quiet_mode;
70    extern int quiet_mode;
71    
72  extern struct emul *debugger_emul;  extern struct emul *debugger_emul;
73  extern struct diskimage *diskimages[];  extern struct diskimage *diskimages[];
# Line 70  extern struct diskimage *diskimages[]; Line 75  extern struct diskimage *diskimages[];
75  static char *diskimage_types[] = DISKIMAGE_TYPES;  static char *diskimage_types[] = DISKIMAGE_TYPES;
76    
77    
78    static void print_separator(void)
79    {
80            int i = 79;
81            while (i-- > 0)
82                    debug("-");
83            debug("\n");
84    }
85    
86    
87  /*  /*
88   *  add_dump_points():   *  add_dump_points():
89   *   *
# Line 96  static void add_dump_points(struct machi Line 110  static void add_dump_points(struct machi
110                          uint64_t addr;                          uint64_t addr;
111                          int res = get_symbol_addr(&m->symbol_context,                          int res = get_symbol_addr(&m->symbol_context,
112                              m->breakpoint_string[i], &addr);                              m->breakpoint_string[i], &addr);
113                          if (!res)                          if (!res) {
114                                  fprintf(stderr,                                  fprintf(stderr,
115                                      "WARNING! Breakpoint '%s' could not be"                                      "ERROR! Breakpoint '%s' could not be"
116                                          " parsed\n",                                          " parsed\n",
117                                      m->breakpoint_string[i]);                                      m->breakpoint_string[i]);
118                          else {                          } else {
119                                  dp = addr;                                  dp = addr;
120                                  string_flag = 1;                                  string_flag = 1;
121                          }                          }
# Line 112  static void add_dump_points(struct machi Line 126  static void add_dump_points(struct machi
126                   *  were automatically converted into the correct address.                   *  were automatically converted into the correct address.
127                   */                   */
128    
129                  if ((dp >> 32) == 0 && ((dp >> 31) & 1))                  if (m->arch == ARCH_MIPS) {
130                          dp |= 0xffffffff00000000ULL;                          if ((dp >> 32) == 0 && ((dp >> 31) & 1))
131                                    dp |= 0xffffffff00000000ULL;
132                    }
133    
134                  m->breakpoint_addr[i] = dp;                  m->breakpoint_addr[i] = dp;
135    
136                  debug("breakpoint %i: 0x%016llx", i, (long long)dp);                  debug("breakpoint %i: 0x%llx", i, (long long)dp);
137                  if (string_flag)                  if (string_flag)
138                          debug(" (%s)", m->breakpoint_string[i]);                          debug(" (%s)", m->breakpoint_string[i]);
139                  debug("\n");                  debug("\n");
# Line 129  static void add_dump_points(struct machi Line 146  static void add_dump_points(struct machi
146   */   */
147  static void fix_console(void)  static void fix_console(void)
148  {  {
149          console_deinit();          console_deinit_main();
150  }  }
151    
152    
# Line 149  static int iso_load_bootblock(struct mac Line 166  static int iso_load_bootblock(struct mac
166          int *n_loadp, char ***load_namesp)          int *n_loadp, char ***load_namesp)
167  {  {
168          char str[35];          char str[35];
169          int filenr, i, ofs, dirlen, res = 0, res2, iadd = 4;          int filenr, i, ofs, dirlen, res = 0, res2, iadd = DEBUG_INDENTATION;
170          int found_dir;          int found_dir;
171          uint64_t dirofs;          uint64_t dirofs;
172          uint64_t fileofs, filelen;          uint64_t fileofs, filelen;
# Line 158  static int iso_load_bootblock(struct mac Line 175  static int iso_load_bootblock(struct mac
175          char *p, *filename_orig;          char *p, *filename_orig;
176          char *filename = strdup(cpu->machine->boot_kernel_filename);          char *filename = strdup(cpu->machine->boot_kernel_filename);
177          unsigned char *filebuf = NULL;          unsigned char *filebuf = NULL;
178          char *tmpfilename = NULL;          char *tmpfname = NULL;
179          char **new_array;          char **new_array;
180          int tmpfile_handle;          int tmpfile_handle;
181    
# Line 204  static int iso_load_bootblock(struct mac Line 221  static int iso_load_bootblock(struct mac
221                  fatal("WARNING: Root directory length mismatch?\n");                  fatal("WARNING: Root directory length mismatch?\n");
222    
223          dirofs = (int64_t)(buf[0x8c] + (buf[0x8d] << 8) + (buf[0x8e] << 16) +          dirofs = (int64_t)(buf[0x8c] + (buf[0x8d] << 8) + (buf[0x8e] << 16) +
224              (buf[0x8f] << 24)) * 2048;              ((uint64_t)buf[0x8f] << 24)) * 2048;
225    
226          /*  debug("root = %i bytes at 0x%llx\n", dirlen, (long long)dirofs);  */          /*  debug("root = %i bytes at 0x%llx\n", dirlen, (long long)dirofs);  */
227    
# Line 225  static int iso_load_bootblock(struct mac Line 242  static int iso_load_bootblock(struct mac
242          dp = dirbuf; filenr = 1;          dp = dirbuf; filenr = 1;
243          p = NULL;          p = NULL;
244          while (dp < dirbuf + dirlen) {          while (dp < dirbuf + dirlen) {
245                  int i, nlen = dp[0];                  size_t i, nlen = dp[0];
246                  int x = dp[2] + (dp[3] << 8) + (dp[4] << 16) + (dp[5] << 24);                  int x = dp[2] + (dp[3] << 8) + (dp[4] << 16) +
247                        ((uint64_t)dp[5] << 24);
248                  int y = dp[6] + (dp[7] << 8);                  int y = dp[6] + (dp[7] << 8);
249                  char direntry[65];                  char direntry[65];
250    
# Line 296  static int iso_load_bootblock(struct mac Line 314  static int iso_load_bootblock(struct mac
314          }          }
315    
316          for (;;) {          for (;;) {
317                  int len, i;                  size_t len, i;
318    
319                  /*  Too close to another sector? Then realign.  */                  /*  Too close to another sector? Then realign.  */
320                  if ((dirofs & 2047) + 70 > 2047) {                  if ((dirofs & 2047) + 70 > 2047) {
# Line 361  static int iso_load_bootblock(struct mac Line 379  static int iso_load_bootblock(struct mac
379          }          }
380    
381          fileofs = match_entry[2] + (match_entry[3] << 8) +          fileofs = match_entry[2] + (match_entry[3] << 8) +
382              (match_entry[4] << 16) + (match_entry[5] << 24);              (match_entry[4] << 16) + ((uint64_t)match_entry[5] << 24);
383          filelen = match_entry[10] + (match_entry[11] << 8) +          filelen = match_entry[10] + (match_entry[11] << 8) +
384              (match_entry[12] << 16) + (match_entry[13] << 24);              (match_entry[12] << 16) + ((uint64_t)match_entry[13] << 24);
385          fileofs *= 2048;          fileofs *= 2048;
386    
387          /*  debug("filelen=%llx fileofs=%llx\n", (long long)filelen,          /*  debug("filelen=%llx fileofs=%llx\n", (long long)filelen,
# Line 376  static int iso_load_bootblock(struct mac Line 394  static int iso_load_bootblock(struct mac
394                  goto ret;                  goto ret;
395          }          }
396    
397          tmpfilename = strdup("/tmp/gxemul.XXXXXXXXXXXX");          tmpfname = strdup("/tmp/gxemul.XXXXXXXXXXXX");
   
         debug("extracting %lli bytes into %s\n",  
             (long long)filelen, tmpfilename);  
398    
399          res2 = diskimage_access(m, disk_id, disk_type, 0, fileofs, filebuf,          res2 = diskimage_access(m, disk_id, disk_type, 0, fileofs, filebuf,
400              filelen);              filelen);
# Line 388  static int iso_load_bootblock(struct mac Line 403  static int iso_load_bootblock(struct mac
403                  goto ret;                  goto ret;
404          }          }
405    
406          tmpfile_handle = mkstemp(tmpfilename);          tmpfile_handle = mkstemp(tmpfname);
407          if (tmpfile_handle < 0) {          if (tmpfile_handle < 0) {
408                  fatal("could not create %s\n", tmpfilename);                  fatal("could not create %s\n", tmpfname);
409                  exit(1);                  exit(1);
410          }          }
411          write(tmpfile_handle, filebuf, filelen);          write(tmpfile_handle, filebuf, filelen);
412          close(tmpfile_handle);          close(tmpfile_handle);
413    
414            debug("extracted %lli bytes into %s\n", (long long)filelen, tmpfname);
415    
416          /*  Add the temporary filename to the load_namesp array:  */          /*  Add the temporary filename to the load_namesp array:  */
417          (*n_loadp)++;          (*n_loadp)++;
418          new_array = malloc(sizeof(char *) * (*n_loadp));          new_array = malloc(sizeof(char *) * (*n_loadp));
# Line 409  static int iso_load_bootblock(struct mac Line 426  static int iso_load_bootblock(struct mac
426          /*  This adds a Backspace char in front of the filename; this          /*  This adds a Backspace char in front of the filename; this
427              is a special hack which causes the file to be removed once              is a special hack which causes the file to be removed once
428              it has been loaded.  */              it has been loaded.  */
429          tmpfilename = realloc(tmpfilename, strlen(tmpfilename) + 2);          tmpfname = realloc(tmpfname, strlen(tmpfname) + 2);
430          memmove(tmpfilename + 1, tmpfilename, strlen(tmpfilename) + 1);          memmove(tmpfname + 1, tmpfname, strlen(tmpfname) + 1);
431          tmpfilename[0] = 8;          tmpfname[0] = 8;
432    
433          (*load_namesp)[*n_loadp - 1] = tmpfilename;          (*load_namesp)[*n_loadp - 1] = tmpfname;
434    
435          res = 1;          res = 1;
436    
# Line 466  static int apple_load_bootblock(struct m Line 483  static int apple_load_bootblock(struct m
483                  int ofs = 0x200 * (partnr + 1);                  int ofs = 0x200 * (partnr + 1);
484                  if (partnr == 0)                  if (partnr == 0)
485                          n_partitions = buf[ofs + 7];                          n_partitions = buf[ofs + 7];
486                  start = (buf[ofs + 8] << 24) + (buf[ofs + 9] << 16) +                  start = ((uint64_t)buf[ofs + 8] << 24) + (buf[ofs + 9] << 16) +
487                      (buf[ofs + 10] << 8) + buf[ofs + 11];                      (buf[ofs + 10] << 8) + buf[ofs + 11];
488                  length = (buf[ofs + 12] << 24) + (buf[ofs + 13] << 16) +                  length = ((uint64_t)buf[ofs+12] << 24) + (buf[ofs + 13] << 16) +
489                      (buf[ofs + 14] << 8) + buf[ofs + 15];                      (buf[ofs + 14] << 8) + buf[ofs + 15];
490    
491                  debug("partition %i: '%s', type '%s', start %i, length %i\n",                  debug("partition %i: '%s', type '%s', start %i, length %i\n",
# Line 523  static int load_bootblock(struct machine Line 540  static int load_bootblock(struct machine
540                  return 0;                  return 0;
541    
542          switch (m->machine_type) {          switch (m->machine_type) {
543          case MACHINE_DEC:          case MACHINE_PMAX:
544                  /*                  /*
545                   *  The first few bytes of a disk contains information about                   *  The first few bytes of a disk contains information about
546                   *  where the bootblock(s) are located. (These are all 32-bit                   *  where the bootblock(s) are located. (These are all 32-bit
# Line 544  static int load_bootblock(struct machine Line 561  static int load_bootblock(struct machine
561                      minibuf, sizeof(minibuf));                      minibuf, sizeof(minibuf));
562    
563                  bootblock_loadaddr = minibuf[0x10] + (minibuf[0x11] << 8)                  bootblock_loadaddr = minibuf[0x10] + (minibuf[0x11] << 8)
564                    + (minibuf[0x12] << 16) + (minibuf[0x13] << 24);                    + (minibuf[0x12] << 16) + ((uint64_t)minibuf[0x13] << 24);
565    
566                  /*  Convert loadaddr to uncached:  */                  /*  Convert loadaddr to uncached:  */
567                  if ((bootblock_loadaddr & 0xf0000000ULL) != 0x80000000 &&                  if ((bootblock_loadaddr & 0xf0000000ULL) != 0x80000000 &&
568                      (bootblock_loadaddr & 0xf0000000ULL) != 0xa0000000)                      (bootblock_loadaddr & 0xf0000000ULL) != 0xa0000000) {
569                          fatal("\nWARNING! Weird load address 0x%08x.\n\n",                          fatal("\nWARNING! Weird load address 0x%08"PRIx32
570                              (int)bootblock_loadaddr);                              " for SCSI id %i.\n\n",
571                                (uint32_t)bootblock_loadaddr, boot_disk_id);
572                            if (bootblock_loadaddr == 0) {
573                                    fatal("I'm assuming that this is _not_ a "
574                                        "DEC bootblock.\nAre you sure you are"
575                                        " booting from the correct disk?\n");
576                                    exit(1);
577                            }
578                    }
579    
580                  bootblock_loadaddr &= 0x0fffffffULL;                  bootblock_loadaddr &= 0x0fffffffULL;
581                  bootblock_loadaddr |= 0xffffffffa0000000ULL;                  bootblock_loadaddr |= 0xffffffffa0000000ULL;
582    
583                  bootblock_pc = minibuf[0x14] + (minibuf[0x15] << 8)                  bootblock_pc = minibuf[0x14] + (minibuf[0x15] << 8)
584                    + (minibuf[0x16] << 16) + (minibuf[0x17] << 24);                    + (minibuf[0x16] << 16) + ((uint64_t)minibuf[0x17] << 24);
585    
586                  bootblock_pc &= 0x0fffffffULL;                  bootblock_pc &= 0x0fffffffULL;
587                  bootblock_pc |= 0xffffffffa0000000ULL;                  bootblock_pc |= 0xffffffffa0000000ULL;
# Line 576  static int load_bootblock(struct machine Line 602  static int load_bootblock(struct machine
602                          }                          }
603    
604                          n_blocks = minibuf[0] + (minibuf[1] << 8)                          n_blocks = minibuf[0] + (minibuf[1] << 8)
605                            + (minibuf[2] << 16) + (minibuf[3] << 24);                            + (minibuf[2] << 16) + ((uint64_t)minibuf[3] << 24);
606    
607                          bootblock_offset = (minibuf[4] + (minibuf[5] << 8)                          bootblock_offset = (minibuf[4] + (minibuf[5] << 8) +
608                            + (minibuf[6] << 16) + (minibuf[7] << 24)) * 512;                            (minibuf[6]<<16) + ((uint64_t)minibuf[7]<<24)) * 512;
609    
610                          if (n_blocks < 1)                          if (n_blocks < 1)
611                                  break;                                  break;
# Line 675  static int load_bootblock(struct machine Line 701  static int load_bootblock(struct machine
701                  iso_type = 3;                  iso_type = 3;
702    
703          if (iso_type != 0) {          if (iso_type != 0) {
704                  /*  We can't load a kernel if the name                  /*
705                      isn't specified.  */                   *  If the user specified a kernel name, then load it from
706                     *  disk.
707                     */
708                  if (cpu->machine->boot_kernel_filename == NULL ||                  if (cpu->machine->boot_kernel_filename == NULL ||
709                      cpu->machine->boot_kernel_filename[0] == '\0')                      cpu->machine->boot_kernel_filename[0] == '\0')
710                          fatal("\nISO9660 filesystem, but no kernel "                          fatal("\nISO9660 filesystem, but no kernel "
# Line 699  static int load_bootblock(struct machine Line 727  static int load_bootblock(struct machine
727          }          }
728          if (bootblock_buf[0x000] == 'E' && bootblock_buf[0x001] == 'R' &&          if (bootblock_buf[0x000] == 'E' && bootblock_buf[0x001] == 'R' &&
729              bootblock_buf[0x200] == 'P' && bootblock_buf[0x201] == 'M') {              bootblock_buf[0x200] == 'P' && bootblock_buf[0x201] == 'M') {
                 /*  We can't load a kernel if the name  
                     isn't specified.  */  
730                  if (cpu->machine->boot_kernel_filename == NULL ||                  if (cpu->machine->boot_kernel_filename == NULL ||
731                      cpu->machine->boot_kernel_filename[0] == '\0')                      cpu->machine->boot_kernel_filename[0] == '\0')
732                          fatal("\nApple partition table, but no kernel "                          fatal("\nApple partition table, but no kernel "
# Line 732  struct emul *emul_new(char *name) Line 758  struct emul *emul_new(char *name)
758    
759          memset(e, 0, sizeof(struct emul));          memset(e, 0, sizeof(struct emul));
760    
761            e->settings = settings_new();
762    
763            settings_add(e->settings, "n_machines", 0,
764                SETTINGS_TYPE_INT, SETTINGS_FORMAT_DECIMAL,
765                (void *) &e->n_machines);
766    
767            /*  TODO: More settings?  */
768    
769          /*  Sane default values:  */          /*  Sane default values:  */
770          e->n_machines = 0;          e->n_machines = 0;
771          e->next_serial_nr = 1;          e->next_serial_nr = 1;
# Line 742  struct emul *emul_new(char *name) Line 776  struct emul *emul_new(char *name)
776                          fprintf(stderr, "out of memory in emul_new()\n");                          fprintf(stderr, "out of memory in emul_new()\n");
777                          exit(1);                          exit(1);
778                  }                  }
779    
780                    settings_add(e->settings, "name", 0,
781                        SETTINGS_TYPE_STRING, SETTINGS_FORMAT_STRING,
782                        (void *) &e->name);
783          }          }
784    
785          return e;          return e;
# Line 749  struct emul *emul_new(char *name) Line 787  struct emul *emul_new(char *name)
787    
788    
789  /*  /*
790     *  emul_destroy():
791     *
792     *  Destroys a previously created emul object.
793     */
794    void emul_destroy(struct emul *emul)
795    {
796            int i;
797    
798            if (emul->name != NULL) {
799                    settings_remove(emul->settings, "name");
800                    free(emul->name);
801            }
802    
803            for (i=0; i<emul->n_machines; i++)
804                    machine_destroy(emul->machines[i]);
805    
806            if (emul->machines != NULL)
807                    free(emul->machines);
808    
809            /*  Remove any remaining level-1 settings:  */
810            settings_remove_all(emul->settings);
811            settings_destroy(emul->settings);
812    
813            free(emul);
814    }
815    
816    
817    /*
818   *  emul_add_machine():   *  emul_add_machine():
819   *   *
820   *  Calls machine_new(), adds the new machine into the emul struct, and   *  Calls machine_new(), adds the new machine into the emul struct, and
# Line 759  struct emul *emul_new(char *name) Line 825  struct emul *emul_new(char *name)
825  struct machine *emul_add_machine(struct emul *e, char *name)  struct machine *emul_add_machine(struct emul *e, char *name)
826  {  {
827          struct machine *m;          struct machine *m;
828            char tmpstr[20];
829            int i;
830    
831          m = machine_new(name, e);          m = machine_new(name, e);
832          m->serial_nr = (e->next_serial_nr ++);          m->serial_nr = (e->next_serial_nr ++);
833    
834            i = e->n_machines;
835    
836          e->n_machines ++;          e->n_machines ++;
837          e->machines = realloc(e->machines,          e->machines = realloc(e->machines,
838              sizeof(struct machine *) * e->n_machines);              sizeof(struct machine *) * e->n_machines);
# Line 771  struct machine *emul_add_machine(struct Line 841  struct machine *emul_add_machine(struct
841                  exit(1);                  exit(1);
842          }          }
843    
844          e->machines[e->n_machines - 1] = m;          e->machines[i] = m;
845    
846            snprintf(tmpstr, sizeof(tmpstr), "machine[%i]", i);
847            settings_add(e->settings, tmpstr, 1, SETTINGS_TYPE_SUBSETTINGS, 0,
848                e->machines[i]->settings);
849    
850          return m;          return m;
851  }  }
852    
# Line 900  static void add_arc_components(struct ma Line 975  static void add_arc_components(struct ma
975  void emul_machine_setup(struct machine *m, int n_load, char **load_names,  void emul_machine_setup(struct machine *m, int n_load, char **load_names,
976          int n_devices, char **device_names)          int n_devices, char **device_names)
977  {  {
         struct emul *emul;  
978          struct cpu *cpu;          struct cpu *cpu;
979          int i, iadd=4;          int i, iadd = DEBUG_INDENTATION;
980          uint64_t memory_amount, entrypoint = 0, gp = 0, toc = 0;          uint64_t memory_amount, entrypoint = 0, gp = 0, toc = 0;
981          int byte_order;          int byte_order;
982    
         emul = m->emul;  
   
983          debug("machine \"%s\":\n", m->name);          debug("machine \"%s\":\n", m->name);
984          debug_indentation(iadd);          debug_indentation(iadd);
985    
# Line 931  void emul_machine_setup(struct machine * Line 1003  void emul_machine_setup(struct machine *
1003          if (m->arch == ARCH_ALPHA)          if (m->arch == ARCH_ALPHA)
1004                  m->arch_pagesize = 8192;                  m->arch_pagesize = 8192;
1005    
         if (m->arch != ARCH_MIPS)  
                 m->bintrans_enable = 0;  
   
1006          machine_memsize_fix(m);          machine_memsize_fix(m);
1007    
1008          /*          /*
# Line 981  void emul_machine_setup(struct machine * Line 1050  void emul_machine_setup(struct machine *
1050          }          }
1051          memset(m->cpus, 0, sizeof(struct cpu *) * m->ncpus);          memset(m->cpus, 0, sizeof(struct cpu *) * m->ncpus);
1052    
         /*  Initialize dynamic binary translation, if available:  */  
         if (m->bintrans_enable)  
                 bintrans_init(m, m->memory);  
   
1053          debug("cpu0");          debug("cpu0");
1054          if (m->ncpus > 1)          if (m->ncpus > 1)
1055                  debug(" .. cpu%i", m->ncpus - 1);                  debug(" .. cpu%i", m->ncpus - 1);
1056          debug(": ");          debug(": ");
1057          for (i=0; i<m->ncpus; i++) {          for (i=0; i<m->ncpus; i++) {
1058                  m->cpus[i] = cpu_new(m->memory, m, i, m->cpu_name);                  m->cpus[i] = cpu_new(m->memory, m, i, m->cpu_name);
1059                  if (m->bintrans_enable)                  if (m->cpus[i] == NULL) {
1060                          bintrans_init_cpu(m->cpus[i]);                          fprintf(stderr, "Unable to create CPU object. "
1061                                "Aborting.");
1062                            exit(1);
1063                    }
1064          }          }
1065          debug("\n");          debug("\n");
1066    
# Line 1003  void emul_machine_setup(struct machine * Line 1071  void emul_machine_setup(struct machine *
1071                  m->cpus[m->ncpus] = cpu_new(m->memory, m,                  m->cpus[m->ncpus] = cpu_new(m->memory, m,
1072                      0  /*  use 0 here to show info with debug()  */,                      0  /*  use 0 here to show info with debug()  */,
1073                      "Allegrex" /*  TODO  */);                      "Allegrex" /*  TODO  */);
                 if (m->bintrans_enable)  
                         bintrans_init_cpu(m->cpus[m->ncpus]);  
1074                  debug("\n");                  debug("\n");
1075                  m->ncpus ++;                  m->ncpus ++;
1076          }          }
# Line 1060  void emul_machine_setup(struct machine * Line 1126  void emul_machine_setup(struct machine *
1126          }          }
1127    
1128          diskimage_dump_info(m);          diskimage_dump_info(m);
1129            console_debug_dump(m);
1130    
1131          /*  Load files (ROM code, boot code, ...) into memory:  */          /*  Load files (ROM code, boot code, ...) into memory:  */
1132          if (n_load == 0) {          if (n_load == 0) {
# Line 1215  void emul_machine_setup(struct machine * Line 1282  void emul_machine_setup(struct machine *
1282                          break;                          break;
1283    
1284                  case ARCH_ARM:                  case ARCH_ARM:
1285                            if (cpu->pc & 3) {
1286                                    fatal("ARM: lowest bits of pc set: TODO\n");
1287                                    exit(1);
1288                            }
1289                          cpu->pc &= 0xfffffffc;                          cpu->pc &= 0xfffffffc;
                         cpu->cd.arm.r[ARM_PC] = cpu->pc;  
1290                          break;                          break;
1291    
1292                  case ARCH_AVR:                  case ARCH_AVR:
# Line 1227  void emul_machine_setup(struct machine * Line 1297  void emul_machine_setup(struct machine *
1297                          }                          }
1298                          break;                          break;
1299    
1300                    case ARCH_AVR32:
1301                            cpu->pc = (uint32_t) cpu->pc;
1302                            if (cpu->pc & 1) {
1303                                    fatal("AVR32: lowest bit of pc set: TODO\n");
1304                                    exit(1);
1305                            }
1306                            break;
1307    
1308                    case ARCH_RCA180X:
1309                            cpu->pc &= 0xffff;
1310                            break;
1311    
1312                  case ARCH_HPPA:                  case ARCH_HPPA:
1313                          break;                          break;
1314    
# Line 1240  void emul_machine_setup(struct machine * Line 1322  void emul_machine_setup(struct machine *
1322                          break;                          break;
1323    
1324                  case ARCH_MIPS:                  case ARCH_MIPS:
1325                          if ((cpu->pc >> 32) == 0                          if ((cpu->pc >> 32) == 0 && (cpu->pc & 0x80000000ULL))
                             && (cpu->pc & 0x80000000ULL))  
1326                                  cpu->pc |= 0xffffffff00000000ULL;                                  cpu->pc |= 0xffffffff00000000ULL;
1327    
1328                          cpu->cd.mips.gpr[MIPS_GPR_GP] = gp;                          cpu->cd.mips.gpr[MIPS_GPR_GP] = gp;
# Line 1262  void emul_machine_setup(struct machine * Line 1343  void emul_machine_setup(struct machine *
1343                          break;                          break;
1344    
1345                  case ARCH_SH:                  case ARCH_SH:
1346                          if (cpu->cd.sh.bits == 32)                          if (cpu->cd.sh.cpu_type.bits == 32)
1347                                  cpu->pc &= 0xffffffffULL;                                  cpu->pc &= 0xffffffffULL;
1348                          cpu->pc &= ~1;                          cpu->pc &= ~1;
1349                          break;                          break;
# Line 1270  void emul_machine_setup(struct machine * Line 1351  void emul_machine_setup(struct machine *
1351                  case ARCH_SPARC:                  case ARCH_SPARC:
1352                          break;                          break;
1353    
1354                    case ARCH_TRANSPUTER:
1355                            cpu->pc &= 0xffffffffULL;
1356                            break;
1357    
1358                  case ARCH_X86:                  case ARCH_X86:
1359                          /*                          /*
1360                           *  NOTE: The toc field is used to indicate an ELF32                           *  NOTE: The toc field is used to indicate an ELF32
# Line 1323  void emul_machine_setup(struct machine * Line 1408  void emul_machine_setup(struct machine *
1408                  useremul_setup(cpu, n_load, load_names);                  useremul_setup(cpu, n_load, load_names);
1409    
1410          /*  Startup the bootstrap CPU:  */          /*  Startup the bootstrap CPU:  */
1411          cpu->bootstrap_cpu_flag = 1;          cpu->running = 1;
         cpu->running            = 1;  
1412    
1413          /*  ... or pause all CPUs, if start_paused is set:  */          /*  ... or pause all CPUs, if start_paused is set:  */
1414          if (m->start_paused) {          if (m->start_paused) {
# Line 1336  void emul_machine_setup(struct machine * Line 1420  void emul_machine_setup(struct machine *
1420          add_dump_points(m);          add_dump_points(m);
1421    
1422          /*  TODO: This is MIPS-specific!  */          /*  TODO: This is MIPS-specific!  */
1423          if (m->machine_type == MACHINE_DEC &&          if (m->machine_type == MACHINE_PMAX &&
1424              cpu->cd.mips.cpu_type.mmu_model == MMU3K)              cpu->cd.mips.cpu_type.mmu_model == MMU3K)
1425                  add_symbol_name(&m->symbol_context,                  add_symbol_name(&m->symbol_context,
1426                      0x9fff0000, 0x10000, "r2k3k_cache", 0, 0);                      0x9fff0000, 0x10000, "r2k3k_cache", 0, 0);
1427    
1428          symbol_recalc_sizes(&m->symbol_context);          symbol_recalc_sizes(&m->symbol_context);
1429    
         if (m->max_random_cycles_per_chunk > 0)  
                 debug("using random cycle chunks (1 to %i cycles)\n",  
                     m->max_random_cycles_per_chunk);  
   
1430          /*  Special hack for ARC/SGI emulation:  */          /*  Special hack for ARC/SGI emulation:  */
1431          if ((m->machine_type == MACHINE_ARC ||          if ((m->machine_type == MACHINE_ARC ||
1432              m->machine_type == MACHINE_SGI) && m->prom_emulation)              m->machine_type == MACHINE_SGI) && m->prom_emulation)
# Line 1395  void emul_machine_setup(struct machine * Line 1475  void emul_machine_setup(struct machine *
1475                  break;                  break;
1476    
1477          default:          default:
1478                  debug("0x%016llx", (long long)cpu->pc);                  if (cpu->is_32bit)
1479                            debug("0x%08x", (int)cpu->pc);
1480                    else
1481                            debug("0x%016llx", (long long)cpu->pc);
1482          }          }
1483          debug("\n");          debug("\n");
1484    
# Line 1410  void emul_machine_setup(struct machine * Line 1493  void emul_machine_setup(struct machine *
1493   */   */
1494  void emul_dumpinfo(struct emul *e)  void emul_dumpinfo(struct emul *e)
1495  {  {
1496          int j, nm, iadd = 4;          int j, nm, iadd = DEBUG_INDENTATION;
1497    
1498          if (e->net != NULL)          if (e->net != NULL)
1499                  net_dumpinfo(e->net);                  net_dumpinfo(e->net);
# Line 1439  void emul_dumpinfo(struct emul *e) Line 1522  void emul_dumpinfo(struct emul *e)
1522   */   */
1523  void emul_simple_init(struct emul *emul)  void emul_simple_init(struct emul *emul)
1524  {  {
1525          int iadd=4;          int iadd = DEBUG_INDENTATION;
1526          struct machine *m;          struct machine *m;
1527    
1528          if (emul->n_machines != 1) {          if (emul->n_machines != 1) {
# Line 1455  void emul_simple_init(struct emul *emul) Line 1538  void emul_simple_init(struct emul *emul)
1538    
1539                  /*  Create a simple network:  */                  /*  Create a simple network:  */
1540                  emul->net = net_init(emul, NET_INIT_FLAG_GATEWAY,                  emul->net = net_init(emul, NET_INIT_FLAG_GATEWAY,
1541                      "10.0.0.0", 8, NULL, 0, 0);                      NET_DEFAULT_IPV4_MASK,
1542                        NET_DEFAULT_IPV4_LEN,
1543                        NULL, 0, 0, NULL);
1544          } else {          } else {
1545                  /*  Userland pseudo-machine:  */                  /*  Userland pseudo-machine:  */
1546                  debug("Syscall emulation (userland-only) setup...\n");                  debug("Syscall emulation (userland-only) setup...\n");
# Line 1476  void emul_simple_init(struct emul *emul) Line 1561  void emul_simple_init(struct emul *emul)
1561   */   */
1562  struct emul *emul_create_from_configfile(char *fname)  struct emul *emul_create_from_configfile(char *fname)
1563  {  {
1564          int iadd = 4;          int iadd = DEBUG_INDENTATION;
1565          struct emul *e = emul_new(fname);          struct emul *e = emul_new(fname);
         FILE *f;  
         char buf[128];  
         size_t len;  
1566    
1567          debug("Creating emulation from configfile \"%s\":\n", fname);          debug("Creating emulation from configfile \"%s\":\n", fname);
1568          debug_indentation(iadd);          debug_indentation(iadd);
1569    
1570          f = fopen(fname, "r");          emul_parse_config(e, fname);
         if (f == NULL) {  
                 perror(fname);  
                 exit(1);  
         }  
1571    
         /*  Read header: (must be !!gxemul)  */  
         len = fread(buf, 1, 8, f);  
         if (len != 8 || strncmp(buf, "!!gxemul", 8) != 0) {  
                 fprintf(stderr, "%s: must start with '!!gxemul'\n", fname);  
                 exit(1);  
         }  
   
         /*  Restart from beginning:  */  
         rewind(f);  
   
         emul_parse_config(e, f);  
   
         fclose(f);  
1572          debug_indentation(-iadd);          debug_indentation(-iadd);
1573          return e;          return e;
1574  }  }
# Line 1530  void emul_run(struct emul **emuls, int n Line 1595  void emul_run(struct emul **emuls, int n
1595    
1596          atexit(fix_console);          atexit(fix_console);
1597    
         i = 79;  
         while (i-- > 0)  
                 debug("-");  
         debug("\n\n");  
   
1598          /*  Initialize the interactive debugger:  */          /*  Initialize the interactive debugger:  */
1599          debugger_init(emuls, n_emuls);          debugger_init(emuls, n_emuls);
1600    
1601            /*  Run any additional debugger commands before starting:  */
1602            for (i=0; i<n_emuls; i++) {
1603                    struct emul *emul = emuls[i];
1604                    if (emul->n_debugger_cmds > 0) {
1605                            int j;
1606                            if (i == 0)
1607                                    print_separator();
1608                            for (j = 0; j < emul->n_debugger_cmds; j ++) {
1609                                    debug("> %s\n", emul->debugger_cmds[j]);
1610                                    debugger_execute_cmd(emul->debugger_cmds[j],
1611                                        strlen(emul->debugger_cmds[j]));
1612                            }
1613                    }
1614            }
1615    
1616            print_separator();
1617            debug("\n");
1618    
1619    
1620          /*          /*
1621           *  console_init_main() makes sure that the terminal is in a           *  console_init_main() makes sure that the terminal is in a
1622           *  reasonable state.           *  reasonable state.
# Line 1570  void emul_run(struct emul **emuls, int n Line 1649  void emul_run(struct emul **emuls, int n
1649                  cpu_functioncall_trace(emuls[0]->machines[0]->cpus[0],                  cpu_functioncall_trace(emuls[0]->machines[0]->cpus[0],
1650                      emuls[0]->machines[0]->cpus[0]->pc);                      emuls[0]->machines[0]->cpus[0]->pc);
1651    
1652            /*  Start emulated clocks:  */
1653            timer_start();
1654    
1655          /*          /*
1656           *  MAIN LOOP:           *  MAIN LOOP:
1657           *           *
# Line 1579  void emul_run(struct emul **emuls, int n Line 1661  void emul_run(struct emul **emuls, int n
1661          while (go) {          while (go) {
1662                  go = 0;                  go = 0;
1663    
1664                  x11_check_event(emuls, n_emuls);                  /*  Flush X11 and serial console output every now and then:  */
1665                    if (emuls[0]->machines[0]->ninstrs >
1666                        emuls[0]->machines[0]->ninstrs_flush + (1<<19)) {
1667                            x11_check_event(emuls, n_emuls);
1668                            console_flush();
1669                            emuls[0]->machines[0]->ninstrs_flush =
1670                                emuls[0]->machines[0]->ninstrs;
1671                    }
1672    
1673                    if (emuls[0]->machines[0]->ninstrs >
1674                        emuls[0]->machines[0]->ninstrs_show + (1<<25)) {
1675                            emuls[0]->machines[0]->ninstrs_since_gettimeofday +=
1676                                (emuls[0]->machines[0]->ninstrs -
1677                                 emuls[0]->machines[0]->ninstrs_show);
1678                            cpu_show_cycles(emuls[0]->machines[0], 0);
1679                            emuls[0]->machines[0]->ninstrs_show =
1680                                emuls[0]->machines[0]->ninstrs;
1681                    }
1682    
1683                    if (single_step == ENTER_SINGLE_STEPPING) {
1684                            /*  TODO: Cleanup!  */
1685                            old_instruction_trace =
1686                                emuls[0]->machines[0]->instruction_trace;
1687                            old_quiet_mode = quiet_mode;
1688                            old_show_trace_tree =
1689                                emuls[0]->machines[0]->show_trace_tree;
1690                            emuls[0]->machines[0]->instruction_trace = 1;
1691                            emuls[0]->machines[0]->show_trace_tree = 1;
1692                            quiet_mode = 0;
1693                            single_step = SINGLE_STEPPING;
1694                    }
1695    
1696                    if (single_step == SINGLE_STEPPING)
1697                            debugger();
1698    
1699                  for (i=0; i<n_emuls; i++) {                  for (i=0; i<n_emuls; i++) {
1700                          e = emuls[i];                          e = emuls[i];
                         if (e == NULL)  
                                 continue;  
1701    
1702                          for (j=0; j<e->n_machines; j++) {                          for (j=0; j<e->n_machines; j++) {
1703                                  /*  TODO: cpu_run() is a strange name, since                                  if (e->machines[j]->gdb.port > 0)
1704                                      there can be multiple cpus in a machine  */                                          debugger_gdb_check_incoming(
1705                                  anything = cpu_run(e, e->machines[j]);                                              e->machines[j]);
1706    
1707                                    anything = machine_run(e->machines[j]);
1708                                  if (anything)                                  if (anything)
1709                                          go = 1;                                          go = 1;
1710                          }                          }
1711                  }                  }
1712          }          }
1713    
1714            /*  Stop any running timers:  */
1715            timer_stop();
1716    
1717          /*  Deinitialize all CPUs in all machines in all emulations:  */          /*  Deinitialize all CPUs in all machines in all emulations:  */
1718          for (i=0; i<n_emuls; i++) {          for (i=0; i<n_emuls; i++) {
1719                  e = emuls[i];                  e = emuls[i];
# Line 1612  void emul_run(struct emul **emuls, int n Line 1730  void emul_run(struct emul **emuls, int n
1730                  debugger();                  debugger();
1731          }          }
1732    
1733          /*  Any machine using X11? Then we should wait before exiting:  */          /*  Any machine using X11? Then wait before exiting:  */
1734          n = 0;          n = 0;
1735          for (i=0; i<n_emuls; i++)          for (i=0; i<n_emuls; i++)
1736                  for (j=0; j<emuls[i]->n_machines; j++)                  for (j=0; j<emuls[i]->n_machines; j++)
# Line 1622  void emul_run(struct emul **emuls, int n Line 1740  void emul_run(struct emul **emuls, int n
1740                  printf("Press enter to quit.\n");                  printf("Press enter to quit.\n");
1741                  while (!console_charavail(MAIN_CONSOLE)) {                  while (!console_charavail(MAIN_CONSOLE)) {
1742                          x11_check_event(emuls, n_emuls);                          x11_check_event(emuls, n_emuls);
1743                          usleep(1);                          usleep(10000);
1744                  }                  }
1745                  console_readchar(MAIN_CONSOLE);                  console_readchar(MAIN_CONSOLE);
1746          }          }
1747    
1748          console_deinit();          console_deinit_main();
1749  }  }
1750    

Legend:
Removed from v.18  
changed lines
  Added in v.32

  ViewVC Help
Powered by ViewVC 1.1.26