/[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 2 by dpavlin, Mon Oct 8 16:17:48 2007 UTC revision 6 by dpavlin, Mon Oct 8 16:18:11 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: emul.c,v 1.179 2005/03/14 19:14:04 debug Exp $   *  $Id: emul.c,v 1.203 2005/06/03 07:39:27 debug Exp $
29   *   *
30   *  Emulation startup and misc. routines.   *  Emulation startup and misc. routines.
31   */   */
# Line 41  Line 41 
41  #include "arcbios.h"  #include "arcbios.h"
42  #include "bintrans.h"  #include "bintrans.h"
43  #include "cpu.h"  #include "cpu.h"
 #include "cpu_mips.h"  
44  #include "emul.h"  #include "emul.h"
45  #include "console.h"  #include "console.h"
46  #include "debugger.h"  #include "debugger.h"
# Line 67  extern int quiet_mode; Line 66  extern int quiet_mode;
66  extern struct emul *debugger_emul;  extern struct emul *debugger_emul;
67  extern struct diskimage *diskimages[];  extern struct diskimage *diskimages[];
68    
69    static char *diskimage_types[] = DISKIMAGE_TYPES;
70    
71    
72  /*  /*
73   *  add_dump_points():   *  add_dump_points():
# Line 132  static void fix_console(void) Line 133  static void fix_console(void)
133    
134    
135  /*  /*
136     *  iso_load_bootblock():
137     *
138     *  Try to load a kernel from an ISO 9660 disk image. iso_type is 1 for
139     *  "CD001" (standard), 2 for "CDW01" (ECMA), and 3 for "CDROM" (Sierra).
140     *
141     *  TODO: This function uses too many magic offsets and so on; it should be
142     *  cleaned up some day.
143     *
144     *  Returns 1 on success, 0 on failure.
145     */
146    static int iso_load_bootblock(struct machine *m, struct cpu *cpu,
147            int disk_id, int disk_type, int iso_type, unsigned char *buf,
148            int *n_loadp, char ***load_namesp)
149    {
150            char str[35];
151            int filenr, i, ofs, dirlen, res = 0, res2, iadd = 4;
152            int found_dir;
153            uint64_t dirofs;
154            uint64_t fileofs, filelen;
155            unsigned char *dirbuf = NULL, *dp;
156            unsigned char *match_entry = NULL;
157            char *p, *filename_orig;
158            char *filename = strdup(cpu->machine->boot_kernel_filename);
159            unsigned char *filebuf = NULL;
160            char *tmpfilename = NULL;
161            char **new_array;
162            int tmpfile_handle;
163    
164            if (filename == NULL) {
165                    fatal("out of memory\n");
166                    exit(1);
167            }
168            filename_orig = filename;
169    
170            debug("ISO9660 boot:\n");
171            debug_indentation(iadd);
172    
173            /*  Volume ID:  */
174            ofs = iso_type == 3? 48 : 40;
175            memcpy(str, buf + ofs, sizeof(str));
176            str[32] = '\0';  i = 31;
177            while (i >= 0 && str[i]==' ')
178                    str[i--] = '\0';
179            if (str[0])
180                    debug("\"%s\"", str);
181            else {
182                    /*  System ID:  */
183                    ofs = iso_type == 3? 16 : 8;
184                    memcpy(str, buf + ofs, sizeof(str));
185                    str[32] = '\0';  i = 31;
186                    while (i >= 0 && str[i]==' ')
187                            str[i--] = '\0';
188                    if (str[0])
189                            debug("\"%s\"", str);
190                    else
191                            debug("(no ID)");
192            }
193    
194            debug(":%s\n", filename);
195    
196    
197            /*
198             *  Traverse the directory structure to find the kernel.
199             */
200    
201            dirlen = buf[0x84] + 256*buf[0x85] + 65536*buf[0x86];
202            if (dirlen != buf[0x8b] + 256*buf[0x8a] + 65536*buf[0x89])
203                    fatal("WARNING: Root directory length mismatch?\n");
204    
205            dirofs = (int64_t)(buf[0x8c] + (buf[0x8d] << 8) + (buf[0x8e] << 16) +
206                (buf[0x8f] << 24)) * 2048;
207    
208            /*  debug("root = %i bytes at 0x%llx\n", dirlen, (long long)dirofs);  */
209    
210            dirbuf = malloc(dirlen);
211            if (dirbuf == NULL) {
212                    fatal("out of memory in iso_load_bootblock()\n");
213                    exit(1);
214            }
215    
216            res2 = diskimage_access(m, disk_id, disk_type, 0, dirofs, dirbuf,
217                dirlen);
218            if (!res2) {
219                    fatal("Couldn't read the disk image. Aborting.\n");
220                    goto ret;
221            }
222    
223            found_dir = 1;  /*  Assume root dir  */
224            dp = dirbuf; filenr = 1;
225            p = NULL;
226            while (dp < dirbuf + dirlen) {
227                    int i, nlen = dp[0];
228                    int x = dp[2] + (dp[3] << 8) + (dp[4] << 16) + (dp[5] << 24);
229                    int y = dp[6] + (dp[7] << 8);
230                    char direntry[65];
231    
232                    dp += 8;
233    
234                    /*
235                     *  As long as there is an \ or / in the filename, then we
236                     *  have not yet found the directory.
237                     */
238                    p = strchr(filename, '/');
239                    if (p == NULL)
240                            p = strchr(filename, '\\');
241    
242                    /*  debug("%i%s: %i, %i, \"", filenr, filenr == found_dir?
243                        " [CURRENT]" : "", x, y);  */
244                    for (i=0; i<nlen && i<sizeof(direntry)-1; i++)
245                            if (dp[i]) {
246                                    direntry[i] = dp[i];
247                                    /*  debug("%c", dp[i]);  */
248                            } else
249                                    break;
250                    /*  debug("\"\n");  */
251                    direntry[i] = '\0';
252    
253                    /*  A directory name match?  */
254                    if (p != NULL && strncasecmp(filename, direntry, nlen) == 0
255                        && nlen == (size_t)p - (size_t)filename && found_dir == y) {
256                            found_dir = filenr;
257                            filename = p+1;
258                            dirofs = 2048 * (int64_t)x;
259                    }
260    
261                    dp += nlen;
262    
263                    /*  16-bit aligned lenght:  */
264                    if (nlen & 1)
265                            dp ++;
266    
267                    filenr ++;
268            }
269    
270            p = strchr(filename, '/');
271            if (p == NULL)
272                    p = strchr(filename, '\\');
273    
274            if (p != NULL) {
275                    char *blah = filename_orig;
276    
277                    fatal("could not find '%s' in /", filename);
278    
279                    /*  Print the first part of the filename:  */
280                    while (blah != filename)
281                            fatal("%c", *blah++);
282                    
283                    fatal("\n");
284                    goto ret;
285            }
286    
287            /*  debug("dirofs = 0x%llx\n", (long long)dirofs);  */
288    
289            /*  Free the old dirbuf, and allocate a new one:  */
290            free(dirbuf);
291            dirbuf = malloc(512);
292            if (dirbuf == NULL) {
293                    fatal("out of memory in iso_load_bootblock()\n");
294                    exit(1);
295            }
296    
297            for (;;) {
298                    int len, i;
299    
300                    /*  Too close to another sector? Then realign.  */
301                    if ((dirofs & 2047) + 70 > 2047) {
302                            dirofs = (dirofs | 2047) + 1;
303                            /*  debug("realign dirofs = 0x%llx\n", dirofs);  */
304                    }
305    
306                    res2 = diskimage_access(m, disk_id, disk_type, 0, dirofs,
307                        dirbuf, 256);
308                    if (!res2) {
309                            fatal("Couldn't read the disk image. Aborting.\n");
310                            goto ret;
311                    }
312    
313                    dp = dirbuf;
314                    len = dp[0];
315                    if (len < 2)
316                            break;
317    
318                    /*
319                     *  TODO: Actually parse the directory entry!
320                     *
321                     *  Haha, this must be rewritten.
322                     */
323                    for (i=32; i<len; i++) {
324                            if (i < len - strlen(filename))
325                                    if (strncasecmp(filename, (char *)dp + i,
326                                        strlen(filename)) == 0) {
327                                            /*  The filename was found somewhere
328                                                in the directory entry.  */
329                                            if (match_entry != NULL) {
330                                                    fatal("TODO: I'm too lazy to"
331                                                        " implement a correct "
332                                                        "directory parser right "
333                                                        "now... (BUG)\n");
334                                                    exit(1);
335                                            }
336                                            match_entry = malloc(512);
337                                            if (match_entry == NULL) {
338                                                    fatal("out of memory\n");
339                                                    exit(1);
340                                            }
341                                            memcpy(match_entry, dp, 512);
342                                            break;
343                                    }
344                    }
345    
346                    dirofs += len;
347            }
348    
349            if (match_entry == NULL) {
350                    char *blah = filename_orig;
351    
352                    fatal("could not find '%s' in /", filename);
353    
354                    /*  Print the first part of the filename:  */
355                    while (blah != filename)
356                            fatal("%c", *blah++);
357                    
358                    fatal("\n");
359                    goto ret;
360            }
361    
362            fileofs = match_entry[2] + (match_entry[3] << 8) +
363                (match_entry[4] << 16) + (match_entry[5] << 24);
364            filelen = match_entry[10] + (match_entry[11] << 8) +
365                (match_entry[12] << 16) + (match_entry[13] << 24);
366            fileofs *= 2048;
367    
368            /*  debug("filelen=%llx fileofs=%llx\n", (long long)filelen,
369                (long long)fileofs);  */
370    
371            filebuf = malloc(filelen);
372            if (filebuf == NULL) {
373                    fatal("could not allocate %lli bytes to read the file"
374                        " from the disk image!\n", (long long)filelen);
375                    goto ret;
376            }
377    
378            tmpfilename = strdup("/tmp/gxemul.XXXXXXXXXXXX");
379    
380            debug("extracting %lli bytes into %s\n",
381                (long long)filelen, tmpfilename);
382    
383            res2 = diskimage_access(m, disk_id, disk_type, 0, fileofs, filebuf,
384                filelen);
385            if (!res2) {
386                    fatal("could not read the file from the disk image!\n");
387                    goto ret;
388            }
389    
390            tmpfile_handle = mkstemp(tmpfilename);
391            if (tmpfile_handle < 0) {
392                    fatal("could not create %s\n", tmpfilename);
393                    exit(1);
394            }
395            write(tmpfile_handle, filebuf, filelen);
396            close(tmpfile_handle);
397    
398            /*  Add the temporary filename to the load_namesp array:  */
399            (*n_loadp)++;
400            new_array = malloc(sizeof(char *) * (*n_loadp));
401            if (new_array == NULL) {
402                    fatal("out of memory\n");
403                    exit(1);
404            }
405            memcpy(new_array, *load_namesp, sizeof(char *) * (*n_loadp));
406            *load_namesp = new_array;
407    
408            /*  This adds a Backspace char in front of the filename; this
409                is a special hack which causes the file to be removed once
410                it has been loaded.  */
411            tmpfilename = realloc(tmpfilename, strlen(tmpfilename) + 2);
412            memmove(tmpfilename + 1, tmpfilename, strlen(tmpfilename) + 1);
413            tmpfilename[0] = 8;
414    
415            (*load_namesp)[*n_loadp - 1] = tmpfilename;
416    
417            res = 1;
418    
419    ret:
420            if (dirbuf != NULL)
421                    free(dirbuf);
422    
423            if (filebuf != NULL)
424                    free(filebuf);
425    
426            if (match_entry != NULL)
427                    free(match_entry);
428    
429            free(filename_orig);
430    
431            debug_indentation(-iadd);
432            return res;
433    }
434    
435    
436    /*
437   *  load_bootblock():   *  load_bootblock():
438   *   *
439   *  For some emulation modes, it is possible to boot from a harddisk image by   *  For some emulation modes, it is possible to boot from a harddisk image by
440   *  loading a bootblock from a specific disk offset into memory, and executing   *  loading a bootblock from a specific disk offset into memory, and executing
441   *  that, instead of requiring a separate kernel file.  It is then up to the   *  that, instead of requiring a separate kernel file.  It is then up to the
442   *  bootblock to load a kernel.   *  bootblock to load a kernel.
443     *
444     *  Returns 1 on success, 0 on failure.
445   */   */
446  static void load_bootblock(struct machine *m, struct cpu *cpu)  static int load_bootblock(struct machine *m, struct cpu *cpu,
447            int *n_loadp, char ***load_namesp)
448  {  {
449          int boot_disk_id;          int boot_disk_id, boot_disk_type = 0, n_blocks, res, readofs,
450                iso_type, retval = 0;
451          unsigned char minibuf[0x20];          unsigned char minibuf[0x20];
452          unsigned char *bootblock_buf;          unsigned char *bootblock_buf;
453          uint64_t bootblock_offset;          uint64_t bootblock_offset;
454          uint64_t bootblock_loadaddr, bootblock_pc;          uint64_t bootblock_loadaddr, bootblock_pc;
         int n_blocks, res, readofs;  
455    
456          boot_disk_id = diskimage_bootdev(m);          boot_disk_id = diskimage_bootdev(m, &boot_disk_type);
457          if (boot_disk_id < 0)          if (boot_disk_id < 0)
458                  return;                  return 0;
459    
460          switch (m->machine_type) {          switch (m->machine_type) {
461          case MACHINE_DEC:          case MACHINE_DEC:
# Line 170  static void load_bootblock(struct machin Line 475  static void load_bootblock(struct machin
475                   *  nr of blocks to read and offset are repeated until nr of                   *  nr of blocks to read and offset are repeated until nr of
476                   *  blocks to read is zero.                   *  blocks to read is zero.
477                   */                   */
478                  res = diskimage_access(m, boot_disk_id, 0, 0,                  res = diskimage_access(m, boot_disk_id, boot_disk_type, 0, 0,
479                      minibuf, sizeof(minibuf));                      minibuf, sizeof(minibuf));
480    
481                  bootblock_loadaddr = minibuf[0x10] + (minibuf[0x11] << 8)                  bootblock_loadaddr = minibuf[0x10] + (minibuf[0x11] << 8)
# Line 197  static void load_bootblock(struct machin Line 502  static void load_bootblock(struct machin
502                  readofs = 0x18;                  readofs = 0x18;
503    
504                  for (;;) {                  for (;;) {
505                          res = diskimage_access(m, boot_disk_id, 0, readofs,                          res = diskimage_access(m, boot_disk_id, boot_disk_type,
506                              minibuf, sizeof(minibuf));                              0, readofs, minibuf, sizeof(minibuf));
507                          if (!res) {                          if (!res) {
508                                  printf("couldn't read disk?\n");                                  fatal("Couldn't read the disk image. "
509                                  exit(1);                                      "Aborting.\n");
510                                    return 0;
511                          }                          }
512    
513                          n_blocks = minibuf[0] + (minibuf[1] << 8)                          n_blocks = minibuf[0] + (minibuf[1] << 8)
# Line 226  static void load_bootblock(struct machin Line 532  static void load_bootblock(struct machin
532                                  exit(1);                                  exit(1);
533                          }                          }
534    
535                          res = diskimage_access(m, boot_disk_id, 0,                          res = diskimage_access(m, boot_disk_id, boot_disk_type,
536                              bootblock_offset, bootblock_buf, n_blocks * 512);                              0, bootblock_offset, bootblock_buf, n_blocks * 512);
537                          if (!res) {                          if (!res) {
538                                  fatal("WARNING: could not load bootblocks from"                                  fatal("WARNING: could not load bootblocks from"
539                                      " disk offset 0x%llx\n",                                      " disk offset 0x%llx\n",
# Line 243  static void load_bootblock(struct machin Line 549  static void load_bootblock(struct machin
549                  }                  }
550    
551                  debug(readofs == 0x18? ": no blocks?\n" : " blocks\n");                  debug(readofs == 0x18? ": no blocks?\n" : " blocks\n");
552                  break;                  return 1;
553          default:  
554                  fatal("Booting from disk without a separate kernel "          case MACHINE_X86:
555                      "doesn't work in this emulation mode.\n");                  /*  TODO: "El Torito" etc?  */
556                    if (diskimage_is_a_cdrom(cpu->machine, boot_disk_id,
557                        boot_disk_type))
558                            break;
559    
560                    bootblock_buf = malloc(512);
561                    if (bootblock_buf == NULL) {
562                            fprintf(stderr, "Out of memory.\n");
563                            exit(1);
564                    }
565    
566                    debug("loading PC bootsector from %s id %i\n",
567                        diskimage_types[boot_disk_type], boot_disk_id);
568    
569                    res = diskimage_access(m, boot_disk_id, boot_disk_type, 0, 0,
570                        bootblock_buf, 512);
571                    if (!res) {
572                            fatal("Couldn't read the disk image. Aborting.\n");
573                            return 0;
574                    }
575    
576                    if (bootblock_buf[510] != 0x55 || bootblock_buf[511] != 0xaa)
577                            debug("WARNING! The 0x55,0xAA marker is missing! "
578                                "Booting anyway.\n");
579                    store_buf(cpu, 0x7c00, (char *)bootblock_buf, 512);
580                    free(bootblock_buf);
581    
582                    return 1;
583            }
584    
585    
586            /*
587             *  Try reading a kernel manually from the disk. The code here
588             *  does not rely on machine-dependant boot blocks etc.
589             */
590            /*  ISO9660: (0x800 bytes at 0x8000)  */
591            bootblock_buf = malloc(0x800);
592            if (bootblock_buf == NULL) {
593                    fprintf(stderr, "Out of memory.\n");
594                  exit(1);                  exit(1);
595          }          }
596    
597            res = diskimage_access(m, boot_disk_id, boot_disk_type,
598                0, 0x8000, bootblock_buf, 0x800);
599            if (!res) {
600                    fatal("Couldn't read the disk image. Aborting.\n");
601                    return 0;
602            }
603    
604            iso_type = 0;
605            if (strncmp((char *)bootblock_buf+1, "CD001", 5) == 0)
606                    iso_type = 1;
607            if (strncmp((char *)bootblock_buf+1, "CDW01", 5) == 0)
608                    iso_type = 2;
609            if (strncmp((char *)bootblock_buf+1, "CDROM", 5) == 0)
610                    iso_type = 3;
611    
612            if (iso_type != 0) {
613                    /*  We can't load a kernel if the name
614                        isn't specified.  */
615                    if (cpu->machine->boot_kernel_filename == NULL ||
616                        cpu->machine->boot_kernel_filename[0] == '\0')
617                            fatal("\nISO9660 filesystem, but no kernel "
618                                "specified? (Use the -j option.)\n");
619                    else
620                            retval = iso_load_bootblock(m, cpu, boot_disk_id,
621                                boot_disk_type, iso_type, bootblock_buf,
622                                n_loadp, load_namesp);
623            }
624    
625            free(bootblock_buf);
626            return retval;
627  }  }
628    
629    
# Line 340  static void add_arc_components(struct ma Line 715  static void add_arc_components(struct ma
715          arcbios_add_memory_descriptor(cpu,          arcbios_add_memory_descriptor(cpu,
716              start, len, ARCBIOS_MEM_LoadedProgram);              start, len, ARCBIOS_MEM_LoadedProgram);
717    
718          scsicontroller = arcbios_get_scsicontroller();          scsicontroller = arcbios_get_scsicontroller(m);
719          if (scsicontroller == 0)          if (scsicontroller == 0)
720                  return;                  return;
721    
# Line 388  static void add_arc_components(struct ma Line 763  static void add_arc_components(struct ma
763                                  snprintf(component_string,                                  snprintf(component_string,
764                                      sizeof(component_string),                                      sizeof(component_string),
765                                      "scsi(0)cdrom(%i)", d->id);                                      "scsi(0)cdrom(%i)", d->id);
766                                  arcbios_add_string_to_component(                                  arcbios_add_string_to_component(m,
767                                      component_string, scsidevice);                                      component_string, scsidevice);
768    
769                                  snprintf(component_string,                                  snprintf(component_string,
770                                      sizeof(component_string),                                      sizeof(component_string),
771                                      "scsi(0)cdrom(%i)fdisk(0)", d->id);                                      "scsi(0)cdrom(%i)fdisk(0)", d->id);
772                                  arcbios_add_string_to_component(                                  arcbios_add_string_to_component(m,
773                                      component_string, scsidisk);                                      component_string, scsidisk);
774                          } else {                          } else {
775                                  snprintf(component_string,                                  snprintf(component_string,
776                                      sizeof(component_string),                                      sizeof(component_string),
777                                      "scsi(0)disk(%i)", d->id);                                      "scsi(0)disk(%i)", d->id);
778                                  arcbios_add_string_to_component(                                  arcbios_add_string_to_component(m,
779                                      component_string, scsidevice);                                      component_string, scsidevice);
780    
781                                  snprintf(component_string,                                  snprintf(component_string,
782                                      sizeof(component_string),                                      sizeof(component_string),
783                                      "scsi(0)disk(%i)rdisk(0)", d->id);                                      "scsi(0)disk(%i)rdisk(0)", d->id);
784                                  arcbios_add_string_to_component(                                  arcbios_add_string_to_component(m,
785                                      component_string, scsidisk);                                      component_string, scsidisk);
786                          }                          }
787                  }                  }
# Line 432  void emul_machine_setup(struct machine * Line 807  void emul_machine_setup(struct machine *
807          struct emul *emul;          struct emul *emul;
808          struct cpu *cpu;          struct cpu *cpu;
809          int i, iadd=4;          int i, iadd=4;
810          uint64_t addr, memory_amount, entrypoint = 0, gp = 0, toc = 0;          uint64_t memory_amount, entrypoint = 0, gp = 0, toc = 0;
811          int byte_order;          int byte_order;
812    
813          emul = m->emul;          emul = m->emul;
# Line 537  void emul_machine_setup(struct machine * Line 912  void emul_machine_setup(struct machine *
912                  x11_init(m);                  x11_init(m);
913    
914          /*  Fill memory with random bytes:  */          /*  Fill memory with random bytes:  */
         /*  TODO: This is MIPS-specific!  */  
