Hi, attached patch: * clears the timer's ENABLE bit when a non-auto-restarting timer expires (like the hardware does). * removes uses of QEMU's "one-shot" timer option which 1/ does not work (timers always seem to be "multi-shot") 2/ does not closely match the hardware which checks for the autorestart bit only when the timer expires.
Sébastien
diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c index 494c6db..da78385 100644 --- a/hw/milkymist-sysctl.c +++ b/hw/milkymist-sysctl.c @@ -106,7 +106,7 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint32_t value) addr >>= 2; D(printf("%s addr=" TARGET_FMT_plx " val=%x (off=%d)\n", __func__, addr * 4, value, (int)addr & 3)); - switch (addr) + switch (addr) { case R_GPIO_OUT: case R_GPIO_INTEN: @@ -127,11 +127,7 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint32_t value) case R_TIMER0_CONTROL: t->regs[addr] = value; if (t->regs[R_TIMER0_CONTROL] & CTRL_ENABLE) { - if (t->regs[R_TIMER0_CONTROL] & CTRL_AUTORESTART) { - ptimer_run(t->ptimer0, 0); - } else { - ptimer_run(t->ptimer0, 1); - } + ptimer_run(t->ptimer0, 0); } else { ptimer_stop(t->ptimer0); } @@ -139,11 +135,7 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint32_t value) case R_TIMER1_CONTROL: t->regs[addr] = value; if (t->regs[R_TIMER1_CONTROL] & CTRL_ENABLE) { - if (t->regs[R_TIMER1_CONTROL] & CTRL_AUTORESTART) { - ptimer_run(t->ptimer1, 0); - } else { - ptimer_run(t->ptimer1, 1); - } + ptimer_run(t->ptimer1, 0); } else { ptimer_stop(t->ptimer1); } @@ -180,6 +172,10 @@ static void timer0_hit(void *opaque) D(printf("%s\n", __func__)); qemu_irq_pulse(t->timer0_irq); + if (!(t->regs[R_TIMER0_CONTROL] & CTRL_AUTORESTART)) { + t->regs[R_TIMER0_CONTROL] &= ~CTRL_ENABLE; + ptimer_stop(t->ptimer0); + } } static void timer1_hit(void *opaque) @@ -189,6 +185,10 @@ static void timer1_hit(void *opaque) D(printf("%s\n", __func__)); qemu_irq_pulse(t->timer1_irq); + if (!(t->regs[R_TIMER1_CONTROL] & CTRL_AUTORESTART)) { + t->regs[R_TIMER1_CONTROL] &= ~CTRL_ENABLE; + ptimer_stop(t->ptimer1); + } } static int milkymist_sysctl_init(SysBusDevice *dev)
_______________________________________________ http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org IRC: #milkym...@freenode Webchat: www.milkymist.org/irc.html Wiki: www.milkymist.org/wiki