From 00e8c80c7b33eb0549fe77c3a40b6c697dddc8b2 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Thu, 28 Jan 2016 08:00:41 -0800 Subject: [PATCH] TIMER: Provide an internal calibrated clock when none is otherwise available. In the event that there are no active clock devices, no instruction rate calibration will be performed. This is more likely on simpler simulators which don't have a full spectrum of standard devices or possibly when a clock device exists but its use is optional and thus sometimes it may be disabled. --- sim_timer.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/sim_timer.c b/sim_timer.c index a02d1320..d33bd36d 100644 --- a/sim_timer.c +++ b/sim_timer.c @@ -555,7 +555,8 @@ static uint32 rtc_elapsed[SIM_NTIMERS] = { 0 }; /* sec since init */ static uint32 rtc_calibrations[SIM_NTIMERS] = { 0 }; /* calibration count */ static double rtc_clock_skew_max[SIM_NTIMERS] = { 0 }; /* asynchronous max skew */ -UNIT sim_timer_units[SIM_NTIMERS+1]; /* one for each timer and one for throttle */ +UNIT sim_timer_units[SIM_NTIMERS+2]; /* one for each timer and one for throttle */ + /* plus one for an internal clock if no clocks are registered */ void sim_rtcn_init_all (void) @@ -896,7 +897,7 @@ MTAB sim_timer_mod[] = { DEVICE sim_timer_dev = { "TIMER", sim_timer_units, sim_timer_reg, sim_timer_mod, - SIM_NTIMERS+1, 0, 0, 0, 0, 0, + SIM_NTIMERS+2, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, DEV_DEBUG | DEV_NOSAVE, 0, sim_timer_debug}; @@ -1376,8 +1377,34 @@ return NULL; #endif /* defined(SIM_ASYNCH_IO) && defined(SIM_ASYNCH_CLOCKS) */ +/* + In the event that there are no active clock devices, no instruction + rate calibration will be performed. This is more likely on simpler + simulators which don't have a full spectrum of standard devices or + possibly when a clock device exists but its use is optional. + + To solve this we merely run an internal clock at 50Hz. + */ +#define CLK_TPS 50 +static sim_timer_clock_tick_svc (UNIT *uptr) +{ +sim_rtcn_calb (CLK_TPS, SIM_NTIMERS-1); +sim_activate_after (uptr, 1000000/CLK_TPS); /* reactivate unit */ +} + void sim_start_timer_services (void) { +uint32 i; + +for (i = 0; i < SIM_NTIMERS; i++) + if (rtc_initd[i] != 0) + break; +if (i == SIM_NTIMERS) { /* No clocks have signed in. */ + /* setup internal clock */ + sim_timer_units[SIM_NTIMERS+1].action = &sim_timer_clock_tick_svc; + sim_rtcn_init_unit (&sim_timer_units[SIM_NTIMERS+1], 5000, SIM_NTIMERS-1); + sim_activate_abs (&sim_timer_units[SIM_NTIMERS+1], 5000); + } #if defined(SIM_ASYNCH_IO) && defined(SIM_ASYNCH_CLOCKS) pthread_mutex_lock (&sim_timer_lock); if (sim_asynch_enabled && sim_asynch_timer) {