OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0/] [or1ksim/] [sim-cmd.c] - Diff between revs 1446 and 1471

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 1446 Rev 1471
Line 50... Line 50...
#include "debug.h"
#include "debug.h"
#include "trace.h"
#include "trace.h"
#include "stats.h"
#include "stats.h"
#include "cuc.h"
#include "cuc.h"
#include "gdbcomm.h"
#include "gdbcomm.h"
 
#include "sched.h"
 
 
/* FIXME: These *really* need to be cleaned up */
/* FIXME: These *really* need to be cleaned up */
#include "sprs.h"
#include "sprs.h"
#include "immu.h"
#include "immu.h"
#include "dmmu.h"
#include "dmmu.h"
#include "icache_model.h"
#include "icache_model.h"
#include "dcache_model.h"
#include "dcache_model.h"
#include "branch_predict.h"
#include "branch_predict.h"
 
 
 
/* The number of instructions to execute before droping into interactive mode */
 
static long long to_insn_num;
 
 
struct sim_stat {
struct sim_stat {
  void (*stat_func)(void *dat);
  void (*stat_func)(void *dat);
  void *dat;
  void *dat;
  struct sim_stat *next;
  struct sim_stat *next;
};
};
Line 103... Line 107...
    PRINTF("%08x %s\n", insn, disassembled);
    PRINTF("%08x %s\n", insn, disassembled);
    i += 4;
    i += 4;
  }
  }
}
}
 
 
 
/* Schedules the next job so that it will run after the next instruction */
 
static void sched_next_insn(void (*func)(void *))
 
{
 
  int32_t cycles = 1;
 
  struct sched_entry *cur = scheduler.job_queue;
 
 
 
  /* The cycles count of the jobs may go into negatives.  If this happens, func
 
   * will get called before the next instruction has executed. */
 
  while(cur && (cur->time < 0)) {
 
    cycles -= cur->time;
 
    cur = cur->next;
 
  }
 
 
 
  SCHED_ADD(func, NULL, cycles);
 
}
 
 
 
/* Scheduler job that drops us back into interactive mode after the next
 
 * instruction has executed */
 
void reenter_int(void *dat)
 
{
 
  if (!runtime.sim.hush) dumpreg();
 
  handle_sim_command();
 
}
 
 
static int sim_cmd_quit(int argc, char **argv) /* quit */
static int sim_cmd_quit(int argc, char **argv) /* quit */
{
{
  PRINTF ("\n");
  PRINTF ("\n");
  sim_done();
  sim_done();
  return 0;
  return 0;
Line 144... Line 172...
  return 0;
  return 0;
}
}
 
 
static int sim_cmd_trace(int argc, char **argv) /* trace */
static int sim_cmd_trace(int argc, char **argv) /* trace */
{
{
  runtime.sim.cont_run = 1;
  runtime.sim.hush = 0;
 
  sched_next_insn(reenter_int);
  return 1;
  return 1;
}
}
 
 
static int sim_cmd_dm(int argc, char **argv) /* dump memory */
static int sim_cmd_dm(int argc, char **argv) /* dump memory */
{
{
Line 267... Line 296...
  if(argc != 3) {
  if(argc != 3) {
    PRINTF("pr <register> <value>\n");
    PRINTF("pr <register> <value>\n");
    return 0;
    return 0;
  }
  }
  setsim_reg(strtoul(argv[1], NULL,0), strtoul(argv[2], NULL, 0));
  setsim_reg(strtoul(argv[1], NULL,0), strtoul(argv[2], NULL, 0));
 
#if DYNAMIC_EXECUTION
 
  PRINTF("WARNING: Patching registers may not work with the dynamic execution model\n");
 
#endif
  return 0;
  return 0;
}
}
 
 
static int sim_cmd_pc(int argc, char **argv) /* patch PC */
static int sim_cmd_pc(int argc, char **argv) /* patch PC */
{
{
 
#if DYNAMIC_EXECUTION
 
  PRINTF("Patching the pc in the dynamic execution model doesn't work\n");
 
#else
  if(argc != 2) {
  if(argc != 2) {
    PRINTF("pc <value>\n");
    PRINTF("pc <value>\n");
    return 0;
    return 0;
  }
  }
 
 
  cpu_state.pc = strtoul(argv[1], NULL, 0);
  cpu_state.pc = strtoul(argv[1], NULL, 0);
  pcnext = cpu_state.pc + 4;
  pcnext = cpu_state.pc + 4;
 
#endif
  return 0;
  return 0;
}
}
 
 
static int sim_cmd_breaks(int argc, char **argv) /* print breakpoints */
static int sim_cmd_breaks(int argc, char **argv) /* print breakpoints */
{
{
Line 357... Line 393...
    dumpmemory(cur->addr, cur->addr + 4, 1, 1);
    dumpmemory(cur->addr, cur->addr + 4, 1, 1);
  PRINTF("\n");
  PRINTF("\n");
  return 0;
  return 0;
}
}
 
 
 
