示例#1
0
int exec(Memory entry_p)
{
  Instruction insn;
  unsigned long clk = 0;

  uint32_t cmod;

  if(signal(SIGINT, signal_on_sigint) == SIG_ERR) {
    err(EXIT_FAILURE, "signal SIGINT");
  }

  step_by_step = false;
  exec_finish = false;

  /* initialize internal variable */
  memory_is_fault = 0;
  memory_io_writeback = 0;
  instruction_prefetch_flush();

  /* setup system registers */
  PSR = 0;
  cmod = (PSR & PSR_CMOD_MASK);
  PCR = entry_p;
  next_PCR = 0xffffffff;
  KSPR = (Memory)STACK_DEFAULT;

#if !NO_DEBUG
  /* internal debug variable */
  traceback_next = 0;

  FLAGR.flags = 0x80000000;
  prev_FLAGR.flags = 0x80000000;

  for(unsigned int i = 0; i < breakp_next; i++) {
    NOTICE("Break point[%d]: 0x%08x\n", i, breakp[i]);
  }
#endif

  NOTICE("Execution Start: entry = 0x%08x\n", PCR);

  do {
    /* choose stack */
    if(cmod != (PSR & PSR_CMOD_MASK)) {
      SPR = !cmod ? USPR : KSPR;
    }
    cmod = (PSR & PSR_CMOD_MASK);

#if !NO_DEBUG
    /* break point check */
    for(unsigned int i = 0; i < breakp_next; i++) {
      if(PCR == breakp[i]) {
	step_by_step = true;
	break;
      }
    }
#endif

    /* instruction fetch */
    insn.value = instruction_fetch(PCR);

    if(memory_is_fault) {
      /* fault fetch */
      DEBUGINT("[FAULT] Instruction fetch: %08x\n", PCR);
      goto fault;
    }

#if !NO_DEBUG
    if(DEBUG || step_by_step) {
      puts("---");
      print_instruction(insn);
    }
#endif

    /* execution */
    insn_dispatch(insn);

  fault:
    if(memory_is_fault) {
      /* faulting memory access */
      interrupt_dispatch_nonmask(memory_is_fault);
      next_PCR = PCR;

      memory_io_writeback = 0;
      memory_is_fault = 0;
    }
    else if(memory_io_writeback) {
      /* sync io */
      io_store(memory_io_writeback);
      memory_io_writeback = 0;
    }

    /* writeback SP */
    if(cmod) {
      USPR = SPR;
    }
    else {
      KSPR = SPR;
    }

#if !NO_DEBUG
    if(step_by_step) {
      step_by_step_pause();
    }
    else {
      if(DEBUG && DEBUG_REG) { print_registers(); }
      if(DEBUG_TRACE) { print_traceback(); }
      if(DEBUG_STACK) { print_stack(SPR); }
      if(DEBUG_DPS) { dps_info(); }
    }
#endif

    if(!(clk & MONITOR_RECV_INTERVAL_MASK)) {
      if((PSR & PSR_IM_ENABLE) && IDT_ISENABLE(IDT_DPS_LS_NUM)) {
	dps_sci_recv();
      }

      if(MONITOR) {
	monitor_method_recv();
	monitor_send_queue();
      }
    }

    /* next */
    if(next_PCR != 0xffffffff) {
#if !NO_DEBUG
      /* alignment check */
      if(next_PCR & 0x3) {
	abort_sim();
	errx(EXIT_FAILURE, "invalid branch addres. %08x", next_PCR);
      }
#endif

      PCR = next_PCR;
      next_PCR = 0xffffffff;
    }
    else {
      PCR += 4;
    }

    /* interrupt check */
    interrupt_dispatcher();

#if !NO_DEBUG
    /* for invalid flags checking */
    prev_FLAGR.flags = FLAGR.flags;
    FLAGR._invalid |= 1;
#endif

    /* next cycle */
    clk++;

  } while(!(PCR == 0 && GR[31] == 0 && DEBUG_EXIT_B0) && !exec_finish);
  /* DEBUG_EXIT_B0: exit if b rret && rret == 0 */

  NOTICE("---- Program Terminated ----\n");
  print_instruction(insn);
  print_registers();

  return 0;
}
示例#2
0
int TenshiRunQuanta(TenshiRuntimeState s) {
  // Do timeouts
  ActorProcessTimeouts(s);

  // Run the sensor actor
  // Dup the function first, as it disappears when we exit
  // TODO(rqou): Will we have a problem with the hardcoded op limit?
  lua_pushvalue(s->sensor_actor->L, -1);
  int ret = threading_run_ops(s->sensor_actor->L, 1000, NULL);
  if (ret != THREADING_EXITED) {
    printf("There was an error running the sensor actor!\n");
    print_traceback(s->sensor_actor->L);
    return ret;
  }

  // Run the main code
  int ops_left = QUANTA_OPCODES;
  while (ops_left > 0) {
    TenshiActorState a;
    ret = ActorDequeueHead(s, &a);
    if (ret != LUA_OK) return ret;

    if (!a) {
      break;
    }

    ret = threading_run_ops(a->L, ops_left, &ops_left);
    if (ret == THREADING_ERROR) {
      printf("THERE WAS AN ERROR!\n");
      print_traceback(a->L);

      return LUA_ERRRUN;
    }

    if (ret == THREADING_EXITED) {
      printf("Thread exited!\n");
      ActorDestroy(a);
    } else if (ret == THREADING_YIELD) {
      printf("Thread yielded (blocked)!\n");
      ret = ActorSetBlocked(a);
      if (ret != LUA_OK) return ret;
    } else if (ret == THREADING_PREEMPT) {
      // Requeue it
      ret = ActorSetRunnable(a, 0);
      if (ret != LUA_OK) return ret;
    }
  }

  // Run the actuator actor
  // Dup the function first, as it disappears when we exit
  lua_pushvalue(s->actuator_actor->L, -1);
  ret = threading_run_ops(s->actuator_actor->L, 1000, NULL);
  if (ret != THREADING_EXITED) {
    printf("There was an error running the actuator actor!\n");
    print_traceback(s->actuator_actor->L);
    return ret;
  }

  lua_gc(s->L, LUA_GCCOLLECT, 0);

  return LUA_OK;
}