timer: read PIT timer solely after interrupt

Stop gap solution until  gets resolved.
This commit is contained in:
Alexander Boettcher 2017-11-14 20:12:18 +01:00 committed by Christian Helmuth
parent 2ba5f8f4f3
commit 80778b267d
3 changed files with 33 additions and 8 deletions
repos/os/src/drivers/timer

@ -30,11 +30,16 @@ class Genode::Signalled_time_source : public Time_source
Signal_handler _signal_handler;
Timeout_handler *_handler = nullptr;
bool _irq = false;
void _handle_timeout()
{
if (_handler) {
_handler->handle_timeout(curr_time()); }
_irq = true;
Duration time(curr_time());
_irq = false;
_handler->handle_timeout(time);
}
}
public:

@ -53,19 +53,27 @@ void Timer::Time_source::schedule_timeout(Microseconds duration,
Timeout_handler &handler)
{
_handler = &handler;
_timer_irq.ack_irq();
unsigned long duration_us = duration.value;
/* limit timer-interrupt rate */
enum { MAX_TIMER_IRQS_PER_SECOND = 4*1000 };
if (duration_us < 1000 * 1000 / MAX_TIMER_IRQS_PER_SECOND)
duration_us = 1000 * 1000 / MAX_TIMER_IRQS_PER_SECOND;
if (duration_us > max_timeout().value)
/* timeout '0' is trigger to cancel the current pending, if required */
if (!duration.value) {
duration_us = max_timeout().value;
Signal_transmitter(_signal_handler).submit();
} else {
/* limit timer-interrupt rate */
enum { MAX_TIMER_IRQS_PER_SECOND = 4*1000 };
if (duration_us < 1000 * 1000 / MAX_TIMER_IRQS_PER_SECOND)
duration_us = 1000 * 1000 / MAX_TIMER_IRQS_PER_SECOND;
if (duration_us > max_timeout().value)
duration_us = max_timeout().value;
}
_counter_init_value = (PIT_TICKS_PER_MSEC * duration_us) / 1000;
_set_counter(_counter_init_value);
if (duration.value)
_timer_irq.ack_irq();
}
@ -93,6 +101,16 @@ uint32_t Timer::Time_source::_ticks_since_update_one_wrap(uint16_t curr_counter)
Duration Timer::Time_source::curr_time()
{
/* read out and update curr time solely if running in context of irq */
if (_irq)
_curr_time();
return Duration(Microseconds(_curr_time_us));
}
Duration Timer::Time_source::_curr_time()
{
/* read PIT counter and wrapped status */
uint32_t ticks;

@ -82,6 +82,8 @@ class Timer::Time_source : public Genode::Signalled_time_source
Genode::uint32_t _ticks_since_update_no_wrap(Genode::uint16_t curr_counter);
Duration _curr_time();
public:
Time_source(Genode::Env &env);