- small cleanups in the pit_wrap and virt_timer code

- TODO: rewrite virtual timer code to support both timer types at the same time
This commit is contained in:
Volker Ruppert 2011-06-04 06:40:04 +00:00
parent acf2175d6d
commit f2f4099bc1
3 changed files with 108 additions and 113 deletions

View File

@ -77,7 +77,6 @@ void libpit_LTX_plugin_fini(void)
bx_pit_c::bx_pit_c()
{
put("PIT");
s.speaker_data_on=0;
/* 8254 PIT (Programmable Interval Timer) */
@ -124,17 +123,17 @@ void bx_pit_c::init(void)
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.last_usec = my_time_usec;
BX_PIT_THIS s.total_ticks=0;
BX_PIT_THIS s.total_usec=0;
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));
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));
}
void bx_pit_c::reset(unsigned type)
@ -145,7 +144,7 @@ void bx_pit_c::reset(unsigned type)
void bx_pit_c::register_state(void)
{
bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "pit", "8254 PIT State", 7);
new bx_shadow_num_c(list, "speaker_data_on", &BX_PIT_THIS s.speaker_data_on, BASE_HEX);
new bx_shadow_bool_c(list, "speaker_data_on", &BX_PIT_THIS s.speaker_data_on);
new bx_shadow_bool_c(list, "refresh_clock_div2", &BX_PIT_THIS s.refresh_clock_div2);
new bx_shadow_num_c(list, "last_usec", &BX_PIT_THIS s.last_usec);
new bx_shadow_num_c(list, "last_next_event_time", &BX_PIT_THIS s.last_next_event_time);
@ -172,9 +171,8 @@ void bx_pit_c::handle_timer()
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_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"));
@ -186,10 +184,10 @@ void bx_pit_c::handle_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));
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));
}
// static IO port read callback handler
@ -232,10 +230,10 @@ Bit32u bx_pit_c::read(Bit32u address, unsigned io_len)
case 0x61:
/* AT, port 61h */
BX_PIT_THIS s.refresh_clock_div2 = (bx_bool)((my_time_usec / 15) & 1);
value = (BX_PIT_THIS s.timer.read_OUT(2)<<5) |
(BX_PIT_THIS s.refresh_clock_div2<<4) |
(BX_PIT_THIS s.speaker_data_on<<1) |
(BX_PIT_THIS s.timer.read_GATE(2)?1:0);
value = (BX_PIT_THIS s.timer.read_OUT(2) << 5) |
(BX_PIT_THIS s.refresh_clock_div2 << 4) |
(BX_PIT_THIS s.speaker_data_on << 1) |
(BX_PIT_THIS s.timer.read_GATE(2) ? 1 : 0);
break;
default:
@ -269,7 +267,7 @@ void bx_pit_c::write(Bit32u address, Bit32u dvalue, unsigned io_len)
if(time_passed32) {
periodic(time_passed32);
}
BX_PIT_THIS s.last_usec=BX_PIT_THIS s.last_usec + time_passed;
BX_PIT_THIS s.last_usec = BX_PIT_THIS s.last_usec + time_passed;
value = (Bit8u) dvalue;
@ -307,8 +305,7 @@ void bx_pit_c::write(Bit32u address, Bit32u dvalue, unsigned io_len)
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()))
{
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"));
@ -320,10 +317,10 @@ void bx_pit_c::write(Bit32u address, Bit32u dvalue, unsigned io_len)
}
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));
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));
}
@ -332,7 +329,7 @@ bx_bool bx_pit_c::periodic(Bit32u usec_delta)
Bit32u ticks_delta = 0;
BX_PIT_THIS s.total_usec += usec_delta;
ticks_delta=(Bit32u)((USEC_TO_TICKS((Bit64u)(BX_PIT_THIS s.total_usec)))-BX_PIT_THIS s.total_ticks);
ticks_delta = (Bit32u)((USEC_TO_TICKS((Bit64u)(BX_PIT_THIS s.total_usec)))-BX_PIT_THIS s.total_ticks);
BX_PIT_THIS s.total_ticks += ticks_delta;
while ((BX_PIT_THIS s.total_ticks >= TICKS_PER_SECOND) && (BX_PIT_THIS s.total_usec >= USEC_PER_SECOND)) {
@ -341,13 +338,13 @@ bx_bool bx_pit_c::periodic(Bit32u usec_delta)
}
while(ticks_delta>0) {
Bit32u maxchange=BX_PIT_THIS s.timer.get_next_event_time();
Bit32u timedelta=maxchange;
if((maxchange==0) || (maxchange>ticks_delta)) {
timedelta=ticks_delta;
Bit32u maxchange = BX_PIT_THIS s.timer.get_next_event_time();
Bit32u timedelta = maxchange;
if((maxchange == 0) || (maxchange>ticks_delta)) {
timedelta = ticks_delta;
}
BX_PIT_THIS s.timer.clock_all(timedelta);
ticks_delta-=timedelta;
ticks_delta -= timedelta;
}
return 0;

View File

@ -50,13 +50,13 @@ private:
struct s_type {
pit_82C54 timer;
Bit8u speaker_data_on;
bx_bool speaker_data_on;
bx_bool refresh_clock_div2;
Bit64u last_usec;
Bit32u last_next_event_time;
Bit64u total_ticks;
Bit64u total_usec;
int timer_handle[3];
Bit64u last_usec;
Bit32u last_next_event_time;
Bit64u total_ticks;
Bit64u total_usec;
int timer_handle[3];
} s;
static void timer_handler(void *this_ptr);

View File

@ -62,7 +62,6 @@
#include "virt_timer.h"
#define BX_USE_VIRTUAL_TIMERS 1
#define BX_VIRTUAL_TIMERS_REALTIME 1
//Important constant #defines:
#define USEC_PER_SECOND (1000000)
@ -146,25 +145,25 @@ void bx_virt_timer_c::periodic(Bit64u time_passed)
current_timers_time += time_passed;
//If no events are occurring, just pass the time and we're done.
if(time_passed < timers_next_event_time) return;
if (time_passed < timers_next_event_time) return;
//Starting timer handler calls.
in_timer_handler = 1;
//Otherwise, cause any events to occur that should.
unsigned i;
for(i=0;i<numTimers;i++) {
if(timer[i].inUse && timer[i].active) {
for (i=0;i<numTimers;i++) {
if (timer[i].inUse && timer[i].active) {
//Assert that we haven't skipped any timers.
BX_ASSERT(current_timers_time <= timer[i].timeToFire);
if(timer[i].timeToFire == current_timers_time) {
if(timer[i].continuous) {
timer[i].timeToFire+=timer[i].period;
} else {
timer[i].active = 0;
}
//This function MUST return, or the timer mechanism
// will be broken.
timer[i].funct(timer[i].this_ptr);
if(timer[i].continuous) {
timer[i].timeToFire += timer[i].period;
} else {
timer[i].active = 0;
}
//This function MUST return, or the timer mechanism
// will be broken.
timer[i].funct(timer[i].this_ptr);
}
}
}
@ -176,12 +175,12 @@ void bx_virt_timer_c::periodic(Bit64u time_passed)
// here we use it as a temporary variable that IS a cycle time,
// but then convert it back to a cycle count afterwards.
timers_next_event_time = current_timers_time + BX_MAX_VIRTUAL_TIME;
for(i=0;i<numTimers;i++) {
if(timer[i].inUse && timer[i].active && ((timer[i].timeToFire)<timers_next_event_time)) {
for (i=0;i<numTimers;i++) {
if (timer[i].inUse && timer[i].active && ((timer[i].timeToFire)<timers_next_event_time)) {
timers_next_event_time = timer[i].timeToFire;
}
}
timers_next_event_time-=current_timers_time;
timers_next_event_time -= current_timers_time;
next_event_time_update();
//FIXME
}
@ -189,20 +188,19 @@ void bx_virt_timer_c::periodic(Bit64u time_passed)
//Get the current virtual time.
// This may return the same value on subsequent calls.
Bit64u bx_virt_timer_c::time_usec(void)
Bit64u bx_virt_timer_c::time_usec()
{
if(!use_virtual_timers) {
if (!use_virtual_timers) {
return bx_pc_system.time_usec();
} else {
//Update the time here only if we're not in a timer handler.
//If we're in a timer handler we're up-to-date, and otherwise
// this prevents call stack loops.
if (!in_timer_handler) {
timer_handler();
}
return current_timers_time;
}
//Update the time here only if we're not in a timer handler.
//If we're in a timer handler we're up-to-date, and otherwise
// this prevents call stack loops.
if(!in_timer_handler) {
timer_handler();
}
return current_timers_time;
}
//Get the current virtual time.
@ -210,7 +208,7 @@ Bit64u bx_virt_timer_c::time_usec(void)
// MUST NOT be called from within a timer interrupt.
Bit64u bx_virt_timer_c::time_usec_sequential(void)
{
if(!use_virtual_timers) {
if (!use_virtual_timers) {
return bx_pc_system.time_usec_sequential();
}
@ -219,7 +217,7 @@ Bit64u bx_virt_timer_c::time_usec_sequential(void)
BX_ASSERT(timers_next_event_time>0);
BX_ASSERT(!in_timer_handler);
if(last_sequential_time >= current_timers_time) {
if (last_sequential_time >= current_timers_time) {
periodic(1);
last_sequential_time = current_timers_time;
}
@ -230,13 +228,13 @@ Bit64u bx_virt_timer_c::time_usec_sequential(void)
//Register a timer handler to go off after a given interval.
//Register a timer handler to go off with a periodic interval.
int bx_virt_timer_c::register_timer(void *this_ptr, bx_timer_handler_t handler,
Bit32u useconds,
bx_bool continuous, bx_bool active,
const char *id)
Bit32u useconds,
bx_bool continuous, bx_bool active,
const char *id)
{
if(!use_virtual_timers) {
if (!use_virtual_timers) {
return bx_pc_system.register_timer(this_ptr, handler, useconds,
continuous, active, id);
continuous, active, id);
}
//We don't like starting with a zero period timer.
@ -245,11 +243,11 @@ int bx_virt_timer_c::register_timer(void *this_ptr, bx_timer_handler_t handler,
//Search for an unused timer.
unsigned int i;
for (i=0; i < numTimers; i++) {
if (timer[i].inUse == 0 || i==numTimers)
if ((timer[i].inUse == 0) || (i == numTimers))
break;
}
// If we didn't find a free slot, increment the bound, numTimers.
if (i==numTimers)
if (i == numTimers)
numTimers++; // One new timer installed.
BX_ASSERT(numTimers<BX_MAX_VIRTUAL_TIMERS);
@ -263,7 +261,7 @@ int bx_virt_timer_c::register_timer(void *this_ptr, bx_timer_handler_t handler,
strncpy(timer[i].id, id, BxMaxTimerIDLen);
timer[i].id[BxMaxTimerIDLen-1]=0; //I like null terminated strings.
if(useconds < timers_next_event_time) {
if (useconds < timers_next_event_time) {
timers_next_event_time = useconds;
next_event_time_update();
//FIXME
@ -274,7 +272,7 @@ int bx_virt_timer_c::register_timer(void *this_ptr, bx_timer_handler_t handler,
//unregister a previously registered timer.
bx_bool bx_virt_timer_c::unregisterTimer(unsigned timerID)
{
if(!use_virtual_timers)
if (!use_virtual_timers)
return bx_pc_system.unregisterTimer(timerID);
BX_ASSERT(timerID < BX_MAX_VIRTUAL_TIMERS);
@ -292,7 +290,7 @@ bx_bool bx_virt_timer_c::unregisterTimer(unsigned timerID)
void bx_virt_timer_c::start_timers(void)
{
if(!use_virtual_timers) {
if (!use_virtual_timers) {
bx_pc_system.start_timers();
return;
}
@ -301,9 +299,9 @@ void bx_virt_timer_c::start_timers(void)
//activate a deactivated but registered timer.
void bx_virt_timer_c::activate_timer(unsigned timer_index, Bit32u useconds,
bx_bool continuous)
bx_bool continuous)
{
if(!use_virtual_timers) {
if (!use_virtual_timers) {
bx_pc_system.activate_timer(timer_index, useconds, continuous);
return;
}
@ -313,12 +311,12 @@ void bx_virt_timer_c::activate_timer(unsigned timer_index, Bit32u useconds,
BX_ASSERT(timer[timer_index].inUse);
BX_ASSERT(useconds>0);
timer[timer_index].period=useconds;
timer[timer_index].period = useconds;
timer[timer_index].timeToFire = current_timers_time + (Bit64u)useconds;
timer[timer_index].active=1;
timer[timer_index].continuous=continuous;
timer[timer_index].active = 1;
timer[timer_index].continuous = continuous;
if(useconds < timers_next_event_time) {
if (useconds < timers_next_event_time) {
timers_next_event_time = useconds;
next_event_time_update();
//FIXME
@ -328,7 +326,7 @@ void bx_virt_timer_c::activate_timer(unsigned timer_index, Bit32u useconds,
//deactivate (but don't unregister) a currently registered timer.
void bx_virt_timer_c::deactivate_timer(unsigned timer_index)
{
if(!use_virtual_timers) {
if (!use_virtual_timers) {
bx_pc_system.deactivate_timer(timer_index);
return;
}
@ -346,7 +344,7 @@ void bx_virt_timer_c::advance_virtual_time(Bit64u time_passed)
current_virtual_time += time_passed;
virtual_next_event_time -= time_passed;
if(current_virtual_time > current_timers_time) {
if (current_virtual_time > current_timers_time) {
periodic(current_virtual_time - current_timers_time);
}
}
@ -355,12 +353,12 @@ void bx_virt_timer_c::advance_virtual_time(Bit64u time_passed)
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) {
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);
(Bit32u)BX_MIN(0x7FFFFFFF,BX_MAX(1,TICKS_TO_USEC(virtual_next_event_time))),
0);
}
}
@ -400,19 +398,19 @@ void bx_virt_timer_c::init(void)
//Real time variables:
#if BX_HAVE_REALTIME_USEC
last_real_time=GET_VIRT_REALTIME64_USEC()+(Bit64u)TIME_HEADSTART*(Bit64u)USEC_PER_SECOND;
last_real_time = GET_VIRT_REALTIME64_USEC()+(Bit64u)TIME_HEADSTART*(Bit64u)USEC_PER_SECOND;
#endif
total_real_usec=0;
last_realtime_delta=0;
total_real_usec = 0;
last_realtime_delta = 0;
//System time variables:
last_usec = 0;
usec_per_second = USEC_PER_SECOND;
stored_delta=0;
last_system_usec=0;
em_last_realtime=0;
stored_delta = 0;
last_system_usec = 0;
em_last_realtime = 0;
//Virtual timer variables:
total_ticks=0;
last_realtime_ticks=0;
total_ticks = 0;
last_realtime_ticks = 0;
ticks_per_second = USEC_PER_SECOND;
init_done = 1;
@ -455,19 +453,19 @@ 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) {
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);
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;
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);
(Bit32u)BX_MIN(0x7FFFFFFF,(virtual_next_event_time>2)?(virtual_next_event_time-2):1),
0);
return;
}
@ -514,15 +512,15 @@ void bx_virt_timer_c::timer_handler(void)
# 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);
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
@ -557,8 +555,8 @@ void bx_virt_timer_c::timer_handler(void)
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);
(Bit32u)BX_MIN(0x7FFFFFFF,BX_MAX(1,TICKS_TO_USEC(virtual_next_event_time))),
0);
}
void bx_virt_timer_c::pc_system_timer_handler(void* this_ptr)