예제 #1
0
파일: cgen-run.c 프로젝트: ChrisG0x20/gdb
static void
engine_run_n (SIM_DESC sd, int next_cpu_nr, int nr_cpus, int max_insns, int fast_p)
{
  int i;
  ENGINE_FN *engine_fns[MAX_NR_PROCESSORS];

  for (i = 0; i < nr_cpus; ++i)
    {
      SIM_CPU *cpu = STATE_CPU (sd, i);

      engine_fns[i] = fast_p ? CPU_FAST_ENGINE_FN (cpu) : CPU_FULL_ENGINE_FN (cpu);
      prime_cpu (cpu, max_insns);
    }

  while (1)
    {
      SIM_ENGINE_PREFIX_HOOK (sd);

      /* FIXME: proper cycling of all of them, blah blah blah.  */
      while (next_cpu_nr != nr_cpus)
	{
	  SIM_CPU *cpu = STATE_CPU (sd, next_cpu_nr);

	  (* engine_fns[next_cpu_nr]) (cpu);
	  ++next_cpu_nr;
	}

      SIM_ENGINE_POSTFIX_HOOK (sd);

      /* process any events */
      if (sim_events_tick (sd))
	sim_events_process (sd);
    }
}
예제 #2
0
int
is_condition_ok (SIM_DESC sd,
		 address_word cia,
		 int cond)
{
  switch (cond)
    {
    case 0x0:
      return 1;
    case 0x1:
      return PSW_VAL(PSW_F0);
    case 0x2:
      return !PSW_VAL(PSW_F0);
    case 0x3:
      return PSW_VAL(PSW_F1);
    case 0x4:
      return !PSW_VAL(PSW_F1);
    case 0x5:
      return PSW_VAL(PSW_F0) && PSW_VAL(PSW_F1);
    case 0x6:
      return PSW_VAL(PSW_F0) && !PSW_VAL(PSW_F1);
    case 0x7:
      sim_engine_abort (sd, STATE_CPU (sd, 0), cia,
			"is_condition_ok - bad instruction condition bits");
      return 0;
    default:
      sim_engine_abort (sd, STATE_CPU (sd, 0), cia,
			"internal error - is_condition_ok - bad switch");
      return -1;
    }
}
예제 #3
0
파일: sim-cpu.c 프로젝트: gygy/asuswrt
void
sim_cpu_free_all (SIM_DESC sd)
{
  int c;

  for (c = 0; c < MAX_NR_PROCESSORS; ++c)
    if (STATE_CPU (sd, c))
      sim_cpu_free (STATE_CPU (sd, c));
}
예제 #4
0
static void
attach_bfin_cec_regs (struct hw *me, struct bfin_cec *cec)
{
  address_word attach_address;
  int attach_space;
  unsigned attach_size;
  reg_property_spec reg;

  if (hw_find_property (me, "reg") == NULL)
    hw_abort (me, "Missing \"reg\" property");

  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
    hw_abort (me, "\"reg\" property must contain three addr/size entries");

  hw_unit_address_to_attach_address (hw_parent (me),
				     &reg.address,
				     &attach_space, &attach_address, me);
  hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);

  if (attach_size != BFIN_COREMMR_CEC_SIZE)
    hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_CEC_SIZE);

  hw_attach_address (hw_parent (me),
		     0, attach_space, attach_address, attach_size, me);

  cec->base = attach_address;
  /* XXX: should take from the device tree.  */
  cec->cpu = STATE_CPU (hw_system (me), 0);
  cec->me = me;
}
예제 #5
0
/* Get the memory bank parameters by looking at the global symbols
   defined by the linker.  */
