mos6522: update counters when timer interrupts are off

Even if the interrupts are off, counters must be updated because
they are running anyway and kernel can try to read them
(it's the case with g3beige kernel).

Reported-by: Andrew Randrianasulu <randrianasulu@gmail.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <20191125141414.5015-1-laurent@vivier.eu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Laurent Vivier 2019-11-25 15:14:14 +01:00 committed by David Gibson
parent b14848f5d7
commit 6cf80f90c4
1 changed files with 6 additions and 2 deletions

View File

@ -113,6 +113,10 @@ static int64_t get_next_irq_time(MOS6522State *s, MOS6522Timer *ti,
int64_t d, next_time;
unsigned int counter;
if (ti->frequency == 0) {
return INT64_MAX;
}
/* current counter value */
d = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - ti->load_time,
ti->frequency, NANOSECONDS_PER_SECOND);
@ -149,10 +153,10 @@ static void mos6522_timer1_update(MOS6522State *s, MOS6522Timer *ti,
if (!ti->timer) {
return;
}
ti->next_irq_time = get_next_irq_time(s, ti, current_time);
if ((s->ier & T1_INT) == 0 || (s->acr & T1MODE) != T1MODE_CONT) {
timer_del(ti->timer);
} else {
ti->next_irq_time = get_next_irq_time(s, ti, current_time);
timer_mod(ti->timer, ti->next_irq_time);
}
}
@ -163,10 +167,10 @@ static void mos6522_timer2_update(MOS6522State *s, MOS6522Timer *ti,
if (!ti->timer) {
return;
}
ti->next_irq_time = get_next_irq_time(s, ti, current_time);
if ((s->ier & T2_INT) == 0) {
timer_del(ti->timer);
} else {
ti->next_irq_time = get_next_irq_time(s, ti, current_time);
timer_mod(ti->timer, ti->next_irq_time);
}
}