915          if (m->random_mem_contents) {          if (m->random_mem_contents) {
916                  for (i=0; i<m->physical_ram_in_mb * 1048576; i+=256) {                  for (i=0; i<m->physical_ram_in_mb * 1048576; i+=256) {
917                          unsigned char data[256];                          unsigned char data[256];
918                          unsigned int j;                          unsigned int j;
919                          for (j=0; j<sizeof(data); j++)                          for (j=0; j<sizeof(data); j++)
920                                  data[j] = random() & 255;                                  data[j] = random() & 255;
921                          addr = 0xffffffff80000000ULL + i;                          cpu->memory_rw(cpu, m->memory, i, data, sizeof(data),
922                          cpu->memory_rw(cpu, m->memory, addr, data, sizeof(data),                              MEM_WRITE, CACHE_NONE | NO_EXCEPTIONS | PHYSICAL);
                             MEM_WRITE, CACHE_NONE | NO_EXCEPTIONS);  
923                  }                  }
924          }          }
925    
         if ((m->machine_type == MACHINE_ARC ||  
             m->machine_type == MACHINE_SGI) && m->prom_emulation)  
                 arcbios_init();  
   
926          if (m->userland_emul != NULL) {          if (m->userland_emul != NULL) {
927                  /*                  /*
928                   *  For userland-only emulation, no machine emulation                   *  For userland-only emulation, no machine emulation
# Line 570  void emul_machine_setup(struct machine * Line 939  void emul_machine_setup(struct machine *
939    
940          /*  Load files (ROM code, boot code, ...) into memory:  */          /*  Load files (ROM code, boot code, ...) into memory:  */
941          if (n_load == 0) {          if (n_load == 0) {
942                  if (m->first_diskimage != NULL)                  if (m->first_diskimage != NULL) {
943                          load_bootblock(m, cpu);                          if (!load_bootblock(m, cpu, &n_load, &load_names)) {
944                  else {                                  fprintf(stderr, "\nNo executable files were"
945                                        " specified, and booting directly from disk"
946                                        " failed.\n");
947                                    exit(1);
948                            }
949                    } else {
950                          fprintf(stderr, "No executable file(s) loaded, and "                          fprintf(stderr, "No executable file(s) loaded, and "
951                              "we are not booting directly from a disk image."                              "we are not booting directly from a disk image."
952                              "\nAborting.\n");                              "\nAborting.\n");
# Line 581  void emul_machine_setup(struct machine * Line 955  void emul_machine_setup(struct machine *
955          }          }
956    
957          while (n_load > 0) {          while (n_load > 0) {
958                    FILE *tmp_f;
959                    char *name_to_load = *load_names;
960                    int remove_after_load = 0;
961    
962                    /*  Special hack for removing temporary files:  */
963                    if (name_to_load[0] == 8) {
964                            name_to_load ++;
965                            remove_after_load = 1;
966                    }
967    
968                    /*
969                     *  Another special hack for temporary files; running gunzip
970                     *  on them, if they have a gzip header.  TODO: Change this
971                     *  into some kind of generic support for gzipped files!
972                     */
973                    tmp_f = fopen(name_to_load, "r");
974                    if (tmp_f != NULL) {
975                            unsigned char buf[2];           /*  gzip header  */
976                            memset(buf, 0, sizeof(buf));
977                            fread(buf, 1, sizeof(buf), tmp_f);
978                            if (buf[0]==0x1f && buf[1]==0x8b) {
979                                    char *zz = malloc(strlen(name_to_load)*2 + 100);
980                                    debug("gunziping %s\n", name_to_load);
981                                    sprintf(zz, "mv %s %s.gz", name_to_load,
982                                        name_to_load);
983                                    system(zz);
984                                    sprintf(zz, "gunzip %s.gz", name_to_load);
985                                    system(zz);
986                                    free(zz);
987                            }
988                            fclose(tmp_f);
989                    }
990    
991                    /*  Special things required _before_ loading the file:  */
992                    switch (m->arch) {
993                    case ARCH_X86:
994                            /*
995                             *  X86 machines normally don't need to load any files,
996                             *  they can boot from disk directly. Therefore, an x86
997                             *  machine usually boots up in 16-bit real mode. When
998                             *  loading a 32-bit (or even 64-bit) ELF, that's not
999                             *  very nice, hence this special case.
1000                             */
1001                            pc_bios_simple_pmode_setup(cpu);
1002                            break;
1003                    }
1004    
1005                  byte_order = NO_BYTE_ORDER_OVERRIDE;                  byte_order = NO_BYTE_ORDER_OVERRIDE;
1006    
1007                  file_load(m, m->memory, *load_names, &entrypoint,                  /*
1008                     *  Load the file:  :-)
1009                     */
1010                    file_load(m, m->memory, name_to_load, &entrypoint,
1011                      m->arch, &gp, &byte_order, &toc);                      m->arch, &gp, &byte_order, &toc);
1012    
1013                    if (remove_after_load) {
1014                            debug("removing %s\n", name_to_load);
1015                            unlink(name_to_load);
1016                    }
1017    
1018                  if (byte_order != NO_BYTE_ORDER_OVERRIDE)                  if (byte_order != NO_BYTE_ORDER_OVERRIDE)
1019                          cpu->byte_order = byte_order;                          cpu->byte_order = byte_order;
1020    
# Line 604  void emul_machine_setup(struct machine * Line 1033  void emul_machine_setup(struct machine *
1033                                  cpu->cd.mips.gpr[MIPS_GPR_GP] |=                                  cpu->cd.mips.gpr[MIPS_GPR_GP] |=
1034                                      0xffffffff00000000ULL;                                      0xffffffff00000000ULL;
1035                          break;                          break;
1036    
1037                  case ARCH_PPC:                  case ARCH_PPC:
1038                            /*  See http://www.linuxbase.org/spec/ELF/ppc64/
1039                                spec/x458.html for more info.  */
1040                          cpu->cd.ppc.gpr[2] = toc;                          cpu->cd.ppc.gpr[2] = toc;
1041                            /*  TODO  */
1042                          break;                          break;
1043    
1044                    case ARCH_ALPHA:
1045                    case ARCH_HPPA:
1046                  case ARCH_SPARC:                  case ARCH_SPARC:
                         break;  
1047                  case ARCH_URISC:                  case ARCH_URISC:
1048                          break;                          break;
1049                  case ARCH_HPPA:  
1050                    case ARCH_ARM:
1051                            cpu->pc &= 0xffffffff;
1052                          break;                          break;
1053                  case ARCH_ALPHA:  
1054                    case ARCH_X86:
1055                            /*
1056                             *  NOTE: The toc field is used to indicate an ELF32
1057                             *  or ELF64 load.
1058                             */
1059                            switch (toc) {
1060                            case 0: /*  16-bit? TODO  */
1061                                    cpu->pc &= 0xffffffffULL;
1062                                    break;
1063                            case 1: /*  32-bit.  */
1064                                    cpu->pc &= 0xffffffffULL;
1065                                    break;
1066                            case 2: /*  64-bit:  TODO  */
1067                                    fatal("64-bit x86 load. TODO\n");
1068                                    exit(1);
1069                            }
1070                          break;                          break;
1071    
1072                  default:                  default:
1073                          fatal("emul_machine_setup(): Internal error: "                          fatal("emul_machine_setup(): Internal error: "
1074                              "Unimplemented arch %i\n", m->arch);                              "Unimplemented arch %i\n", m->arch);
# Line 704  void emul_machine_setup(struct machine * Line 1158  void emul_machine_setup(struct machine *
1158                  else                  else
1159                          debug("0x%016llx", (long long)entrypoint);                          debug("0x%016llx", (long long)entrypoint);
1160                  break;                  break;
1161            case ARCH_ARM:
1162                    /*  ARM cpus aren't 64-bit:  */
1163                    debug("0x%08x", (int)entrypoint);
1164                    break;
1165          case ARCH_URISC:          case ARCH_URISC:
1166                  {                  {
1167                          char tmps[100];                          char tmps[100];
# Line 727  void emul_machine_setup(struct machine * Line 1185  void emul_machine_setup(struct machine *
1185                          cpu->pc = entrypoint;                          cpu->pc = entrypoint;
1186                  }                  }
1187                  break;                  break;
1188            case ARCH_X86:
1189                    debug("0x%04x:0x%llx", cpu->cd.x86.s[X86_S_CS],
1190                        (long long)cpu->pc);
1191                    break;
1192          default:          default:
1193                  debug("0x%016llx", (long long)entrypoint);                  debug("0x%016llx", (long long)cpu->pc);
1194          }          }
1195          debug("\n");          debug("\n");
1196    

Legend:
Removed from v.2  
changed lines
  Added in v.6

  ViewVC Help
Powered by ViewVC 1.1.26