static int
sim_get_bank_parameters (SIM_DESC sd)
{
  sim_cpu *cpu;
  unsigned size;
  bfd_vma addr;

  cpu = STATE_CPU (sd, 0);

  addr = trace_sym_value (sd, BFD_M68HC11_BANK_START_NAME);
  if (addr != -1)
    cpu->bank_start = addr;

  size = trace_sym_value (sd, BFD_M68HC11_BANK_SIZE_NAME);
  if (size == -1)
    size = 0;

  addr = trace_sym_value (sd, BFD_M68HC11_BANK_VIRTUAL_NAME);
  if (addr != -1)
    cpu->bank_virtual = addr;

  cpu->bank_end = cpu->bank_start + size;
  cpu->bank_shift = 0;
  for (; size > 1; size >>= 1)
    cpu->bank_shift++;

  return 0;
}
static void
m68hc11sio_info (struct hw *me)
{
  SIM_DESC sd;
  uint16 base = 0;
  sim_cpu *cpu;
  struct m68hc11sio *controller;
  uint8 val;
  long clock_cycle;
  
  sd = hw_system (me);
  cpu = STATE_CPU (sd, 0);
  controller = hw_data (me);
  
  sim_io_printf (sd, "M68HC11 SIO:\n");

  base = cpu_get_io_base (cpu);

  val  = cpu->ios[M6811_BAUD];
  print_io_byte (sd, "BAUD ", baud_desc, val, base + M6811_BAUD);
  sim_io_printf (sd, " (%ld baud)\n",
                 (cpu->cpu_frequency / 4) / controller->baud_cycle);

  val = cpu->ios[M6811_SCCR1];
  print_io_byte (sd, "SCCR1", sccr1_desc, val, base + M6811_SCCR1);
  sim_io_printf (sd, "  (%d bits) (%dN1)\n",
                 controller->data_length, controller->data_length - 2);

  val = cpu->ios[M6811_SCCR2];
  print_io_byte (sd, "SCCR2", sccr2_desc, val, base + M6811_SCCR2);
  sim_io_printf (sd, "\n");

  val = cpu->ios[M6811_SCSR];
  print_io_byte (sd, "SCSR ", scsr_desc, val, base + M6811_SCSR);
  sim_io_printf (sd, "\n");

  clock_cycle = controller->data_length * controller->baud_cycle;
  
  if (controller->tx_poll_event)
    {
      signed64 t;
      int n;

      t = hw_event_remain_time (me, controller->tx_poll_event);
      n = (clock_cycle - t) / controller->baud_cycle;
      n = controller->data_length - n;
      sim_io_printf (sd, "  Transmit finished in %s (%d bit%s)\n",
		     cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE),
                     n, (n > 1 ? "s" : ""));
    }
  if (controller->rx_poll_event)
    {
      signed64 t;

      t = hw_event_remain_time (me, controller->rx_poll_event);
      sim_io_printf (sd, "  Receive finished in %s\n",
		     cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE));
    }
  
}
예제 #7
0
do_syscall ()
{

    /* We use this for simulated system calls; we may need to change
       it to a reserved instruction if we conflict with uses at
       Matsushita.  */
    int save_errno = errno;
    errno = 0;

    /* Registers passed to trap 0 */

    /* Function number.  */
#define FUNC   (State.regs[0])

    /* Parameters.  */
#define PARM1   (State.regs[1])
#define PARM2   (load_word (State.regs[REG_SP] + 12))
#define PARM3   (load_word (State.regs[REG_SP] + 16))

    /* Registers set by trap 0 */

#define RETVAL State.regs[0]	/* return value */
#define RETERR State.regs[1]	/* return error code */

    /* Turn a pointer in a register into a pointer into real memory. */
#define MEMPTR(x) (State.mem + x)

    if ( FUNC == TARGET_SYS_exit )
    {
        /* EXIT - caller can look in PARM1 to work out the reason */
        if (PARM1 == 0xdead)
            State.exception = SIGABRT;
        else
        {
            sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
                             sim_exited, PARM1);
            State.exception = SIGQUIT;
        }
        State.exited = 1;
    }
    else
    {
        CB_SYSCALL syscall;

        CB_SYSCALL_INIT (&syscall);
        syscall.arg1 = PARM1;
        syscall.arg2 = PARM2;
        syscall.arg3 = PARM3;
        syscall.func = FUNC;
        syscall.p1 = (PTR) simulator;
        syscall.read_mem = syscall_read_mem;
        syscall.write_mem = syscall_write_mem;
        cb_syscall (STATE_CALLBACK (simulator), &syscall);
        RETERR = syscall.errcode;
        RETVAL = syscall.result;
    }


    errno = save_errno;
}
예제 #8
0
void
sim_model_set (SIM_DESC sd, sim_cpu *cpu, const MODEL *model)
{
  if (! cpu)
    {
      int c;

      for (c = 0; c < MAX_NR_PROCESSORS; ++c)
	if (STATE_CPU (sd, c))
	  model_set (STATE_CPU (sd, c), model);
    }
  else
    {
      model_set (cpu, model);
    }
}
예제 #9
0
void
sim_engine_run (SIM_DESC sd, int next_cpu_nr, int nr_cpus,
		int signal)
{
  micromips_m32_instruction_word instruction_0;
  sim_cpu *cpu = STATE_CPU (sd, next_cpu_nr);
  micromips32_instruction_address cia = CPU_PC_GET (cpu);
  sd->isa_mode = ISA_MODE_MIPS32;

  while (1)
    {
      micromips32_instruction_address nia;

      /* Allow us to switch back from MIPS32 to microMIPS
	 This covers two cases:
	 1. Setting the correct isa mode based on the start address
	 from the elf header.
	 2. Setting the correct isa mode after a MIPS32 jump or branch
	 instruction.  */
      if ((sd->isa_mode == ISA_MODE_MIPS32)
	  && ((cia & 0x1) == ISA_MODE_MICROMIPS))
	{
	  sd->isa_mode = ISA_MODE_MICROMIPS;
	  cia = cia & ~0x1;
	}

#if defined (ENGINE_ISSUE_PREFIX_HOOK)
      ENGINE_ISSUE_PREFIX_HOOK ();
#endif
      switch (sd->isa_mode)
	{
	case ISA_MODE_MICROMIPS:
	  nia =
	    micromips_instruction_decode (sd, cpu, cia,
					  MICROMIPS_DELAYSLOT_SIZE_ANY);
	  break;
	case ISA_MODE_MIPS32:
	  instruction_0 = IMEM32 (cia);
	  nia = micromips_m32_idecode_issue (sd, instruction_0, cia);
	  break;
	default:
	  nia = NULL_CIA;
	}

#if defined (ENGINE_ISSUE_POSTFIX_HOOK)
      ENGINE_ISSUE_POSTFIX_HOOK ();
#endif

      /* Update the instruction address */
      cia = nia;

      /* process any events */
      if (sim_events_tick (sd))
	{
	  CPU_PC_SET (cpu, cia);
	  sim_events_process (sd);
	  cia = CPU_PC_GET (cpu);
	}
    }
}
예제 #10
0
void
sim_do_command (SIM_DESC sd, char *cmd)
{
  char *mm_cmd = "memory-map";
  char *int_cmd = "interrupt";
  sim_cpu *cpu;

  cpu = STATE_CPU (sd, 0);
  /* Commands available from GDB:   */
  if (sim_args_command (sd, cmd) != SIM_RC_OK)
    {
      if (strncmp (cmd, "info", sizeof ("info") - 1) == 0)
	sim_get_info (sd, &cmd[4]);
      else if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
	sim_io_eprintf (sd,
			"`memory-map' command replaced by `sim memory'\n");
      else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
	sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
      else
	sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
    }

  /* If the architecture changed, re-configure.  */
  if (STATE_ARCHITECTURE (sd) != cpu->cpu_configured_arch)
    sim_hw_configure (sd);
}
예제 #11
0
static void
parse_cache_option (SIM_DESC sd, char *arg, char *cache_name, int is_data_cache)
{
  int i;
  address_word ways = 0, sets = 0, linesize = 0;
  if (arg != NULL)
    {
      char *chp = arg;
      /* parse the arguments */
      chp = parse_size (chp, &ways);
      ways = check_pow2 (ways, "WAYS", cache_name, sd);
      if (*chp == ',')
	{
	  chp = parse_size (chp + 1, &sets);
	  sets = check_pow2 (sets, "SETS", cache_name, sd);
	  if (*chp == ',')
	    {
	      chp = parse_size (chp + 1, &linesize);
	      linesize = check_pow2 (linesize, "LINESIZE", cache_name, sd);
	    }
	}
    }
  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
    {
      SIM_CPU *current_cpu = STATE_CPU (sd, i);
      FRV_CACHE *cache = is_data_cache ? CPU_DATA_CACHE (current_cpu)
	                               : CPU_INSN_CACHE (current_cpu);
      cache->ways = ways;
      cache->sets = sets;
      cache->line_size = linesize;
      frv_cache_init (current_cpu, cache);
    }
}
예제 #12
0
void
sim_board_reset (SIM_DESC sd)
{
  struct hw *hw_cpu;
  sim_cpu *cpu;
  const struct bfd_arch_info *arch;
  const char *cpu_type;

  cpu = STATE_CPU (sd, 0);
  arch = STATE_ARCHITECTURE (sd);

  /*  hw_cpu = sim_hw_parse (sd, "/"); */
  if (arch->arch == bfd_arch_m68hc11)
    {
      cpu->cpu_type = CPU_M6811;
      cpu_type = "/m68hc11";
    }
  else
    {
      cpu->cpu_type = CPU_M6812;
      cpu_type = "/m68hc12";
    }
  
  hw_cpu = sim_hw_parse (sd, cpu_type);
  if (hw_cpu == 0)
    {
      sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type);
      return;
    }

  cpu_reset (cpu);
  hw_port_event (hw_cpu, 3, 0);
  cpu_restart (cpu);
}
예제 #13
0
void
cgen_init (SIM_DESC sd)
{
  int i, c;

  /* If no profiling or tracing has been enabled, run in fast mode.  */
  {
    int run_fast_p = 1;

    for (c = 0; c < MAX_NR_PROCESSORS; ++c)
      {
	SIM_CPU *cpu = STATE_CPU (sd, c);

	for (i = 0; i < MAX_PROFILE_VALUES; ++i)
	  if (CPU_PROFILE_FLAGS (cpu) [i])
	    {
	      run_fast_p = 0;
	      break;
	    }
	for (i = 0; i < MAX_TRACE_VALUES; ++i)
	  if (CPU_TRACE_FLAGS (cpu) [i])
	    {
	      run_fast_p = 0;
	      break;
	    }
	if (! run_fast_p)
	  break;
      }
    STATE_RUN_FAST_P (sd) = run_fast_p;
  }
}
예제 #14
0
SIM_RC
sim_pre_argv_init (SIM_DESC sd, const char *myname)
{
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  SIM_ASSERT (STATE_MODULES (sd) == NULL);

  STATE_MY_NAME (sd) = lbasename (myname);

  /* Set the cpu names to default values.  */
  {
    int i;
    for (i = 0; i < MAX_NR_PROCESSORS; ++i)
      {
	char *name;
	if (asprintf (&name, "cpu%d", i) < 0)
	  return SIM_RC_FAIL;
	CPU_NAME (STATE_CPU (sd, i)) = name;
      }
  }

  sim_config_default (sd);

  /* Install all configured in modules.  */
  if (sim_module_install (sd) != SIM_RC_OK)
    return SIM_RC_FAIL;

  return SIM_RC_OK;
}
void
sim_resume (SIM_DESC sd,
	    int step,
	    int siggnal)
{
  sim_engine *engine = STATE_ENGINE (sd);
  jmp_buf buf;
  int jmpval;

  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);

  /* we only want to be single stepping the simulator once */
  if (engine->stepper != NULL)
    {
      sim_events_deschedule (sd, engine->stepper);
      engine->stepper = NULL;
    }
  if (step)
    engine->stepper = sim_events_schedule (sd, 1, has_stepped, sd);

  sim_module_resume (sd);

  /* run/resume the simulator */
  engine->jmpbuf = &buf;
  jmpval = setjmp (buf);
  if (jmpval == sim_engine_start_jmpval
      || jmpval == sim_engine_restart_jmpval)
    {
      int last_cpu_nr = sim_engine_last_cpu_nr (sd);
      int next_cpu_nr = sim_engine_next_cpu_nr (sd);
      int nr_cpus = sim_engine_nr_cpus (sd);
      int sig_to_deliver;

      sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
      if (next_cpu_nr >= nr_cpus)
	next_cpu_nr = 0;

      /* Only deliver the SIGGNAL [sic] the first time through - don't
         re-deliver any SIGGNAL during a restart.  NOTE: A new local
         variable is used to avoid problems with the automatic
         variable ``siggnal'' being trashed by a long jump.  */
      if (jmpval == sim_engine_start_jmpval)
	sig_to_deliver = siggnal;
      else
	sig_to_deliver = 0;

#ifdef SIM_CPU_EXCEPTION_RESUME
      {
	sim_cpu* cpu = STATE_CPU (sd, next_cpu_nr);
	SIM_CPU_EXCEPTION_RESUME(sd, cpu, sig_to_deliver);
      }
#endif

      sim_engine_run (sd, next_cpu_nr, nr_cpus, sig_to_deliver);
    }
  engine->jmpbuf = NULL;

  sim_module_suspend (sd);
}
예제 #16
0
syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
                   unsigned long taddr, const char *buf, int bytes)
{
    SIM_DESC sd = (SIM_DESC) sc->p1;
    sim_cpu *cpu = STATE_CPU(sd, 0);

    return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
}
예제 #17
0
int
sim_store_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
{
  SIM_CPU *cpu = STATE_CPU (sd, 0);

  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  return (* CPU_REG_STORE (cpu)) (cpu, rn, buf, length);
}
예제 #18
0
파일: sim-engine.c 프로젝트: ChrisG0x20/gdb
int
sim_engine_last_cpu_nr (SIM_DESC sd)
{
  sim_engine *engine = STATE_ENGINE (sd);
  if (engine->last_cpu != NULL)
    return engine->last_cpu - STATE_CPU (sd, 0);
  else
    return MAX_NR_PROCESSORS;
}
예제 #19
0
void
m68hc11sio_tx_poll (struct hw *me, void *data)
{
  SIM_DESC sd;
  struct m68hc11sio *controller;
  sim_cpu *cpu;
  
  controller = hw_data (me);
  sd         = hw_system (me);
  cpu        = STATE_CPU (sd, 0);

  cpu->ios[M6811_SCSR] |= M6811_TDRE;
  cpu->ios[M6811_SCSR] |= M6811_TC;
  
  /* Transmitter is enabled and we have something to send.  */
  if ((cpu->ios[M6811_SCCR2] & M6811_TE) && controller->tx_has_char)
    {
      cpu->ios[M6811_SCSR] &= ~M6811_TDRE;
      cpu->ios[M6811_SCSR] &= ~M6811_TC;
      controller->tx_has_char = 0;
      switch (controller->backend)
        {
        case sio_tcp:
          dv_sockser_write (sd, controller->tx_char);
          break;

        case sio_stdio:
          sim_io_write_stdout (sd, &controller->tx_char, 1);
          sim_io_flush_stdout (sd);
          break;

        default:
          break;
        }
    }

  if (controller->tx_poll_event)
    {
      hw_event_queue_deschedule (me, controller->tx_poll_event);
      controller->tx_poll_event = 0;
    }
  
  if ((cpu->ios[M6811_SCCR2] & M6811_TE)
      && ((cpu->ios[M6811_SCSR] & M6811_TC) == 0))
    {
      unsigned long clock_cycle;
      
      /* Compute CPU clock cycles to wait for the next character.  */
      clock_cycle = controller->data_length * controller->baud_cycle;

      controller->tx_poll_event = hw_event_queue_schedule (me, clock_cycle,
                                                           m68hc11sio_tx_poll,
                                                           NULL);
    }

  interrupts_update_pending (&cpu->cpu_interrupts);
}
예제 #20
0
파일: sim-cpu.c 프로젝트: gygy/asuswrt
SIM_RC
sim_cpu_alloc_all (SIM_DESC sd, int ncpus, int extra_bytes)
{
  int c;

  for (c = 0; c < ncpus; ++c)
    STATE_CPU (sd, c) = sim_cpu_alloc (sd, extra_bytes);
  return SIM_RC_OK;
}
예제 #21
0
파일: sim-engine.c 프로젝트: ChrisG0x20/gdb
int
sim_engine_next_cpu_nr (SIM_DESC sd)
{
  sim_engine *engine = STATE_ENGINE (sd);
  if (engine->next_cpu != NULL)
    return engine->next_cpu - STATE_CPU (sd, 0);
  else
    return sim_engine_last_cpu_nr (sd) + 1;
}
예제 #22
0
int
sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
{
  uint16 val;
  sim_cpu *cpu;

  cpu = STATE_CPU (sd, 0);

  val = *memory++;
  if (length == 2)
    val = (val << 8) | *memory;

  switch (rn)
    {
    case D_REGNUM:
      cpu_set_d (cpu, val);
      break;

    case A_REGNUM:
      cpu_set_a (cpu, val);
      return 1;

    case B_REGNUM:
      cpu_set_b (cpu, val);
      return 1;

    case X_REGNUM:
      cpu_set_x (cpu, val);
      break;

    case Y_REGNUM:
      cpu_set_y (cpu, val);
      break;

    case SP_REGNUM:
      cpu_set_sp (cpu, val);
      break;

    case PC_REGNUM:
      cpu_set_pc (cpu, val);
      break;

    case PSW_REGNUM:
      cpu_set_ccr (cpu, val);
      return 1;

    case PAGE_REGNUM:
      cpu_set_page (cpu, val);
      return 1;

    default:
      break;
    }

  return 2;
}
예제 #23
0
int
is_wrong_slot (SIM_DESC sd,
	       address_word cia,
	       itable_index index)
{
  switch (STATE_CPU (sd, 0)->unit)
    {
    case memory_unit:
      return !itable[index].option[itable_option_mu];
    case integer_unit:
      return !itable[index].option[itable_option_iu];
    case any_unit:
      return 0;
    default:
      sim_engine_abort (sd, STATE_CPU (sd, 0), cia,
			"internal error - is_wrong_slot - bad switch");
      return -1;
    }
}
예제 #24
0
SIM_RC
sim_post_argv_init (SIM_DESC sd)
{
  int i;
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  SIM_ASSERT (STATE_MODULES (sd) != NULL);

  /* Set the cpu->state backlinks for each cpu.  */
  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
    {
      CPU_STATE (STATE_CPU (sd, i)) = sd;
      CPU_INDEX (STATE_CPU (sd, i)) = i;
    }

  if (sim_module_init (sd) != SIM_RC_OK)
    return SIM_RC_FAIL;

  return SIM_RC_OK;
}
예제 #25
0
static int
sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
{
  sim_cpu *cpu;
  int elf_flags = 0;

  cpu = STATE_CPU (sd, 0);

  if (abfd != NULL)
    {
      asection *s;

      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
        elf_flags = elf_elfheader (abfd)->e_flags;

      cpu->cpu_elf_start = bfd_get_start_address (abfd);
      /* See if any section sets the reset address */
      cpu->cpu_use_elf_start = 1;
      for (s = abfd->sections; s && cpu->cpu_use_elf_start; s = s->next) 
        {
          if (s->flags & SEC_LOAD)
            {
              bfd_size_type size;

              size = bfd_get_section_size (s);
              if (size > 0)
                {
                  bfd_vma lma;

                  if (STATE_LOAD_AT_LMA_P (sd))
                    lma = bfd_section_lma (abfd, s);
                  else
                    lma = bfd_section_vma (abfd, s);

                  if (lma <= 0xFFFE && lma+size >= 0x10000)
                    cpu->cpu_use_elf_start = 0;
                }
            }
        }

      if (elf_flags & E_M68HC12_BANKS)
        {
          if (sim_get_bank_parameters (sd, abfd) != 0)
            sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
        }
    }

  if (!sim_hw_configure (sd))
    return SIM_RC_FAIL;

  /* reset all state information */
  sim_board_reset (sd);

  return SIM_RC_OK;
}
예제 #26
0
static SIM_RC
sim_model_init (SIM_DESC sd)
{
  SIM_CPU *cpu;

  /* If both cpu model and state architecture are set, ensure they're
     compatible.  If only one is set, set the other.  If neither are set,
     use the default model.  STATE_ARCHITECTURE is the bfd_arch_info data
     for the selected "mach" (bfd terminology).  */

  /* Only check cpu 0.  STATE_ARCHITECTURE is for that one only.  */
  /* ??? At present this only supports homogeneous multiprocessors.  */
  cpu = STATE_CPU (sd, 0);

  if (! STATE_ARCHITECTURE (sd)
      && ! CPU_MACH (cpu))
    {
      /* Set the default model.  */
      const MODEL *model = sim_model_lookup (WITH_DEFAULT_MODEL);
      sim_model_set (sd, NULL, model);
    }

  if (STATE_ARCHITECTURE (sd)
      && CPU_MACH (cpu))
    {
      if (strcmp (STATE_ARCHITECTURE (sd)->printable_name,
		  MACH_BFD_NAME (CPU_MACH (cpu))) != 0)
	{
	  sim_io_eprintf (sd, "invalid model `%s' for `%s'\n",
			  MODEL_NAME (CPU_MODEL (cpu)),
			  STATE_ARCHITECTURE (sd)->printable_name);
	  return SIM_RC_FAIL;
	}
    }
  else if (STATE_ARCHITECTURE (sd))
    {
      /* Use the default model for the selected machine.
	 The default model is the first one in the list.  */
      const MACH *mach = sim_mach_lookup_bfd_name (STATE_ARCHITECTURE (sd)->printable_name);

      if (mach == NULL)
	{
	  sim_io_eprintf (sd, "unsupported machine `%s'\n",
			  STATE_ARCHITECTURE (sd)->printable_name);
	  return SIM_RC_FAIL;
	}
      sim_model_set (sd, NULL, MACH_MODELS (mach));
    }
  else
    {
      STATE_ARCHITECTURE (sd) = bfd_scan_arch (MACH_BFD_NAME (CPU_MACH (cpu)));
    }

  return SIM_RC_OK;
}
예제 #27
0
void
scache_flush (SIM_DESC sd)
{
  int c;

  for (c = 0; c < MAX_NR_PROCESSORS; ++c)
    {
      SIM_CPU *cpu = STATE_CPU (sd, c);
      scache_flush_cpu (cpu);
    }
}
예제 #28
0
/* Get the memory bank parameters by looking at the global symbols
   defined by the linker.  */
