Пример #1
0
void bx_pit_c::handle_timer()
{
  Bit64u my_time_usec = bx_virt_timer.time_usec();
  Bit64u time_passed = my_time_usec-BX_PIT_THIS s.last_usec;
  Bit32u time_passed32 = (Bit32u)time_passed;

  BX_DEBUG(("entering timer handler"));

  if(time_passed32) {
    periodic(time_passed32);
  }
  BX_PIT_THIS s.last_usec = BX_PIT_THIS s.last_usec + time_passed;
  if (time_passed || (BX_PIT_THIS s.last_next_event_time != BX_PIT_THIS s.timer.get_next_event_time())) {
    BX_DEBUG(("RESETting timer"));
    bx_virt_timer.deactivate_timer(BX_PIT_THIS s.timer_handle[0]);
    BX_DEBUG(("deactivated timer"));
    if(BX_PIT_THIS s.timer.get_next_event_time()) {
      bx_virt_timer.activate_timer(BX_PIT_THIS s.timer_handle[0],
                                   (Bit32u)BX_MAX(1,TICKS_TO_USEC(BX_PIT_THIS s.timer.get_next_event_time())),
                                   0);
      BX_DEBUG(("activated timer"));
    }
    BX_PIT_THIS s.last_next_event_time = BX_PIT_THIS s.timer.get_next_event_time();
  }
  BX_DEBUG(("s.last_usec="FMT_LL"d", BX_PIT_THIS s.last_usec));
  BX_DEBUG(("s.timer_id=%d", BX_PIT_THIS s.timer_handle[0]));
  BX_DEBUG(("s.timer.get_next_event_time=%x", BX_PIT_THIS s.timer.get_next_event_time()));
  BX_DEBUG(("s.last_next_event_time=%d", BX_PIT_THIS s.last_next_event_time));
}
ulong get_timer(ulong base)
{
	ulong now = get_timer_masked();

	if (now >= base)
		return now - base;
	else
		return TICKS_TO_USEC(0xFFFFFFFFUL) - (base - now) ;
}
Пример #3
0
//Called when next_event_time changes.
void bx_virt_timer_c::next_event_time_update(void)
{
  virtual_next_event_time = timers_next_event_time + current_timers_time - current_virtual_time;
  if (init_done) {
    bx_pc_system.deactivate_timer(system_timer_id);
    BX_ASSERT(virtual_next_event_time);
    bx_pc_system.activate_timer(system_timer_id,
                                (Bit32u)BX_MIN(0x7FFFFFFF,BX_MAX(1,TICKS_TO_USEC(virtual_next_event_time))),
                                0);
  }
}
Пример #4
0
void bx_pit_c::init(void)
{
  DEV_register_irq(0, "8254 PIT");
  DEV_register_ioread_handler(this, read_handler, 0x0040, "8254 PIT", 1);
  DEV_register_ioread_handler(this, read_handler, 0x0041, "8254 PIT", 1);
  DEV_register_ioread_handler(this, read_handler, 0x0042, "8254 PIT", 1);
  DEV_register_ioread_handler(this, read_handler, 0x0043, "8254 PIT", 1);
  DEV_register_ioread_handler(this, read_handler, 0x0061, "8254 PIT", 1);

  DEV_register_iowrite_handler(this, write_handler, 0x0040, "8254 PIT", 1);
  DEV_register_iowrite_handler(this, write_handler, 0x0041, "8254 PIT", 1);
  DEV_register_iowrite_handler(this, write_handler, 0x0042, "8254 PIT", 1);
  DEV_register_iowrite_handler(this, write_handler, 0x0043, "8254 PIT", 1);
  DEV_register_iowrite_handler(this, write_handler, 0x0061, "8254 PIT", 1);

  BX_DEBUG(("starting init"));

  BX_PIT_THIS s.speaker_data_on = 0;
  BX_PIT_THIS s.refresh_clock_div2 = 0;

  BX_PIT_THIS s.timer.init();
  BX_PIT_THIS s.timer.set_OUT_handler(0, irq_handler);

  Bit64u my_time_usec = bx_virt_timer.time_usec();

  if (BX_PIT_THIS s.timer_handle[0] == BX_NULL_TIMER_HANDLE) {
    BX_PIT_THIS s.timer_handle[0] = bx_virt_timer.register_timer(this, timer_handler, (unsigned) 100 , 1, 1, "pit_wrap");
  }
  BX_DEBUG(("RESETting timer."));
  bx_virt_timer.deactivate_timer(BX_PIT_THIS s.timer_handle[0]);
  BX_DEBUG(("deactivated timer."));
  if (BX_PIT_THIS s.timer.get_next_event_time()) {
    bx_virt_timer.activate_timer(BX_PIT_THIS s.timer_handle[0],
                                 (Bit32u)BX_MAX(1,TICKS_TO_USEC(BX_PIT_THIS s.timer.get_next_event_time())),
                                 0);
    BX_DEBUG(("activated timer."));
  }
  BX_PIT_THIS s.last_next_event_time = BX_PIT_THIS s.timer.get_next_event_time();
  BX_PIT_THIS s.last_usec = my_time_usec;

  BX_PIT_THIS s.total_ticks = 0;
  BX_PIT_THIS s.total_usec = 0;

  BX_DEBUG(("finished init"));

  BX_DEBUG(("s.last_usec="FMT_LL"d",BX_PIT_THIS s.last_usec));
  BX_DEBUG(("s.timer_id=%d",BX_PIT_THIS s.timer_handle[0]));
  BX_DEBUG(("s.timer.get_next_event_time=%d", BX_PIT_THIS s.timer.get_next_event_time()));
  BX_DEBUG(("s.last_next_event_time=%d", BX_PIT_THIS s.last_next_event_time));
}
Пример #5
0
void bx_virt_timer_c::timer_handler(void)
{
  if(!virtual_timers_realtime) {
    Bit64u temp_final_time = bx_pc_system.time_usec();
    temp_final_time -= current_virtual_time;
    while (temp_final_time) {
      if((temp_final_time)>(virtual_next_event_time)) {
        temp_final_time -= virtual_next_event_time;
        advance_virtual_time(virtual_next_event_time);
      } else {
        advance_virtual_time(temp_final_time);
        temp_final_time -= temp_final_time;
      }
    }
    bx_pc_system.activate_timer(system_timer_id,
                                (Bit32u)BX_MIN(0x7FFFFFFF,(virtual_next_event_time>2)?(virtual_next_event_time-2):1),
                                0);
    return;
  }

  Bit64u usec_delta = bx_pc_system.time_usec()-last_usec;

  if (usec_delta) {
#if BX_HAVE_REALTIME_USEC
    Bit64u ticks_delta = 0;
    Bit64u real_time_delta = GET_VIRT_REALTIME64_USEC() - last_real_time - real_time_delay;
    Bit64u real_time_total = real_time_delta + total_real_usec;
    Bit64u system_time_delta = (Bit64u)usec_delta + (Bit64u)stored_delta;
    if(real_time_delta) {
      last_realtime_delta = real_time_delta;
      last_realtime_ticks = total_ticks;
    }
    ticks_per_second = USEC_PER_SECOND;

    //Start out with the number of ticks we would like
    // to have to line up with real time.
    ticks_delta = real_time_total - total_ticks;
    if(real_time_total < total_ticks) {
      //This slows us down if we're already ahead.
      //  probably only an issue on startup, but it solves some problems.
      ticks_delta = 0;
    }
    if(ticks_delta + total_ticks - last_realtime_ticks > (F2I(MAX_MULT * I2F(last_realtime_delta)))) {
      //This keeps us from going too fast in relation to real time.
#if 0
      ticks_delta = (F2I(MAX_MULT * I2F(last_realtime_delta))) + last_realtime_ticks - total_ticks;
#endif
      ticks_per_second = F2I(MAX_MULT * I2F(USEC_PER_SECOND));
    }
    if(ticks_delta > system_time_delta * USEC_PER_SECOND / MIN_USEC_PER_SECOND) {
      //This keeps us from having too few instructions between ticks.
      ticks_delta = system_time_delta * USEC_PER_SECOND / MIN_USEC_PER_SECOND;
    }
    if(ticks_delta > virtual_next_event_time) {
      //This keeps us from missing ticks.
      ticks_delta = virtual_next_event_time;
    }

    if(ticks_delta) {

#  if DEBUG_REALTIME_WITH_PRINTF
      //Every second print some info.
      if(((last_real_time + real_time_delta) / USEC_PER_SECOND) > (last_real_time / USEC_PER_SECOND)) {
        Bit64u temp1, temp2, temp3, temp4;
        temp1 = (Bit64u) total_real_usec;
        temp2 = (total_real_usec);
        temp3 = (Bit64u)total_ticks;
        temp4 = (Bit64u)((total_real_usec) - total_ticks);
        printf("useconds: " FMT_LL "u, ", temp1);
        printf("expect ticks: " FMT_LL "u, ", temp2);
        printf("ticks: " FMT_LL "u, ", temp3);
        printf("diff: "FMT_LL "u\n", temp4);
      }
#  endif

      last_real_time += real_time_delta;
      total_real_usec += real_time_delta;
      last_system_usec += system_time_delta;
      stored_delta = 0;
      total_ticks += ticks_delta;
    } else {
      stored_delta = system_time_delta;
    }

    Bit64u a = usec_per_second, b;
    if(real_time_delta) {
      //FIXME
      Bit64u em_realtime_delta = last_system_usec + stored_delta - em_last_realtime;
      b=((Bit64u)USEC_PER_SECOND * em_realtime_delta / real_time_delta);
      em_last_realtime = last_system_usec + stored_delta;
    } else {
      b=a;
    }
    usec_per_second = ALPHA_LOWER(a,b);
#else
    BX_ASSERT(0);
#endif
#if BX_HAVE_REALTIME_USEC
    advance_virtual_time(ticks_delta);
#endif
  }

  last_usec=last_usec + usec_delta;
  bx_pc_system.deactivate_timer(system_timer_id);
  BX_ASSERT(virtual_next_event_time);
  bx_pc_system.activate_timer(system_timer_id,
                              (Bit32u)BX_MIN(0x7FFFFFFF,BX_MAX(1,TICKS_TO_USEC(virtual_next_event_time))),
                              0);
}
ulong get_timer_masked(void)
{
	return TICKS_TO_USEC(get_timer_raw());

}
Пример #7
0
void bx_pit_c::write(Bit32u address, Bit32u dvalue, unsigned io_len)
{
#else
  UNUSED(this_ptr);
#endif  // !BX_USE_PIT_SMF
  Bit8u   value;
  Bit64u my_time_usec = bx_virt_timer.time_usec();
  Bit64u time_passed = my_time_usec-BX_PIT_THIS s.last_usec;
  Bit32u time_passed32 = (Bit32u)time_passed;

  if(time_passed32) {
    periodic(time_passed32);
  }
  BX_PIT_THIS s.last_usec = BX_PIT_THIS s.last_usec + time_passed;

  value = (Bit8u) dvalue;

  BX_DEBUG(("write to port 0x%04x, value = 0x%02x", address, value));

  switch (address) {
    case 0x40: /* timer 0: write count register */
      BX_PIT_THIS s.timer.write(0, value);
      break;

    case 0x41: /* timer 1: write count register */
      BX_PIT_THIS s.timer.write(1, value);
      break;

    case 0x42: /* timer 2: write count register */
      BX_PIT_THIS s.timer.write(2, value);
      break;

    case 0x43: /* timer 0-2 mode control */
      BX_PIT_THIS s.timer.write(3, value);
      break;

    case 0x61:
      BX_PIT_THIS s.speaker_data_on = (value >> 1) & 0x01;
      if (BX_PIT_THIS s.speaker_data_on) {
        DEV_speaker_beep_on((float)(1193180.0 / BX_PIT_THIS get_timer(2)));
      } else {
        DEV_speaker_beep_off();
      }
      /* ??? only on AT+ */
      BX_PIT_THIS s.timer.set_GATE(2, value & 0x01);
      break;

    default:
      BX_PANIC(("unsupported io write to port 0x%04x = 0x%02x", address, value));
  }

  if (time_passed || (BX_PIT_THIS s.last_next_event_time != BX_PIT_THIS s.timer.get_next_event_time())) {
    BX_DEBUG(("RESETting timer"));
    bx_virt_timer.deactivate_timer(BX_PIT_THIS s.timer_handle[0]);
    BX_DEBUG(("deactivated timer"));
    if(BX_PIT_THIS s.timer.get_next_event_time()) {
      bx_virt_timer.activate_timer(BX_PIT_THIS s.timer_handle[0],
                                   (Bit32u)BX_MAX(1,TICKS_TO_USEC(BX_PIT_THIS s.timer.get_next_event_time())),
                                   0);
      BX_DEBUG(("activated timer"));
    }
    BX_PIT_THIS s.last_next_event_time = BX_PIT_THIS s.timer.get_next_event_time();
  }
  BX_DEBUG(("s.last_usec="FMT_LL"d", BX_PIT_THIS s.last_usec));
  BX_DEBUG(("s.timer_id=%d", BX_PIT_THIS s.timer_handle[0]));
  BX_DEBUG(("s.timer.get_next_event_time=%x", BX_PIT_THIS s.timer.get_next_event_time()));
  BX_DEBUG(("s.last_next_event_time=%d", BX_PIT_THIS s.last_next_event_time));

}