Exemple #1
0
SIM_RC
sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
		     char **argv, char **env)
{
  SIM_CPU *cpu = STATE_CPU (sd, 0);
  SIM_ADDR addr;

  /* Set the PC.  */
  if (abfd != NULL)
    addr = bfd_get_start_address (abfd);
  else
    addr = 0;
  sim_pc_set (cpu, addr);

  /* Standalone mode (i.e. `bfin-...-run`) will take care of the argv
     for us in sim_open() -> sim_parse_args().  But in debug mode (i.e.
     'target sim' with `bfin-...-gdb`), we need to handle it.  */
  if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
    {
      freeargv (STATE_PROG_ARGV (sd));
      STATE_PROG_ARGV (sd) = dupargv (argv);
    }

  switch (STATE_ENVIRONMENT (sd))
    {
    case USER_ENVIRONMENT:
      bfin_user_init (sd, cpu, abfd, (void *)argv, (void *)env);
      break;
    case OPERATING_ENVIRONMENT:
      bfin_os_init (sd, cpu, (void *)argv);
      break;
    default:
      bfin_virtual_init (sd, cpu);
      break;
    }

  return SIM_RC_OK;
}
Exemple #2
0
int
main (int argc, char **argv)
{
  char *name;
  char **prog_argv = NULL;
  struct bfd *prog_bfd;
  enum sim_stop reason;
  int sigrc = 0;
  int single_step = 0;
  RETSIGTYPE (*prev_sigint) ();

  myname = argv[0] + strlen (argv[0]);
  while (myname > argv[0] && myname[-1] != '/')
    --myname;

  /* INTERNAL: When MYNAME is `step', single step the simulator
     instead of allowing it to run free.  The sole purpose of this
     HACK is to allow the sim_resume interface's step argument to be
     tested without having to build/run gdb. */
  if (strlen (myname) > 4 && strcmp (myname - 4, "step") == 0)
    {
      single_step = 1;
    }

  /* Create an instance of the simulator.  */
  default_callback.init (&default_callback);
  sd = sim_open (SIM_OPEN_STANDALONE, &default_callback, NULL, argv);
  if (sd == 0)
    exit (1);
  if (STATE_MAGIC (sd) != SIM_MAGIC_NUMBER)
    {
      fprintf (stderr, "Internal error - bad magic number in simulator struct\n");
      abort ();
    }

  /* We can't set the endianness in the callback structure until
     sim_config is called, which happens in sim_open.  */
  default_callback.target_endian
    = (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN
       ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE);

  /* Was there a program to run?  */
  prog_argv = STATE_PROG_ARGV (sd);
  prog_bfd = STATE_PROG_BFD (sd);
  if (prog_argv == NULL || *prog_argv == NULL)
    usage ();

  name = *prog_argv;

  /* For simulators that don't open prog during sim_open() */
  if (prog_bfd == NULL)
    {
      prog_bfd = bfd_openr (name, 0);
      if (prog_bfd == NULL)
	{
	  fprintf (stderr, "%s: can't open \"%s\": %s\n",
		   myname, name, bfd_errmsg (bfd_get_error ()));
	  exit (1);
	}
      if (!bfd_check_format (prog_bfd, bfd_object))
	{
	  fprintf (stderr, "%s: \"%s\" is not an object file: %s\n",
		   myname, name, bfd_errmsg (bfd_get_error ()));
	  exit (1);
	}
    }

  if (STATE_VERBOSE_P (sd))
    printf ("%s %s\n", myname, name);

  /* Load the program into the simulator.  */
  if (sim_load (sd, name, prog_bfd, 0) == SIM_RC_FAIL)
    exit (1);

  /* Prepare the program for execution.  */
#ifdef HAVE_ENVIRON
  sim_create_inferior (sd, prog_bfd, prog_argv, environ);
#else
  sim_create_inferior (sd, prog_bfd, prog_argv, NULL);
#endif

  /* To accommodate relative file paths, chdir to sysroot now.  We
     mustn't do this until BFD has opened the program, else we wouldn't
     find the executable if it has a relative file path.  */
  if (simulator_sysroot[0] != '\0' && chdir (simulator_sysroot) < 0)
    {
      fprintf (stderr, "%s: can't change directory to \"%s\"\n",
	       myname, simulator_sysroot);
      exit (1);
    }

  /* Run/Step the program.  */
  if (single_step)
    {
      do
	{
	  prev_sigint = signal (SIGINT, cntrl_c);
	  sim_resume (sd, 1/*step*/, 0);
	  signal (SIGINT, prev_sigint);
	  sim_stop_reason (sd, &reason, &sigrc);

	  if ((reason == sim_stopped) &&
	      (sigrc == sim_signal_to_host (sd, SIM_SIGINT)))
	    break; /* exit on control-C */
	}
      /* remain on breakpoint or signals in oe mode*/
      while (((reason == sim_signalled) &&
	      (sigrc == sim_signal_to_host (sd, SIM_SIGTRAP))) ||
	     ((reason == sim_stopped) &&
	      (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)));
    }
  else
    {
      do
	{
#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
	  struct sigaction sa, osa;
	  sa.sa_handler = cntrl_c;
	  sigemptyset (&sa.sa_mask);
	  sa.sa_flags = 0;
	  sigaction (SIGINT, &sa, &osa);
	  prev_sigint = osa.sa_handler;
#else
	  prev_sigint = signal (SIGINT, cntrl_c);
#endif
	  sim_resume (sd, 0, sigrc);
	  signal (SIGINT, prev_sigint);
	  sim_stop_reason (sd, &reason, &sigrc);

	  if ((reason == sim_stopped) &&
	      (sigrc == sim_signal_to_host (sd, SIM_SIGINT)))
	    break; /* exit on control-C */

	  /* remain on signals in oe mode */
	} while ((reason == sim_stopped) &&
		 (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT));

    }
  /* Print any stats the simulator collected.  */
  if (STATE_VERBOSE_P (sd))
    sim_info (sd, 0);

  /* Shutdown the simulator.  */
  sim_close (sd, 0);

  /* If reason is sim_exited, then sigrc holds the exit code which we want
     to return.  If reason is sim_stopped or sim_signalled, then sigrc holds
     the signal that the simulator received; we want to return that to
     indicate failure.  */

  /* Why did we stop? */
  switch (reason)
    {
    case sim_signalled:
    case sim_stopped:
      if (sigrc != 0)
        fprintf (stderr, "program stopped with signal %d.\n", sigrc);
      break;

    case sim_exited:
      break;

    default:
      fprintf (stderr, "program in undefined state (%d:%d)\n", reason, sigrc);
      break;

    }

  return sigrc;
}
Exemple #3
0
SIM_DESC
sim_open (SIM_OPEN_KIND kind, host_callback *callback,
	  struct bfd *abfd, char **argv)
{
  char c;
  int i;
  SIM_DESC sd = sim_state_alloc (kind, callback);

