Ejemplo n.º 1
0
void avr_callback_run_gdb(avr_t * avr)
{
	avr_gdb_processor(avr, avr->state == cpu_Stopped);

	if (avr->state == cpu_Stopped)
		return ;

	// if we are stepping one instruction, we "run" for one..
	int step = avr->state == cpu_Step;
	if (step)
		avr->state = cpu_Running;
	
	uint16_t new_pc = avr->pc;

	if (avr->state == cpu_Running) {
		new_pc = avr_run_one(avr);
#if CONFIG_SIMAVR_TRACE
		avr_dump_state(avr);
#endif
	}

	// if we just re-enabled the interrupts...
	// double buffer the I flag, to detect that edge
	if (avr->sreg[S_I] && !avr->i_shadow)
		avr->pending_wait++;
	avr->i_shadow = avr->sreg[S_I];

	// run the cycle timers, get the suggested sleep time
	// until the next timer is due
	avr_cycle_count_t sleep = avr_cycle_timer_process(avr);

	avr->pc = new_pc;

	if (avr->state == cpu_Sleeping) {
		if (!avr->sreg[S_I]) {
			if (avr->log)
				printf("simavr: sleeping with interrupts off, quitting gracefully\n");
			avr_terminate(avr);
			avr->state = cpu_Done;
			return;
		}
		/*
		 * try to sleep for as long as we can (?)
		 */
		avr->sleep(avr, sleep);
		avr->cycle += 1 + sleep;
	}
	// Interrupt servicing might change the PC too, during 'sleep'
	if (avr->state == cpu_Running || avr->state == cpu_Sleeping)
		avr_service_interrupts(avr);
	
	// if we were stepping, use this state to inform remote gdb
	if (step)
		avr->state = cpu_StepDone;

}
Ejemplo n.º 2
0
void
avr_callback_run_gdb (avr_t * avr)
{
  avr_gdb_processor (avr, avr->state == cpu_Stopped);

  if (avr->state == cpu_Stopped)
    return;

  // if we are stepping one instruction, we "run" for one..
  int step = avr->state == cpu_Step;
  if (step)
    avr->state = cpu_Running;

  avr_flashaddr_t new_pc = avr->pc;

  if (avr->state == cpu_Running)
    {
      new_pc = avr_run_one (avr);
#if CONFIG_SIMAVR_TRACE
      avr_dump_state (avr);
#endif
    }

  // run the cycle timers, get the suggested sleep time until the next timer is due
  avr_cycle_count_t sleep = avr_cycle_timer_process (avr);

  avr->pc = new_pc;

  if (avr->state == cpu_Sleeping)
    {
      if (!avr->sreg[S_I])
        {
          if (avr->log)
            AVR_LOG (avr, LOG_TRACE, "simavr: sleeping with interrupts off, quitting gracefully\n");
          avr->state = cpu_Done;
          return;
        }
      // try to sleep for as long as we can (?)
      avr->sleep (avr, sleep);
      avr->cycle += 1 + sleep;
    }
  // Interrupt servicing might change the PC too, during 'sleep'
  if (avr->state == cpu_Running || avr->state == cpu_Sleeping)
    avr_service_interrupts (avr);

  // if we were stepping, use this state to inform remote gdb
  if (step)
    avr->state = cpu_StepDone;
}
Ejemplo n.º 3
0
void
avr_callback_run_raw (avr_t * avr)
{
  avr_flashaddr_t new_pc = avr->pc;

  if (avr->state == cpu_Running)
    {
      new_pc = avr_run_one (avr);
#if CONFIG_SIMAVR_TRACE
      avr_dump_state (avr);
#endif
    }

  // run the cycle timers, get the suggested sleep time until the next timer is due
  avr_cycle_count_t sleep = avr_cycle_timer_process (avr);

  avr->pc = new_pc;

  if (avr->state == cpu_Sleeping)
    {
      if (!avr->sreg[S_I])
        {
          if (avr->log)
            AVR_LOG (avr, LOG_TRACE, "simavr: sleeping with interrupts off, quitting gracefully\n");
          avr->state = cpu_Done;
          return;
        }
      // try to sleep for as long as we can (?)
      avr->sleep (avr, sleep);
      avr->cycle += 1 + sleep;
    }

  // Interrupt servicing might change the PC too, during 'sleep'
  if (avr->state == cpu_Running || avr->state == cpu_Sleeping)
    {
      // Note: checking interrupt_state here is completely superfluous, however as interrupt_state
      // tells us all we really need to know, here a simple check here may be cheaper than a call
      // not needed.
      if (avr->interrupt_state)
        avr_service_interrupts (avr);
    }
}
Ejemplo n.º 4
0
void avr_callback_run_raw(avr_t * avr)
{
	avr_flashaddr_t new_pc = avr->pc;

	if (avr->state == cpu_Running) {
		new_pc = avr_run_one(avr);
#if CONFIG_SIMAVR_TRACE
		avr_dump_state(avr);
#endif
	}

	// if we just re-enabled the interrupts...
	// double buffer the I flag, to detect that edge
	if (avr->sreg[S_I] && !avr->i_shadow)
		avr->interrupts.pending_wait++;
	avr->i_shadow = avr->sreg[S_I];

	// run the cycle timers, get the suggested sleep time
	// until the next timer is due
	avr_cycle_count_t sleep = avr_cycle_timer_process(avr);

	avr->pc = new_pc;

	if (avr->state == cpu_Sleeping) {
		if (!avr->sreg[S_I]) {
			if (avr->log)
				AVR_LOG(avr, LOG_TRACE, "simavr: sleeping with interrupts off, quitting gracefully\n");
			avr->state = cpu_Done;
			return;
		}
		/*
		 * try to sleep for as long as we can (?)
		 */
		avr->sleep(avr, sleep);
		avr->cycle += 1 + sleep;
	}
	// Interrupt servicing might change the PC too, during 'sleep'
	if (avr->state == cpu_Running || avr->state == cpu_Sleeping)
		avr_service_interrupts(avr);
}