/* Called when it is suspisous that runtime.sim.instructions has reached
 
 * to_insn_num */
 
void check_insn_exec(void *dat)
 
{
 
  if(runtime.cpu.instructions < to_insn_num) {
 
    /* Instruction count has not yet been reached, reschedule */
 
    SCHED_ADD(check_insn_exec, NULL, to_insn_num - runtime.cpu.instructions);
 
    return;
 
  }
 
  handle_sim_command();
 
}
 
 
 
void print_insn_exec(void *dat)
 
{
 
  dumpreg();
 
  if(runtime.cpu.instructions < to_insn_num) {
 
    /* Instruction count has not yet been reached, reschedule */
 
    sched_next_insn(print_insn_exec);
 
    return;
 
  }
 
  handle_sim_command();
 
}
 
 
static int sim_cmd_run(int argc, char **argv) /* run */
static int sim_cmd_run(int argc, char **argv) /* run */
{
{
 
  runtime.sim.hush = 0;
  if(argc >= 3) {
  if(argc >= 3) {
    if(!strcmp(argv[2], "hush"))
    if(!strcmp(argv[2], "hush"))
      runtime.sim.hush = 1;
      runtime.sim.hush = 1;
    else
 
      runtime.sim.hush = 0;
 
  }
  }
 
 
  if(argc >= 2)
  if(argc >= 2) {
    runtime.sim.cont_run = strtol(argv[1], NULL, 0);
    if((to_insn_num = strtol(argv[1], NULL, 0)) != -1) {
  else
      if(runtime.sim.hush) {
    runtime.sim.cont_run = 0;
        /* Schedule a job to run in to_insn_num cycles time since an instruction
 
         * may execute in only 1 cycle.  check_insn_exec will check if the right
 
         * number of instructions have been executed.  If not it will
 
         * reschedule.  */
 
        SCHED_ADD(check_insn_exec, NULL, to_insn_num);
 
      } else {
 
        /* The user wants to see the execution dumps.  Schedule a task to show
 
         * it to him after each cycle */
 
        sched_next_insn(print_insn_exec);
 
      }
 
      to_insn_num += runtime.cpu.instructions;
 
    } else {
 
      if(!runtime.sim.hush)
 
        sched_next_insn(print_insn_exec);
 
    }
 
  } else
 
    /* Run 0 instructions */
 
    return 0;
 
 
  return 1;
  return 1;
}
}
 
 
static int sim_cmd_stall(int argc, char **argv) /* Added by CZ 210801 */
static int sim_cmd_stall(int argc, char **argv) /* Added by CZ 210801 */
{
{
  set_stall_state (1);
  set_stall_state (1);
  runtime.sim.iprompt = 0;
  runtime.sim.iprompt = 0;
  runtime.sim.cont_run = -1;
 
  runtime.sim.hush = 1;
  runtime.sim.hush = 1;
  return 1;
  return 1;
}
}
 
 
static int sim_cmd_stats(int argc, char **argv) /* stats */
static int sim_cmd_stats(int argc, char **argv) /* stats */
Line 520... Line 595...
#else
#else
  char b2[500];
  char b2[500];
  static char prev_str[500] = { 0 };
  static char prev_str[500] = { 0 };
#endif
#endif
 
 
 
  /* Make sure that check_insn_exec is not left hanging in the scheduler (and
 
   * breaking the sim when the user doesn't want it to break). */
 
  SCHED_FIND_REMOVE(check_insn_exec, NULL);
 
  SCHED_FIND_REMOVE(print_insn_exec, NULL);
 
 
#ifdef HAVE_LIBREADLINE
#ifdef HAVE_LIBREADLINE
  initialize_readline (); /* Bind our completer. */
  initialize_readline (); /* Bind our completer. */
#endif
#endif
 
 
  for(;;) {
  for(;;) {
Line 593... Line 673...
        }
        }
      }
      }
 
 
      for(cur_cmd = sim_commands; cur_cmd->name; cur_cmd++) {
      for(cur_cmd = sim_commands; cur_cmd->name; cur_cmd++) {
        if(!strcmp(cur_cmd->name, argv[0])) {
        if(!strcmp(cur_cmd->name, argv[0])) {
          if(cur_cmd->cmd_handle(argc, argv))
          if(cur_cmd->cmd_handle(argc, argv)) {
 
            runtime.sim.iprompt = 0;
            return;
            return;
 
          }
          break;
          break;
        }
        }
      }
      }
 
 
      if(!cur_cmd->name)
      if(!cur_cmd->name)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.