  /* The cpu data is kept in a separately allocated chunk of memory.  */
  if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  {
    /* XXX: Only first core gets profiled ?  */
    SIM_CPU *cpu = STATE_CPU (sd, 0);
    STATE_WATCHPOINTS (sd)->pc = &PCREG;
    STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PCREG);
  }

  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* XXX: Default to the Virtual environment.  */
  if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT)
    STATE_ENVIRONMENT (sd) = VIRTUAL_ENVIRONMENT;

  /* These options override any module options.
     Obviously ambiguity should be avoided, however the caller may wish to
     augment the meaning of an option.  */
#define e_sim_add_option_table(sd, options) \
  do { \
    extern const OPTION options[]; \
    sim_add_option_table (sd, NULL, options); \
  } while (0)
  e_sim_add_option_table (sd, bfin_mmu_options);
  e_sim_add_option_table (sd, bfin_mach_options);

  /* getopt will print the error message so we just have to exit if this fails.
     FIXME: Hmmm...  in the case of gdb we need getopt to call
     print_filtered.  */
  if (sim_parse_args (sd, argv) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* Allocate external memory if none specified by user.
     Use address 4 here in case the user wanted address 0 unmapped.  */
  if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
    {
      bu16 emuexcpt = 0x25;
      sim_do_commandf (sd, "memory-size 0x%lx", BFIN_DEFAULT_MEM_SIZE);
      sim_write (sd, 0, (void *)&emuexcpt, 2);
    }

  /* Check for/establish the a reference program image.  */
  if (sim_analyze_program (sd,
			   (STATE_PROG_ARGV (sd) != NULL
			    ? *STATE_PROG_ARGV (sd)
			    : NULL), abfd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* Establish any remaining configuration options.  */
  if (sim_config (sd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  if (sim_post_argv_init (sd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* CPU specific initialization.  */
  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
    {
      SIM_CPU *cpu = STATE_CPU (sd, i);
      bfin_initialize_cpu (sd, cpu);
    }

  return sd;
}
Exemple #4
0
void
bfin_syscall (SIM_CPU *cpu)
{
  SIM_DESC sd = CPU_STATE (cpu);
  const char * const *argv = (void *)STATE_PROG_ARGV (sd);
  host_callback *cb = STATE_CALLBACK (sd);
  bu32 args[6];
  CB_SYSCALL sc;
  char *p;
  char _tbuf[1024 * 3], *tbuf = _tbuf, tstr[1024];
  int fmt_ret_hex = 0;

  CB_SYSCALL_INIT (&sc);

  if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
    {
      /* Linux syscall.  */
      sc.func = PREG (0);
      sc.arg1 = args[0] = DREG (0);
      sc.arg2 = args[1] = DREG (1);
      sc.arg3 = args[2] = DREG (2);
      sc.arg4 = args[3] = DREG (3);
      /*sc.arg5 =*/ args[4] = DREG (4);
      /*sc.arg6 =*/ args[5] = DREG (5);
    }
  else
    {
      /* libgloss syscall.  */
      sc.func = PREG (0);
      sc.arg1 = args[0] = GET_LONG (DREG (0));
      sc.arg2 = args[1] = GET_LONG (DREG (0) + 4);
      sc.arg3 = args[2] = GET_LONG (DREG (0) + 8);
      sc.arg4 = args[3] = GET_LONG (DREG (0) + 12);
      /*sc.arg5 =*/ args[4] = GET_LONG (DREG (0) + 16);
      /*sc.arg6 =*/ args[5] = GET_LONG (DREG (0) + 20);
    }
  sc.p1 = (PTR) sd;
  sc.p2 = (PTR) cpu;
  sc.read_mem = sim_syscall_read_mem;
  sc.write_mem = sim_syscall_write_mem;

  /* Common cb_syscall() handles most functions.  */
  switch (cb_target_to_host_syscall (cb, sc.func))
    {
    case CB_SYS_exit:
      tbuf += sprintf (tbuf, "exit(%i)", args[0]);
      sim_engine_halt (sd, cpu, NULL, PCREG, sim_exited, sc.arg1);

#ifdef CB_SYS_argc
    case CB_SYS_argc:
      tbuf += sprintf (tbuf, "argc()");
      sc.result = count_argc (argv);
      break;
    case CB_SYS_argnlen:
      {
      tbuf += sprintf (tbuf, "argnlen(%u)", args[0]);
	if (sc.arg1 < count_argc (argv))
	  sc.result = strlen (argv[sc.arg1]);
	else
	  sc.result = -1;
      }
      break;
    case CB_SYS_argn:
      {
	tbuf += sprintf (tbuf, "argn(%u)", args[0]);
	if (sc.arg1 < count_argc (argv))
	  {
	    const char *argn = argv[sc.arg1];
	    int len = strlen (argn);
	    int written = sc.write_mem (cb, &sc, sc.arg2, argn, len + 1);
	    if (written == len + 1)
	      sc.result = sc.arg2;
	    else
	      sc.result = -1;
	  }
	else
	  sc.result = -1;
      }
      break;
#endif

    case CB_SYS_gettimeofday:
      {
	struct timeval _tv, *tv = &_tv;
	struct timezone _tz, *tz = &_tz;

	tbuf += sprintf (tbuf, "gettimeofday(%#x, %#x)", args[0], args[1]);

	if (sc.arg1 == 0)
	  tv = NULL;
	if (sc.arg2 == 0)
	  tz = NULL;
	sc.result = gettimeofday (tv, tz);

	if (sc.result == 0)
	  {
	    bu32 t;

	    if (tv)
	      {
		t = tv->tv_sec;
		sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
		t = tv->tv_usec;
		sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
	      }

	    if (sc.arg2)
	      {
		t = tz->tz_minuteswest;
		sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
		t = tz->tz_dsttime;
		sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
	      }
	  }
	else
	  goto sys_finish;
      }
      break;

    case CB_SYS_ioctl:
      /* XXX: hack just enough to get basic stdio w/uClibc ...  */
      tbuf += sprintf (tbuf, "ioctl(%i, %#x, %u)", args[0], args[1], args[2]);
      if (sc.arg2 == 0x5401)
	{
	  sc.result = !isatty (sc.arg1);
	  sc.errcode = 0;
	}
      else
	{
	  sc.result = -1;
	  sc.errcode = TARGET_EINVAL;
	}
      break;

    case CB_SYS_mmap2:
      {
	static bu32 heap = BFIN_DEFAULT_MEM_SIZE / 2;

	fmt_ret_hex = 1;
	tbuf += sprintf (tbuf, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
			 args[0], args[1], args[2], args[3], args[4], args[5]);

	sc.errcode = 0;

	if (sc.arg4 & 0x20 /*MAP_ANONYMOUS*/)
	  /* XXX: We don't handle zeroing, but default is all zeros.  */;
	else if (args[4] >= MAX_CALLBACK_FDS)
	  sc.errcode = TARGET_ENOSYS;
	else
	  {
#ifdef HAVE_PREAD
	    char *data = xmalloc (sc.arg2);

	    /* XXX: Should add a cb->pread.  */
	    if (pread (cb->fdmap[args[4]], data, sc.arg2, args[5] << 12) == sc.arg2)
	      sc.write_mem (cb, &sc, heap, data, sc.arg2);
	    else
	      sc.errcode = TARGET_EINVAL;

	    free (data);
#else
	    sc.errcode = TARGET_ENOSYS;
#endif
	  }

	if (sc.errcode)
	  {
	    sc.result = -1;
	    break;
	  }

	sc.result = heap;
	heap += sc.arg2;
	/* Keep it page aligned.  */
	heap = ALIGN (heap, 4096);

	break;
      }

    case CB_SYS_munmap:
      /* XXX: meh, just lie for mmap().  */
      tbuf += sprintf (tbuf, "munmap(%#x, %u)", args[0], args[1]);
      sc.result = 0;
      break;

    case CB_SYS_dup2:
      tbuf += sprintf (tbuf, "dup2(%i, %i)", args[0], args[1]);
      if (sc.arg1 >= MAX_CALLBACK_FDS || sc.arg2 >= MAX_CALLBACK_FDS)
	{
	  sc.result = -1;
	  sc.errcode = TARGET_EINVAL;
	}
      else
	{
	  sc.result = dup2 (cb->fdmap[sc.arg1], cb->fdmap[sc.arg2]);
	  goto sys_finish;
	}
      break;

    case CB_SYS__llseek:
      tbuf += sprintf (tbuf, "llseek(%i, %u, %u, %#x, %u)",
		       args[0], args[1], args[2], args[3], args[4]);
      sc.func = TARGET_LINUX_SYS_lseek;
      if (sc.arg2)
	{
	  sc.result = -1;
	  sc.errcode = TARGET_EINVAL;
	}
      else
	{
	  sc.arg2 = sc.arg3;
	  sc.arg3 = args[4];
	  cb_syscall (cb, &sc);
	  if (sc.result != -1)
	    {
	      bu32 z = 0;
	      sc.write_mem (cb, &sc, args[3], (void *)&sc.result, 4);
	      sc.write_mem (cb, &sc, args[3] + 4, (void *)&z, 4);
	    }
	}
      break;

    /* XXX: Should add a cb->pread.  */
    case CB_SYS_pread:
      tbuf += sprintf (tbuf, "pread(%i, %#x, %u, %i)",
		       args[0], args[1], args[2], args[3]);
      if (sc.arg1 >= MAX_CALLBACK_FDS)
	{
	  sc.result = -1;
	  sc.errcode = TARGET_EINVAL;
	}
      else
	{
	  long old_pos, read_result, read_errcode;

	  /* Get current filepos.  */
	  sc.func = TARGET_LINUX_SYS_lseek;
	  sc.arg2 = 0;
	  sc.arg3 = SEEK_CUR;
	  cb_syscall (cb, &sc);
	  if (sc.result == -1)
	    break;
	  old_pos = sc.result;

	  /* Move to the new pos.  */
	  sc.func = TARGET_LINUX_SYS_lseek;
	  sc.arg2 = args[3];
	  sc.arg3 = SEEK_SET;
	  cb_syscall (cb, &sc);
	  if (sc.result == -1)
	    break;

	  /* Read the data.  */
	  sc.func = TARGET_LINUX_SYS_read;
	  sc.arg2 = args[1];
	  sc.arg3 = args[2];
	  cb_syscall (cb, &sc);
	  read_result = sc.result;
	  read_errcode = sc.errcode;

	  /* Move back to the old pos.  */
	  sc.func = TARGET_LINUX_SYS_lseek;
	  sc.arg2 = old_pos;
	  sc.arg3 = SEEK_SET;
	  cb_syscall (cb, &sc);

	  sc.result = read_result;
	  sc.errcode = read_errcode;
	}
      break;

    case CB_SYS_getcwd:
      tbuf += sprintf (tbuf, "getcwd(%#x, %u)", args[0], args[1]);

      p = alloca (sc.arg2);
      if (getcwd (p, sc.arg2) == NULL)
	{
	  sc.result = -1;
	  sc.errcode = TARGET_EINVAL;
	}
      else
	{
	  sc.write_mem (cb, &sc, sc.arg1, p, sc.arg2);
	  sc.result = sc.arg1;
	}
      break;

    case CB_SYS_stat64:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "stat64(%#x:\"%s\", %u)", args[0], tstr, args[1]);
      cb->stat_map = stat_map_64;
      sc.func = TARGET_LINUX_SYS_stat;
      cb_syscall (cb, &sc);
      cb->stat_map = stat_map_32;
      break;
    case CB_SYS_lstat64:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "lstat64(%#x:\"%s\", %u)", args[0], tstr, args[1]);
      cb->stat_map = stat_map_64;
      sc.func = TARGET_LINUX_SYS_lstat;
      cb_syscall (cb, &sc);
      cb->stat_map = stat_map_32;
      break;
    case CB_SYS_fstat64:
      tbuf += sprintf (tbuf, "fstat64(%#x, %u)", args[0], args[1]);
      cb->stat_map = stat_map_64;
      sc.func = TARGET_LINUX_SYS_fstat;
      cb_syscall (cb, &sc);
      cb->stat_map = stat_map_32;
      break;

    case CB_SYS_ftruncate64:
      tbuf += sprintf (tbuf, "ftruncate64(%u, %u)", args[0], args[1]);
      sc.func = TARGET_LINUX_SYS_ftruncate;
      cb_syscall (cb, &sc);
      break;

    case CB_SYS_getuid:
    case CB_SYS_getuid32:
      tbuf += sprintf (tbuf, "getuid()");
      sc.result = getuid ();
      goto sys_finish;
    case CB_SYS_getgid:
    case CB_SYS_getgid32:
      tbuf += sprintf (tbuf, "getgid()");
      sc.result = getgid ();
      goto sys_finish;
    case CB_SYS_setuid:
      sc.arg1 &= 0xffff;
    case CB_SYS_setuid32:
      tbuf += sprintf (tbuf, "setuid(%u)", args[0]);
      sc.result = setuid (sc.arg1);
      goto sys_finish;
    case CB_SYS_setgid:
      sc.arg1 &= 0xffff;
    case CB_SYS_setgid32:
      tbuf += sprintf (tbuf, "setgid(%u)", args[0]);
      sc.result = setgid (sc.arg1);
      goto sys_finish;

    case CB_SYS_getpid:
      tbuf += sprintf (tbuf, "getpid()");
      sc.result = getpid ();
      goto sys_finish;
    case CB_SYS_kill:
      tbuf += sprintf (tbuf, "kill(%u, %i)", args[0], args[1]);
      /* Only let the app kill itself.  */
      if (sc.arg1 != getpid ())
	{
	  sc.result = -1;
	  sc.errcode = TARGET_EPERM;
	}
      else
	{
#ifdef HAVE_KILL
	  sc.result = kill (sc.arg1, sc.arg2);
	  goto sys_finish;
#else
	  sc.result = -1;
	  sc.errcode = TARGET_ENOSYS;
#endif
	}
      break;

    case CB_SYS_open:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "open(%#x:\"%s\", %#x, %o)",
		       args[0], tstr, args[1], args[2]);
      goto case_default;
    case CB_SYS_close:
      tbuf += sprintf (tbuf, "close(%i)", args[0]);
      goto case_default;
    case CB_SYS_read:
      tbuf += sprintf (tbuf, "read(%i, %#x, %u)", args[0], args[1], args[2]);
      goto case_default;
    case CB_SYS_write:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[1]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "write(%i, %#x:\"%s\", %u)",
		       args[0], args[1], tstr, args[2]);
      goto case_default;
    case CB_SYS_lseek:
      tbuf += sprintf (tbuf, "lseek(%i, %i, %i)", args[0], args[1], args[2]);
      goto case_default;
    case CB_SYS_unlink:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "unlink(%#x:\"%s\")", args[0], tstr);
      goto case_default;
    case CB_SYS_truncate:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "truncate(%#x:\"%s\", %i)", args[0], tstr, args[1]);
      goto case_default;
    case CB_SYS_ftruncate:
      tbuf += sprintf (tbuf, "ftruncate(%i, %i)", args[0], args[1]);
      goto case_default;
    case CB_SYS_rename:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "rename(%#x:\"%s\", ", args[0], tstr);
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[1]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "%#x:\"%s\")", args[1], tstr);
      goto case_default;
    case CB_SYS_stat:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "stat(%#x:\"%s\", %#x)", args[0], tstr, args[1]);
      goto case_default;
    case CB_SYS_fstat:
      tbuf += sprintf (tbuf, "fstat(%i, %#x)", args[0], args[1]);
      goto case_default;
    case CB_SYS_lstat:
      if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
	strcpy (tstr, "???");
      tbuf += sprintf (tbuf, "lstat(%#x:\"%s\", %#x)", args[0], tstr, args[1]);
      goto case_default;
    case CB_SYS_pipe:
      tbuf += sprintf (tbuf, "pipe(%#x, %#x)", args[0], args[1]);
      goto case_default;

    default:
      tbuf += sprintf (tbuf, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc.func,
		       args[0], args[1], args[2], args[3], args[4], args[5]);
    case_default:
      cb_syscall (cb, &sc);
      break;

    sys_finish:
      if (sc.result == -1)
	{
	  cb->last_errno = errno;
	  sc.errcode = cb->get_errno (cb);
	}
    }

  TRACE_EVENTS (cpu, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
		sc.func, args[0], args[1], args[2], args[3], args[4], args[5],
		sc.result, sc.errcode);

  tbuf += sprintf (tbuf, " = ");
  if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
    {
      if (sc.result == -1)
	{
	  tbuf += sprintf (tbuf, "-1 (error = %i)", sc.errcode);
	  if (sc.errcode == cb_host_to_target_errno (cb, ENOSYS))
	    {
	      sim_io_eprintf (sd, "bfin-sim: %#x: unimplemented syscall %i\n",
			      PCREG, sc.func);
	    }
	  SET_DREG (0, -sc.errcode);
	}
      else
	{
	  if (fmt_ret_hex)
	    tbuf += sprintf (tbuf, "%#lx", sc.result);
	  else
	    tbuf += sprintf (tbuf, "%lu", sc.result);
	  SET_DREG (0, sc.result);
	}
    }
  else
    {
      tbuf += sprintf (tbuf, "%lu (error = %i)", sc.result, sc.errcode);
      SET_DREG (0, sc.result);
      SET_DREG (1, sc.result2);
      SET_DREG (2, sc.errcode);
    }

  TRACE_SYSCALL (cpu, "%s", _tbuf);
}
SIM_DESC
sim_open (SIM_OPEN_KIND kind, host_callback *callback,
          bfd *abfd, char **argv)
{
  SIM_DESC sd;
  sim_cpu *cpu;

  sd = sim_state_alloc (kind, callback);
  cpu = STATE_CPU (sd, 0);

  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);

  /* for compatibility */
  current_alignment = NONSTRICT_ALIGNMENT;
  current_target_byte_order = BIG_ENDIAN;

  cpu_initialize (sd, cpu);

  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* getopt will print the error message so we just have to exit if this fails.
     FIXME: Hmmm...  in the case of gdb we need getopt to call
     print_filtered.  */
  if (sim_parse_args (sd, argv) != SIM_RC_OK)
    {
      /* Uninstall the modules to avoid memory leaks,
         file descriptor leaks, etc.  */
      free_state (sd);
      return 0;
    }

  /* Check for/establish the a reference program image.  */
  if (sim_analyze_program (sd,
			   (STATE_PROG_ARGV (sd) != NULL
			    ? *STATE_PROG_ARGV (sd)
			    : NULL), abfd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* Establish any remaining configuration options.  */
  if (sim_config (sd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  if (sim_post_argv_init (sd) != SIM_RC_OK)
    {
      /* Uninstall the modules to avoid memory leaks,
         file descriptor leaks, etc.  */
      free_state (sd);
      return 0;
    }
  if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }      

  /* Fudge our descriptor.  */
  return sd;
}
Exemple #6
0
SIM_DESC
sim_open (SIM_OPEN_KIND kind,
	  host_callback *cb,
	  struct bfd *abfd,
	  char **argv)
{
  int i;
  SIM_DESC sd = sim_state_alloc (kind, cb);
  mn10300_callback = cb;

  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);

  /* The cpu data is kept in a separately allocated chunk of memory.  */
  if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
    return 0;

  /* for compatibility */
  simulator = sd;

  /* FIXME: should be better way of setting up interrupts.  For
     moment, only support watchpoints causing a breakpoint (gdb
     halt). */
  STATE_WATCHPOINTS (sd)->pc = &(PC);
  STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
  STATE_WATCHPOINTS (sd)->interrupt_handler = NULL;
  STATE_WATCHPOINTS (sd)->interrupt_names = NULL;

  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
    return 0;
  sim_add_option_table (sd, NULL, mn10300_options);

  /* Allocate core managed memory */
  sim_do_command (sd, "memory region 0,0x100000");
  sim_do_command (sd, "memory region 0x40000000,0x200000");

  /* getopt will print the error message so we just have to exit if this fails.
     FIXME: Hmmm...  in the case of gdb we need getopt to call
     print_filtered.  */
  if (sim_parse_args (sd, argv) != SIM_RC_OK)
    {
      /* Uninstall the modules to avoid memory leaks,
	 file descriptor leaks, etc.  */
      sim_module_uninstall (sd);
      return 0;
    }

  if ( NULL != board
       && (strcmp(board, BOARD_AM32) == 0 ) )
    {
      /* environment */
      STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;

      sim_do_command (sd, "memory region 0x44000000,0x40000");
      sim_do_command (sd, "memory region 0x48000000,0x400000");

      /* device support for mn1030002 */
      /* interrupt controller */

      sim_hw_parse (sd, "/mn103int@0x34000100/reg 0x34000100 0x7C 0x34000200 0x8 0x34000280 0x8");

      /* DEBUG: NMI input's */
      sim_hw_parse (sd, "/glue@0x30000000/reg 0x30000000 12");
      sim_hw_parse (sd, "/glue@0x30000000 > int0 nmirq /mn103int");
      sim_hw_parse (sd, "/glue@0x30000000 > int1 watchdog /mn103int");
      sim_hw_parse (sd, "/glue@0x30000000 > int2 syserr /mn103int");
      
      /* DEBUG: ACK input */
      sim_hw_parse (sd, "/glue@0x30002000/reg 0x30002000 4");
      sim_hw_parse (sd, "/glue@0x30002000 > int ack /mn103int");
      
      /* DEBUG: LEVEL output */
      sim_hw_parse (sd, "/glue@0x30004000/reg 0x30004000 8");
      sim_hw_parse (sd, "/mn103int > nmi int0 /glue@0x30004000");
      sim_hw_parse (sd, "/mn103int > level int1 /glue@0x30004000");
      
      /* DEBUG: A bunch of interrupt inputs */
      sim_hw_parse (sd, "/glue@0x30006000/reg 0x30006000 32");
      sim_hw_parse (sd, "/glue@0x30006000 > int0 irq-0 /mn103int");
      sim_hw_parse (sd, "/glue@0x30006000 > int1 irq-1 /mn103int");
      sim_hw_parse (sd, "/glue@0x30006000 > int2 irq-2 /mn103int");
      sim_hw_parse (sd, "/glue@0x30006000 > int3 irq-3 /mn103int");
      sim_hw_parse (sd, "/glue@0x30006000 > int4 irq-4 /mn103int");
      sim_hw_parse (sd, "/glue@0x30006000 > int5 irq-5 /mn103int");
      sim_hw_parse (sd, "/glue@0x30006000 > int6 irq-6 /mn103int");
      sim_hw_parse (sd, "/glue@0x30006000 > int7 irq-7 /mn103int");
      
      /* processor interrupt device */
      
      /* the device */
      sim_hw_parse (sd, "/mn103cpu@0x20000000");
      sim_hw_parse (sd, "/mn103cpu@0x20000000/reg 0x20000000 0x42");
      
      /* DEBUG: ACK output wired upto a glue device */
      sim_hw_parse (sd, "/glue@0x20002000");
      sim_hw_parse (sd, "/glue@0x20002000/reg 0x20002000 4");
      sim_hw_parse (sd, "/mn103cpu > ack int0 /glue@0x20002000");
      
      /* DEBUG: RESET/NMI/LEVEL wired up to a glue device */
      sim_hw_parse (sd, "/glue@0x20004000");
      sim_hw_parse (sd, "/glue@0x20004000/reg 0x20004000 12");
      sim_hw_parse (sd, "/glue@0x20004000 > int0 reset /mn103cpu");
      sim_hw_parse (sd, "/glue@0x20004000 > int1 nmi /mn103cpu");
      sim_hw_parse (sd, "/glue@0x20004000 > int2 level /mn103cpu");
      
      /* REAL: The processor wired up to the real interrupt controller */
      sim_hw_parse (sd, "/mn103cpu > ack ack /mn103int");
      sim_hw_parse (sd, "/mn103int > level level /mn103cpu");
      sim_hw_parse (sd, "/mn103int > nmi nmi /mn103cpu");
      
      
      /* PAL */
      
      /* the device */
      sim_hw_parse (sd, "/pal@0x31000000");
      sim_hw_parse (sd, "/pal@0x31000000/reg 0x31000000 64");
      sim_hw_parse (sd, "/pal@0x31000000/poll? true");
      
      /* DEBUG: PAL wired up to a glue device */
      sim_hw_parse (sd, "/glue@0x31002000");
      sim_hw_parse (sd, "/glue@0x31002000/reg 0x31002000 16");
      sim_hw_parse (sd, "/pal@0x31000000 > countdown int0 /glue@0x31002000");
      sim_hw_parse (sd, "/pal@0x31000000 > timer int1 /glue@0x31002000");
      sim_hw_parse (sd, "/pal@0x31000000 > int int2 /glue@0x31002000");
      sim_hw_parse (sd, "/glue@0x31002000 > int0 int3 /glue@0x31002000");
      sim_hw_parse (sd, "/glue@0x31002000 > int1 int3 /glue@0x31002000");
      sim_hw_parse (sd, "/glue@0x31002000 > int2 int3 /glue@0x31002000");
      
      /* REAL: The PAL wired up to the real interrupt controller */
      sim_hw_parse (sd, "/pal@0x31000000 > countdown irq-0 /mn103int");
      sim_hw_parse (sd, "/pal@0x31000000 > timer irq-1 /mn103int");
      sim_hw_parse (sd, "/pal@0x31000000 > int irq-2 /mn103int");
      
      /* 8 and 16 bit timers */
      sim_hw_parse (sd, "/mn103tim@0x34001000/reg 0x34001000 36 0x34001080 100 0x34004000 16");

      /* Hook timer interrupts up to interrupt controller */
      sim_hw_parse (sd, "/mn103tim > timer-0-underflow timer-0-underflow /mn103int");
      sim_hw_parse (sd, "/mn103tim > timer-1-underflow timer-1-underflow /mn103int");
      sim_hw_parse (sd, "/mn103tim > timer-2-underflow timer-2-underflow /mn103int");
      sim_hw_parse (sd, "/mn103tim > timer-3-underflow timer-3-underflow /mn103int");
      sim_hw_parse (sd, "/mn103tim > timer-4-underflow timer-4-underflow /mn103int");
      sim_hw_parse (sd, "/mn103tim > timer-5-underflow timer-5-underflow /mn103int");
      sim_hw_parse (sd, "/mn103tim > timer-6-underflow timer-6-underflow /mn103int");
      sim_hw_parse (sd, "/mn103tim > timer-6-compare-a timer-6-compare-a /mn103int");
      sim_hw_parse (sd, "/mn103tim > timer-6-compare-b timer-6-compare-b /mn103int");
      
      
      /* Serial devices 0,1,2 */
      sim_hw_parse (sd, "/mn103ser@0x34000800/reg 0x34000800 48");
      sim_hw_parse (sd, "/mn103ser@0x34000800/poll? true");
      
      /* Hook serial interrupts up to interrupt controller */
      sim_hw_parse (sd, "/mn103ser > serial-0-receive serial-0-receive /mn103int");
      sim_hw_parse (sd, "/mn103ser > serial-0-transmit serial-0-transmit /mn103int");
      sim_hw_parse (sd, "/mn103ser > serial-1-receive serial-1-receive /mn103int");
      sim_hw_parse (sd, "/mn103ser > serial-1-transmit serial-1-transmit /mn103int");
      sim_hw_parse (sd, "/mn103ser > serial-2-receive serial-2-receive /mn103int");
      sim_hw_parse (sd, "/mn103ser > serial-2-transmit serial-2-transmit /mn103int");
      
      sim_hw_parse (sd, "/mn103iop@0x36008000/reg 0x36008000 8 0x36008020 8 0x36008040 0xc 0x36008060 8 0x36008080 8");

      /* Memory control registers */
      sim_do_command (sd, "memory region 0x32000020,0x30");
      /* Cache control register */
      sim_do_command (sd, "memory region 0x20000070,0x4");
      /* Cache purge regions */
      sim_do_command (sd, "memory region 0x28400000,0x800");
      sim_do_command (sd, "memory region 0x28401000,0x800");
      /* DMA registers */
      sim_do_command (sd, "memory region 0x32000100,0xF");
      sim_do_command (sd, "memory region 0x32000200,0xF");
      sim_do_command (sd, "memory region 0x32000400,0xF");
      sim_do_command (sd, "memory region 0x32000800,0xF");
    }
  else
    {
      if (board != NULL)
        {
	  sim_io_eprintf (sd, "Error: Board `%s' unknown.\n", board);
          return 0;
	}
    }
  
  

  /* check for/establish the a reference program image */
  if (sim_analyze_program (sd,
			   (STATE_PROG_ARGV (sd) != NULL
			    ? *STATE_PROG_ARGV (sd)
			    : NULL),
			   abfd) != SIM_RC_OK)
    {
      sim_module_uninstall (sd);
      return 0;
    }

  /* establish any remaining configuration options */
  if (sim_config (sd) != SIM_RC_OK)
    {
      sim_module_uninstall (sd);
      return 0;
    }

  if (sim_post_argv_init (sd) != SIM_RC_OK)
    {
      /* Uninstall the modules to avoid memory leaks,
	 file descriptor leaks, etc.  */
      sim_module_uninstall (sd);
      return 0;
    }


  /* set machine specific configuration */
/*   STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT */
/* 			     | PSW_CY | PSW_OV | PSW_S | PSW_Z); */

  /* CPU specific initialization.  */
  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
    {
      SIM_CPU *cpu = STATE_CPU (sd, i);

      CPU_PC_FETCH (cpu) = mn10300_pc_get;
      CPU_PC_STORE (cpu) = mn10300_pc_set;
    }

  return sd;
}
Exemple #7
0
SIM_DESC
sim_open (SIM_OPEN_KIND kind, host_callback *callback,
	  bfd *abfd, char * const *argv)
{
  int i;
  SIM_DESC sd;
  sim_cpu *cpu;

  sd = sim_state_alloc (kind, callback);

  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);

  /* The cpu data is kept in a separately allocated chunk of memory.  */
  if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  cpu = STATE_CPU (sd, 0);

  cpu_initialize (sd, cpu);

  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* The parser will print an error message for us, so we silently return.  */
  if (sim_parse_args (sd, argv) != SIM_RC_OK)
    {
      /* Uninstall the modules to avoid memory leaks,
         file descriptor leaks, etc.  */
      free_state (sd);
      return 0;
    }

  /* Check for/establish the a reference program image.  */
  if (sim_analyze_program (sd,
			   (STATE_PROG_ARGV (sd) != NULL
			    ? *STATE_PROG_ARGV (sd)
			    : NULL), abfd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  /* Establish any remaining configuration options.  */
  if (sim_config (sd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }

  if (sim_post_argv_init (sd) != SIM_RC_OK)
    {
      /* Uninstall the modules to avoid memory leaks,
         file descriptor leaks, etc.  */
      free_state (sd);
      return 0;
    }
  if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK)
    {
      free_state (sd);
      return 0;
    }      

  /* CPU specific initialization.  */
  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
    {
      SIM_CPU *cpu = STATE_CPU (sd, i);

      CPU_REG_FETCH (cpu) = m68hc11_reg_fetch;
      CPU_REG_STORE (cpu) = m68hc11_reg_store;
      CPU_PC_FETCH (cpu) = m68hc11_pc_get;
      CPU_PC_STORE (cpu) = m68hc11_pc_set;
    }

  return sd;
}