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

Reply via email to