/[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 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC revision 34 by dpavlin, Mon Oct 8 16:21:17 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2007  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.247 2006/02/04 12:27:12 debug Exp $   *  $Id: emul.c,v 1.278 2007/02/10 14:37:38 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    
60  extern int force_debugger_at_exit;  /*  #define ISO_DEBUG  */
61    
62    
63  extern int extra_argc;  extern int extra_argc;
64  extern char **extra_argv;  extern char **extra_argv;
65    
66  extern int verbose;  extern int verbose;
67  extern int quiet_mode;  extern int quiet_mode;
68    extern int force_debugger_at_exit;
69    extern int single_step;
70    extern int old_show_trace_tree;
71    extern int old_instruction_trace;
72    extern int old_quiet_mode;
73    extern int quiet_mode;
74    
75  extern struct emul *debugger_emul;  extern struct emul *debugger_emul;
76  extern struct diskimage *diskimages[];  extern struct diskimage *diskimages[];
# Line 105  static void add_dump_points(struct machi Line 113  static void add_dump_points(struct machi
113                          uint64_t addr;                          uint64_t addr;
114                          int res = get_symbol_addr(&m->symbol_context,                          int res = get_symbol_addr(&m->symbol_context,
115                              m->breakpoint_string[i], &addr);                              m->breakpoint_string[i], &addr);
116                          if (!res)                          if (!res) {
117                                  fprintf(stderr,                                  fprintf(stderr,
118                                      "WARNING! Breakpoint '%s' could not be"                                      "ERROR! Breakpoint '%s' could not be"
119                                          " parsed\n",                                          " parsed\n",
120                                      m->breakpoint_string[i]);                                      m->breakpoint_string[i]);
121                          else {                          } else {
122                                  dp = addr;                                  dp = addr;
123                                  string_flag = 1;                                  string_flag = 1;
124                          }                          }
# Line 141  static void add_dump_points(struct machi Line 149  static void add_dump_points(struct machi
149   */   */
150  static void fix_console(void)  static void fix_console(void)
151  {  {
152          console_deinit();          console_deinit_main();
153  }  }
154    
155    
# Line 218  static int iso_load_bootblock(struct mac Line 226  static int iso_load_bootblock(struct mac
226          dirofs = (int64_t)(buf[0x8c] + (buf[0x8d] << 8) + (buf[0x8e] << 16) +          dirofs = (int64_t)(buf[0x8c] + (buf[0x8d] << 8) + (buf[0x8e] << 16) +
227              ((uint64_t)buf[0x8f] << 24)) * 2048;              ((uint64_t)buf[0x8f] << 24)) * 2048;
228    
229          /*  debug("root = %i bytes at 0x%llx\n", dirlen, (long long)dirofs);  */  #ifdef ISO_DEBUG
230            debug("root = %i bytes at 0x%llx\n", dirlen, (long long)dirofs);
231    #endif
232    
233          dirbuf = malloc(dirlen);          dirbuf = malloc(dirlen);
234          if (dirbuf == NULL) {          if (dirbuf == NULL) {
# Line 253  static int iso_load_bootblock(struct mac Line 263  static int iso_load_bootblock(struct mac
263                  if (p == NULL)                  if (p == NULL)
264                          p = strchr(filename, '\\');                          p = strchr(filename, '\\');
265    
266                  /*  debug("%i%s: %i, %i, \"", filenr, filenr == found_dir?  #ifdef ISO_DEBUG
267                      " [CURRENT]" : "", x, y);  */                  debug("%i%s: %i, %i, \"", filenr, filenr == found_dir?
268                        " [CURRENT]" : "", x, y);
269    #endif
270                  for (i=0; i<nlen && i<sizeof(direntry)-1; i++)                  for (i=0; i<nlen && i<sizeof(direntry)-1; i++)
271                          if (dp[i]) {                          if (dp[i]) {
272                                  direntry[i] = dp[i];                                  direntry[i] = dp[i];
273                                  /*  debug("%c", dp[i]);  */  #ifdef ISO_DEBUG
274                                    debug("%c", dp[i]);
275    #endif
276                          } else                          } else
277                                  break;                                  break;
278                  /*  debug("\"\n");  */  #ifdef ISO_DEBUG
279                    debug("\"\n");
280    #endif
281                  direntry[i] = '\0';                  direntry[i] = '\0';
282    
283                  /*  A directory name match?  */                  /*  A directory name match?  */
284                  if (p != NULL && strncasecmp(filename, direntry, nlen) == 0                  if ((p != NULL && strncasecmp(filename, direntry, nlen) == 0
285                      && nlen == (size_t)p - (size_t)filename && found_dir == y) {                      && nlen == (size_t)p - (size_t)filename && found_dir == y)
286                        || (p == NULL && direntry[0] == '\0') ) {
287                          found_dir = filenr;                          found_dir = filenr;
288                          filename = p+1;                          if (p != NULL)
289                                    filename = p+1;
290                          dirofs = 2048 * (int64_t)x;                          dirofs = 2048 * (int64_t)x;
291                  }                  }
292    
# Line 527  static int load_bootblock(struct machine Line 545  static int load_bootblock(struct machine
545              iso_type, retval = 0;              iso_type, retval = 0;
546          unsigned char minibuf[0x20];          unsigned char minibuf[0x20];
547          unsigned char *bootblock_buf;          unsigned char *bootblock_buf;
548          uint64_t bootblock_offset;          uint64_t bootblock_offset, base_offset;
549          uint64_t bootblock_loadaddr, bootblock_pc;          uint64_t bootblock_loadaddr, bootblock_pc;
550    
551          boot_disk_id = diskimage_bootdev(m, &boot_disk_type);          boot_disk_id = diskimage_bootdev(m, &boot_disk_type);
552          if (boot_disk_id < 0)          if (boot_disk_id < 0)
553                  return 0;                  return 0;
554    
555            base_offset = diskimage_get_baseoffset(m, boot_disk_id, boot_disk_type);
556    
557          switch (m->machine_type) {          switch (m->machine_type) {
558    
559            case MACHINE_DREAMCAST:
560                    if (!diskimage_is_a_cdrom(cpu->machine, boot_disk_id,
561                        boot_disk_type)) {
562                            fatal("The Dreamcast emulation mode can only boot"
563                                " from CD images, not from other disk types.\n");
564                            exit(1);
565                    }
566    
567                    bootblock_buf = malloc(32768);
568                    if (bootblock_buf == NULL) {
569                            fprintf(stderr, "Out of memory.\n");
570                            exit(1);
571                    }
572    
573                    debug("loading Dreamcast IP.BIN from %s id %i\n",
574                        diskimage_types[boot_disk_type], boot_disk_id);
575    
576                    res = diskimage_access(m, boot_disk_id, boot_disk_type,
577                        0, base_offset, bootblock_buf, 0x8000);
578                    if (!res) {
579                            fatal("Couldn't read the disk image. Aborting.\n");
580                            return 0;
581                    }
582    
583                    if (strncmp((char *)bootblock_buf, "SEGA ", 5) != 0) {
584                            fatal("This is not a Dreamcast IP.BIN header.\n");
585                            free(bootblock_buf);
586                            return 0;
587                    }
588    
589                    /*  Store IP.BIN at 0x8c008000, and set entry point.  */
590                    store_buf(cpu, 0x8c008000, (char *)bootblock_buf, 32768);
591                    cpu->pc = 0x8c008300;
592    
593                    /*  Remember the name of the file to boot (1ST_READ.BIN):  */
594                    if (cpu->machine->boot_kernel_filename == NULL ||
595                        cpu->machine->boot_kernel_filename[0] == '\0') {
596                            int i = 0x60;
597                            while (i < 0x70) {
598                                    if (bootblock_buf[i] == ' ')
599                                            bootblock_buf[i] = 0;
600                                    i ++;
601                            }
602                            cpu->machine->boot_kernel_filename = strdup(
603                                (char *)bootblock_buf + 0x60);
604                    }
605    
606                    debug("boot filename: %s\n",
607                        cpu->machine->boot_kernel_filename);
608    
609                    free(bootblock_buf);
610    
611                    break;
612    
613          case MACHINE_PMAX:          case MACHINE_PMAX:
614                  /*                  /*
615                   *  The first few bytes of a disk contains information about                   *  The first few bytes of a disk contains information about
# Line 560  static int load_bootblock(struct machine Line 635  static int load_bootblock(struct machine
635    
636                  /*  Convert loadaddr to uncached:  */                  /*  Convert loadaddr to uncached:  */
637                  if ((bootblock_loadaddr & 0xf0000000ULL) != 0x80000000 &&                  if ((bootblock_loadaddr & 0xf0000000ULL) != 0x80000000 &&
638                      (bootblock_loadaddr & 0xf0000000ULL) != 0xa0000000)                      (bootblock_loadaddr & 0xf0000000ULL) != 0xa0000000) {
639                          fatal("\nWARNING! Weird load address 0x%08x.\n\n",                          fatal("\nWARNING! Weird load address 0x%08"PRIx32
640                              (int)bootblock_loadaddr);                              " for SCSI id %i.\n\n",
641                                (uint32_t)bootblock_loadaddr, boot_disk_id);
642                            if (bootblock_loadaddr == 0) {
643                                    fatal("I'm assuming that this is _not_ a "
644                                        "DEC bootblock.\nAre you sure you are"
645                                        " booting from the correct disk?\n");
646                                    exit(1);
647                            }
648                    }
649    
650                  bootblock_loadaddr &= 0x0fffffffULL;                  bootblock_loadaddr &= 0x0fffffffULL;
651                  bootblock_loadaddr |= 0xffffffffa0000000ULL;                  bootblock_loadaddr |= 0xffffffffa0000000ULL;
652    
# Line 627  static int load_bootblock(struct machine Line 711  static int load_bootblock(struct machine
711    
712                  debug(readofs == 0x18? ": no blocks?\n" : " blocks\n");                  debug(readofs == 0x18? ": no blocks?\n" : " blocks\n");
713                  return 1;                  return 1;
   
         case MACHINE_X86:  
                 /*  TODO: "El Torito" etc?  */  
                 if (diskimage_is_a_cdrom(cpu->machine, boot_disk_id,  
                     boot_disk_type))  
                         break;  
   
                 bootblock_buf = malloc(512);  
                 if (bootblock_buf == NULL) {  
                         fprintf(stderr, "Out of memory.\n");  
                         exit(1);  
                 }  
   
                 debug("loading PC bootsector from %s id %i\n",  
                     diskimage_types[boot_disk_type], boot_disk_id);  
   
                 res = diskimage_access(m, boot_disk_id, boot_disk_type, 0, 0,  
                     bootblock_buf, 512);  
                 if (!res) {  
                         fatal("Couldn't read the disk image. Aborting.\n");  
                         return 0;  
                 }  
   
                 if (bootblock_buf[510] != 0x55 || bootblock_buf[511] != 0xaa)  
                         debug("WARNING! The 0x55,0xAA marker is missing! "  
                             "Booting anyway.\n");  
                 store_buf(cpu, 0x7c00, (char *)bootblock_buf, 512);  
                 free(bootblock_buf);  
   
                 return 1;  
714          }          }
715    
716    
# Line 664  static int load_bootblock(struct machine Line 718  static int load_bootblock(struct machine
718           *  Try reading a kernel manually from the disk. The code here           *  Try reading a kernel manually from the disk. The code here
719           *  does not rely on machine-dependent boot blocks etc.           *  does not rely on machine-dependent boot blocks etc.
720           */           */
721          /*  ISO9660: (0x800 bytes at 0x8000)  */          /*  ISO9660: (0x800 bytes at 0x8000 + base_offset)  */
722          bootblock_buf = malloc(0x800);          bootblock_buf = malloc(0x800);
723          if (bootblock_buf == NULL) {          if (bootblock_buf == NULL) {
724                  fprintf(stderr, "Out of memory.\n");                  fprintf(stderr, "Out of memory.\n");
# Line 672  static int load_bootblock(struct machine Line 726  static int load_bootblock(struct machine
726          }          }
727    
728          res = diskimage_access(m, boot_disk_id, boot_disk_type,          res = diskimage_access(m, boot_disk_id, boot_disk_type,
729              0, 0x8000, bootblock_buf, 0x800);              0, base_offset + 0x8000, bootblock_buf, 0x800);
730          if (!res) {          if (!res) {
731                  fatal("Couldn't read the disk image. Aborting.\n");                  fatal("Couldn't read the disk image. Aborting.\n");
732                  return 0;                  return 0;
# Line 687  static int load_bootblock(struct machine Line 741  static int load_bootblock(struct machine
741                  iso_type = 3;                  iso_type = 3;
742    
743          if (iso_type != 0) {          if (iso_type != 0) {
744                  /*  We can't load a kernel if the name                  /*
745                      isn't specified.  */                   *  If the user specified a kernel name, then load it from
746                     *  disk.
747                     */
748                  if (cpu->machine->boot_kernel_filename == NULL ||                  if (cpu->machine->boot_kernel_filename == NULL ||
749                      cpu->machine->boot_kernel_filename[0] == '\0')                      cpu->machine->boot_kernel_filename[0] == '\0')
750                          fatal("\nISO9660 filesystem, but no kernel "                          fatal("\nISO9660 filesystem, but no kernel "
# Line 711  static int load_bootblock(struct machine Line 767  static int load_bootblock(struct machine
767          }          }
768          if (bootblock_buf[0x000] == 'E' && bootblock_buf[0x001] == 'R' &&          if (bootblock_buf[0x000] == 'E' && bootblock_buf[0x001] == 'R' &&
769              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.  */  
770                  if (cpu->machine->boot_kernel_filename == NULL ||                  if (cpu->machine->boot_kernel_filename == NULL ||
771                      cpu->machine->boot_kernel_filename[0] == '\0')                      cpu->machine->boot_kernel_filename[0] == '\0')
772                          fatal("\nApple partition table, but no kernel "                          fatal("\nApple partition table, but no kernel "
# Line 733  ret_ok: Line 787  ret_ok:
787   *   *
788   *  Returns a reasonably initialized struct emul.   *  Returns a reasonably initialized struct emul.
789   */   */
790  struct emul *emul_new(char *name)  struct emul *emul_new(char *name, int id)
791  {  {
792          struct emul *e;          struct emul *e;
793          e = malloc(sizeof(struct emul));          e = malloc(sizeof(struct emul));
# Line 744  struct emul *emul_new(char *name) Line 798  struct emul *emul_new(char *name)
798    
799          memset(e, 0, sizeof(struct emul));          memset(e, 0, sizeof(struct emul));
800    
801            e->path = malloc(15);
802            if (e->path == NULL) {
803                    fprintf(stderr, "out of memory\n");
804                    exit(1);
805            }
806            snprintf(e->path, 15, "emul[%i]", id);
807    
808            e->settings = settings_new();
809    
810            settings_add(e->settings, "n_machines", 0,
811                SETTINGS_TYPE_INT, SETTINGS_FORMAT_DECIMAL,
812                (void *) &e->n_machines);
813    
814            /*  TODO: More settings?  */
815    
816          /*  Sane default values:  */          /*  Sane default values:  */
817          e->n_machines = 0;          e->n_machines = 0;
818          e->next_serial_nr = 1;          e->next_serial_nr = 1;
# Line 754  struct emul *emul_new(char *name) Line 823  struct emul *emul_new(char *name)
823                          fprintf(stderr, "out of memory in emul_new()\n");                          fprintf(stderr, "out of memory in emul_new()\n");
824                          exit(1);                          exit(1);
825                  }                  }
826    
827                    settings_add(e->settings, "name", 0,
828                        SETTINGS_TYPE_STRING, SETTINGS_FORMAT_STRING,
829                        (void *) &e->name);
830          }          }
831    
832          return e;          return e;
# Line 761  struct emul *emul_new(char *name) Line 834  struct emul *emul_new(char *name)
834    
835    
836  /*  /*
837     *  emul_destroy():
838     *
839     *  Destroys a previously created emul object.
840     */
841    void emul_destroy(struct emul *emul)
842    {
843            int i;
844    
845            if (emul->name != NULL) {
846                    settings_remove(emul->settings, "name");
847                    free(emul->name);
848            }
849    
850            for (i=0; i<emul->n_machines; i++)
851                    machine_destroy(emul->machines[i]);
852    
853            if (emul->machines != NULL)
854                    free(emul->machines);
855    
856            /*  Remove any remaining level-1 settings:  */
857            settings_remove_all(emul->settings);
858            settings_destroy(emul->settings);
859    
860            free(emul);
861    }
862    
863    
864    /*
865   *  emul_add_machine():   *  emul_add_machine():
866   *   *
867   *  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 771  struct emul *emul_new(char *name) Line 872  struct emul *emul_new(char *name)
872  struct machine *emul_add_machine(struct emul *e, char *name)  struct machine *emul_add_machine(struct emul *e, char *name)
873  {  {
874          struct machine *m;          struct machine *m;
875            char tmpstr[20];
876            int i;
877    
878          m = machine_new(name, e);          m = machine_new(name, e, e->n_machines);
879          m->serial_nr = (e->next_serial_nr ++);          m->serial_nr = (e->next_serial_nr ++);
880    
881            i = e->n_machines;
882    
883          e->n_machines ++;          e->n_machines ++;
884          e->machines = realloc(e->machines,          e->machines = realloc(e->machines,
885              sizeof(struct machine *) * e->n_machines);              sizeof(struct machine *) * e->n_machines);
# Line 783  struct machine *emul_add_machine(struct Line 888  struct machine *emul_add_machine(struct
888                  exit(1);                  exit(1);
889          }          }
890    
891          e->machines[e->n_machines - 1] = m;          e->machines[i] = m;
892    
893            snprintf(tmpstr, sizeof(tmpstr), "machine[%i]", i);
894            settings_add(e->settings, tmpstr, 1, SETTINGS_TYPE_SUBSETTINGS, 0,
895                e->machines[i]->settings);
896    
897          return m;          return m;
898  }  }
899    
# Line 940  void emul_machine_setup(struct machine * Line 1050  void emul_machine_setup(struct machine *
1050          if (m->arch == ARCH_ALPHA)          if (m->arch == ARCH_ALPHA)
1051                  m->arch_pagesize = 8192;                  m->arch_pagesize = 8192;
1052    
         if (m->arch != ARCH_MIPS)  
                 m->bintrans_enable = 0;  
   
1053          machine_memsize_fix(m);          machine_memsize_fix(m);
1054    
1055          /*          /*
# Line 990  void emul_machine_setup(struct machine * Line 1097  void emul_machine_setup(struct machine *
1097          }          }
1098          memset(m->cpus, 0, sizeof(struct cpu *) * m->ncpus);          memset(m->cpus, 0, sizeof(struct cpu *) * m->ncpus);
1099    
         /*  Initialize dynamic binary translation, if available:  */  
         if (m->bintrans_enable)  
                 bintrans_init(m, m->memory);  
   
1100          debug("cpu0");          debug("cpu0");
1101          if (m->ncpus > 1)          if (m->ncpus > 1)
1102                  debug(" .. cpu%i", m->ncpus - 1);                  debug(" .. cpu%i", m->ncpus - 1);
1103          debug(": ");          debug(": ");
1104          for (i=0; i<m->ncpus; i++) {          for (i=0; i<m->ncpus; i++) {
1105                  m->cpus[i] = cpu_new(m->memory, m, i, m->cpu_name);                  m->cpus[i] = cpu_new(m->memory, m, i, m->cpu_name);
1106                  if (m->bintrans_enable)                  if (m->cpus[i] == NULL) {
1107                          bintrans_init_cpu(m->cpus[i]);                          fprintf(stderr, "Unable to create CPU object. "
1108                                "Aborting.");
1109                            exit(1);
1110                    }
1111          }          }
1112          debug("\n");          debug("\n");
1113    
# Line 1012  void emul_machine_setup(struct machine * Line 1118  void emul_machine_setup(struct machine *
1118                  m->cpus[m->ncpus] = cpu_new(m->memory, m,                  m->cpus[m->ncpus] = cpu_new(m->memory, m,
1119                      0  /*  use 0 here to show info with debug()  */,                      0  /*  use 0 here to show info with debug()  */,
1120                      "Allegrex" /*  TODO  */);                      "Allegrex" /*  TODO  */);
                 if (m->bintrans_enable)  
                         bintrans_init_cpu(m->cpus[m->ncpus]);  
1121                  debug("\n");                  debug("\n");
1122                  m->ncpus ++;                  m->ncpus ++;
1123          }          }
# Line 1185  void emul_machine_setup(struct machine * Line 1289  void emul_machine_setup(struct machine *
1289                          }                          }
1290                  }                  }
1291    
                 /*  Special things required _before_ loading the file:  */  
                 switch (m->arch) {  
                 case ARCH_X86:  
                         /*  
                          *  X86 machines normally don't need to load any files,  
                          *  they can boot from disk directly. Therefore, an x86  
                          *  machine usually boots up in 16-bit real mode. When  
                          *  loading a 32-bit (or even 64-bit) ELF, that's not  
                          *  very nice, hence this special case.  
                          */  
                         pc_bios_simple_pmode_setup(cpu);  
                         break;  
                 }  
   
1292                  byte_order = NO_BYTE_ORDER_OVERRIDE;                  byte_order = NO_BYTE_ORDER_OVERRIDE;
1293    
1294                  /*                  /*
# Line 1240  void emul_machine_setup(struct machine * Line 1330  void emul_machine_setup(struct machine *
1330                          }                          }
1331                          break;                          break;
1332    
1333                  case ARCH_HPPA:                  case ARCH_RCA180X:
1334                          break;                          cpu->pc &= 0xffff;
   
                 case ARCH_I960:  
                         break;  
   
                 case ARCH_IA64:  
1335                          break;                          break;
1336    
1337                  case ARCH_M68K:                  case ARCH_M68K:
# Line 1274  void emul_machine_setup(struct machine * Line 1359  void emul_machine_setup(struct machine *
1359                          break;                          break;
1360    
1361                  case ARCH_SH:                  case ARCH_SH:
1362                          if (cpu->cd.sh.bits == 32)                          if (cpu->cd.sh.cpu_type.bits == 32)
1363                                  cpu->pc &= 0xffffffffULL;                                  cpu->pc &= 0xffffffffULL;
1364                          cpu->pc &= ~1;                          cpu->pc &= ~1;
1365                          break;                          break;
# Line 1282  void emul_machine_setup(struct machine * Line 1367  void emul_machine_setup(struct machine *
1367                  case ARCH_SPARC:                  case ARCH_SPARC:
1368                          break;                          break;
1369    
1370                  case ARCH_X86:                  case ARCH_TRANSPUTER:
1371                          /*                          cpu->pc &= 0xffffffffULL;
                          *  NOTE: The toc field is used to indicate an ELF32  
                          *  or ELF64 load.  
                          */  
                         switch (toc) {  
                         case 0: /*  16-bit? TODO  */  
                                 cpu->pc &= 0xffffffffULL;  
                                 break;  
                         case 1: /*  32-bit.  */  
                                 cpu->pc &= 0xffffffffULL;  
                                 break;  
                         case 2: /*  64-bit:  TODO  */  
                                 fatal("64-bit x86 load. TODO\n");  
                                 exit(1);  
                         }  
1372                          break;                          break;
1373    
1374                  default:                  default:
# Line 1335  void emul_machine_setup(struct machine * Line 1406  void emul_machine_setup(struct machine *
1406                  useremul_setup(cpu, n_load, load_names);                  useremul_setup(cpu, n_load, load_names);
1407    
1408          /*  Startup the bootstrap CPU:  */          /*  Startup the bootstrap CPU:  */
1409          cpu->bootstrap_cpu_flag = 1;          cpu->running = 1;
         cpu->running            = 1;  
1410    
1411          /*  ... or pause all CPUs, if start_paused is set:  */          /*  ... or pause all CPUs, if start_paused is set:  */
1412          if (m->start_paused) {          if (m->start_paused) {
# Line 1355  void emul_machine_setup(struct machine * Line 1425  void emul_machine_setup(struct machine *
1425    
1426          symbol_recalc_sizes(&m->symbol_context);          symbol_recalc_sizes(&m->symbol_context);
1427    
         if (m->max_random_cycles_per_chunk > 0)  
                 debug("using random cycle chunks (1 to %i cycles)\n",  
                     m->max_random_cycles_per_chunk);  
   
1428          /*  Special hack for ARC/SGI emulation:  */          /*  Special hack for ARC/SGI emulation:  */
1429          if ((m->machine_type == MACHINE_ARC ||          if ((m->machine_type == MACHINE_ARC ||
1430              m->machine_type == MACHINE_SGI) && m->prom_emulation)              m->machine_type == MACHINE_SGI) && m->prom_emulation)
# Line 1401  void emul_machine_setup(struct machine * Line 1467  void emul_machine_setup(struct machine *
1467                          debug("0x%016llx", (long long)entrypoint);                          debug("0x%016llx", (long long)entrypoint);
1468                  break;                  break;
1469    
         case ARCH_X86:  
                 debug("0x%04x:0x%llx", cpu->cd.x86.s[X86_S_CS],  
                     (long long)cpu->pc);  
                 break;  
   
1470          default:          default:
1471                  if (cpu->is_32bit)                  if (cpu->is_32bit)
1472                          debug("0x%08x", (int)cpu->pc);                          debug("0x%08x", (int)cpu->pc);
# Line 1470  void emul_simple_init(struct emul *emul) Line 1531  void emul_simple_init(struct emul *emul)
1531    
1532                  /*  Create a simple network:  */                  /*  Create a simple network:  */
1533                  emul->net = net_init(emul, NET_INIT_FLAG_GATEWAY,                  emul->net = net_init(emul, NET_INIT_FLAG_GATEWAY,
1534                      "10.0.0.0", 8, NULL, 0, 0);                      NET_DEFAULT_IPV4_MASK,
1535                        NET_DEFAULT_IPV4_LEN,
1536                        NULL, 0, 0, NULL);
1537          } else {          } else {
1538                  /*  Userland pseudo-machine:  */                  /*  Userland pseudo-machine:  */
1539                  debug("Syscall emulation (userland-only) setup...\n");                  debug("Syscall emulation (userland-only) setup...\n");
# Line 1489  void emul_simple_init(struct emul *emul) Line 1552  void emul_simple_init(struct emul *emul)
1552   *   *
1553   *  Create an emul struct by reading settings from a configuration file.   *  Create an emul struct by reading settings from a configuration file.
1554   */   */
1555  struct emul *emul_create_from_configfile(char *fname)  struct emul *emul_create_from_configfile(char *fname, int id)
1556  {  {
1557          int iadd = DEBUG_INDENTATION;          int iadd = DEBUG_INDENTATION;
1558          struct emul *e = emul_new(fname);          struct emul *e = emul_new(fname, id);
         FILE *f;  
         char buf[128];  
         size_t len;  
1559    
1560          debug("Creating emulation from configfile \"%s\":\n", fname);          debug("Creating emulation from configfile \"%s\":\n", fname);
1561          debug_indentation(iadd);          debug_indentation(iadd);
1562    
1563          f = fopen(fname, "r");          emul_parse_config(e, fname);
         if (f == NULL) {  
                 perror(fname);  
                 exit(1);  
         }  
   
         /*  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);  
1564    
         fclose(f);  
1565          debug_indentation(-iadd);          debug_indentation(-iadd);
1566          return e;          return e;
1567  }  }
# Line 1599  void emul_run(struct emul **emuls, int n Line 1642  void emul_run(struct emul **emuls, int n
1642                  cpu_functioncall_trace(emuls[0]->machines[0]->cpus[0],                  cpu_functioncall_trace(emuls[0]->machines[0]->cpus[0],
1643                      emuls[0]->machines[0]->cpus[0]->pc);                      emuls[0]->machines[0]->cpus[0]->pc);
1644    
1645            /*  Start emulated clocks:  */
1646            timer_start();
1647    
1648          /*          /*
1649           *  MAIN LOOP:           *  MAIN LOOP:
1650           *           *
# Line 1608  void emul_run(struct emul **emuls, int n Line 1654  void emul_run(struct emul **emuls, int n
1654          while (go) {          while (go) {
1655                  go = 0;                  go = 0;
1656    
1657                  x11_check_event(emuls, n_emuls);                  /*  Flush X11 and serial console output every now and then:  */
1658                    if (emuls[0]->machines[0]->ninstrs >
1659                        emuls[0]->machines[0]->ninstrs_flush + (1<<19)) {
1660                            x11_check_event(emuls, n_emuls);
1661                            console_flush();
1662                            emuls[0]->machines[0]->ninstrs_flush =
1663                                emuls[0]->machines[0]->ninstrs;
1664                    }
1665    
1666                    if (emuls[0]->machines[0]->ninstrs >
1667                        emuls[0]->machines[0]->ninstrs_show + (1<<25)) {
1668                            emuls[0]->machines[0]->ninstrs_since_gettimeofday +=
1669                                (emuls[0]->machines[0]->ninstrs -
1670                                 emuls[0]->machines[0]->ninstrs_show);
1671                            cpu_show_cycles(emuls[0]->machines[0], 0);
1672                            emuls[0]->machines[0]->ninstrs_show =
1673                                emuls[0]->machines[0]->ninstrs;
1674                    }
1675    
1676                    if (single_step == ENTER_SINGLE_STEPPING) {
1677                            /*  TODO: Cleanup!  */
1678                            old_instruction_trace =
1679                                emuls[0]->machines[0]->instruction_trace;
1680                            old_quiet_mode = quiet_mode;
1681                            old_show_trace_tree =
1682                                emuls[0]->machines[0]->show_trace_tree;
1683                            emuls[0]->machines[0]->instruction_trace = 1;
1684                            emuls[0]->machines[0]->show_trace_tree = 1;
1685                            quiet_mode = 0;
1686                            single_step = SINGLE_STEPPING;
1687                    }
1688    
1689                    if (single_step == SINGLE_STEPPING)
1690                            debugger();
1691    
1692                  for (i=0; i<n_emuls; i++) {                  for (i=0; i<n_emuls; i++) {
1693                          e = emuls[i];                          e = emuls[i];
                         if (e == NULL)  
                                 continue;  
1694    
1695                          for (j=0; j<e->n_machines; j++) {                          for (j=0; j<e->n_machines; j++) {
1696                                  /*  TODO: cpu_run() is a strange name, since                                  if (e->machines[j]->gdb.port > 0)
1697                                      there can be multiple cpus in a machine  */                                          debugger_gdb_check_incoming(
1698                                  anything = cpu_run(e, e->machines[j]);                                              e->machines[j]);
1699    
1700                                    anything = machine_run(e->machines[j]);
1701                                  if (anything)                                  if (anything)
1702                                          go = 1;                                          go = 1;
1703                          }                          }
1704                  }                  }
1705          }          }
1706    
1707            /*  Stop any running timers:  */
1708            timer_stop();
1709    
1710          /*  Deinitialize all CPUs in all machines in all emulations:  */          /*  Deinitialize all CPUs in all machines in all emulations:  */
1711          for (i=0; i<n_emuls; i++) {          for (i=0; i<n_emuls; i++) {
1712                  e = emuls[i];                  e = emuls[i];
# Line 1641  void emul_run(struct emul **emuls, int n Line 1723  void emul_run(struct emul **emuls, int n
1723                  debugger();                  debugger();
1724          }          }
1725    
1726          /*  Any machine using X11? Then we should wait before exiting:  */          /*  Any machine using X11? Then wait before exiting:  */
1727          n = 0;          n = 0;
1728          for (i=0; i<n_emuls; i++)          for (i=0; i<n_emuls; i++)
1729                  for (j=0; j<emuls[i]->n_machines; j++)                  for (j=0; j<emuls[i]->n_machines; j++)
# Line 1651  void emul_run(struct emul **emuls, int n Line 1733  void emul_run(struct emul **emuls, int n
1733                  printf("Press enter to quit.\n");                  printf("Press enter to quit.\n");
1734                  while (!console_charavail(MAIN_CONSOLE)) {                  while (!console_charavail(MAIN_CONSOLE)) {
1735                          x11_check_event(emuls, n_emuls);                          x11_check_event(emuls, n_emuls);
1736                          usleep(1);                          usleep(10000);
1737                  }                  }
1738                  console_readchar(MAIN_CONSOLE);                  console_readchar(MAIN_CONSOLE);
1739          }          }
1740    
1741          console_deinit();          console_deinit_main();
1742  }  }
1743    

Legend:
Removed from v.22  
changed lines
  Added in v.34

  ViewVC Help
Powered by ViewVC 1.1.26