static int
sim_get_bank_parameters (SIM_DESC sd, bfd* abfd)
{
  sim_cpu *cpu;
  long symsize;
  long symbol_count, i;
  unsigned size;
  asymbol** asymbols;
  asymbol** current;

  cpu = STATE_CPU (sd, 0);

  symsize = bfd_get_symtab_upper_bound (abfd);
  if (symsize < 0)
    {
      sim_io_eprintf (sd, "Cannot read symbols of program");
      return 0;
    }
  asymbols = (asymbol **) xmalloc (symsize);
  symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
  if (symbol_count < 0)
    {
      sim_io_eprintf (sd, "Cannot read symbols of program");
      return 0;
    }

  size = 0;
  for (i = 0, current = asymbols; i < symbol_count; i++, current++)
    {
      const char* name = bfd_asymbol_name (*current);

      if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0)
        {
          cpu->bank_start = bfd_asymbol_value (*current);
        }
      else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0)
        {
          size = bfd_asymbol_value (*current);
        }
      else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0)
        {
          cpu->bank_virtual = bfd_asymbol_value (*current);
        }
    }
  free (asymbols);

  cpu->bank_end = cpu->bank_start + size;
  cpu->bank_shift = 0;
  for (; size > 1; size >>= 1)
    cpu->bank_shift++;

  return 0;
}
static unsigned
m68hc11eepr_io_read_buffer (struct hw *me,
			    void *dest,
			    int space,
			    unsigned_word base,
			    unsigned nr_bytes)
{
  SIM_DESC sd;
  struct m68hc11eepr *controller;
  sim_cpu *cpu;
  
  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));

  sd         = hw_system (me);
  controller = hw_data (me);
  cpu        = STATE_CPU (sd, 0);

  if (space == io_map)
    {
      unsigned cnt = 0;
      
      while (nr_bytes != 0)
        {
          switch (base)
            {
            case M6811_PPROG:
            case M6811_CONFIG:
              *((uint8*) dest) = cpu->ios[base];
              break;

            default:
              hw_abort (me, "reading wrong register 0x%04x", base);
            }
          dest = (uint8*) (dest) + 1;
          base++;
          nr_bytes--;
          cnt++;
        }
      return cnt;
    }

  /* In theory, we can't read the EEPROM when it's being programmed.  */
  if ((cpu->ios[M6811_PPROG] & M6811_EELAT) != 0
      && cpu_is_running (cpu))
    {
      sim_memory_error (cpu, SIM_SIGBUS, base,
			"EEprom not configured for reading");
    }

  base = base - controller->base_address;
  memcpy (dest, &controller->eeprom[base], nr_bytes);
  return nr_bytes;
}
예제 #30
0
static unsigned
m68hc11tim_io_read_buffer (struct hw *me,
                           void *dest,
                           int space,
                           unsigned_word base,
                           unsigned nr_bytes)
{
  SIM_DESC sd;
  struct m68hc11tim *controller;
  sim_cpu *cpu;
  unsigned8 val;
  unsigned cnt = 0;
  
  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));

  sd  = hw_system (me);
  cpu = STATE_CPU (sd, 0);
  controller = hw_data (me);

  while (nr_bytes)
    {
      switch (base)
        {
          /* The cpu_absolute_cycle is updated after each instruction.
             Reading in a 16-bit register will be split in two accesses
             but this will be atomic within the simulator.  */
        case M6811_TCTN_H:
          val = (uint8) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
                         / (controller->clock_prescaler * 256));
          break;

        case M6811_TCTN_L:
          val = (uint8) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
                         / controller->clock_prescaler);
          break;

        default:
          val = cpu->ios[base];
          break;
        }
      *((unsigned8*) dest) = val;
      dest = (char*) dest + 1;
      base++;
      nr_bytes--;
      cnt++;
    }
  return cnt;
}