[PATCH 1/2] hw/timer/xilinx_timer: Start on the enable edge

Sebastian Huber <[email protected]>
Newsgroups org.nongnu.qemu-devel
Message-ID <[email protected]>
Every write to a control register which has the enable bit set
restarted the count from the load value.  A guest which clears the
interrupt of a periodic timer writes that register with the enable bit
still set, so every period gained the latency of the interrupt.

Start the count only where the enable bit goes from zero to one.

Signed-off-by: Sebastian Huber <[email protected]>
---
 hw/timer/xilinx_timer.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c
index 8a502dae0e..dff439c623 100644
--- a/hw/timer/xilinx_timer.c
+++ b/hw/timer/xilinx_timer.c
@@ -175,17 +175,25 @@ timer_write(void *opaque, hwaddr addr,
     addr &= 3;
     switch (addr) 
     {
-        case R_TCSR:
+        case R_TCSR: {
+            uint32_t old = xt->regs[R_TCSR];
+
             if (value & TCSR_TINT)
                 value &= ~TCSR_TINT;
 
             xt->regs[addr] = value & 0x7ff;
-            if (value & TCSR_ENT) {
+            /*
+             * Only a transition of the enable bit to one starts the count.
+             * A write which leaves the bit set, such as the acknowledge of
+             * an interrupt, does not restart it.
+             */
+            if ((value & TCSR_ENT) && !(old & TCSR_ENT)) {
                 ptimer_transaction_begin(xt->ptimer);
                 timer_enable(xt);
                 ptimer_transaction_commit(xt->ptimer);
             }
             break;
+        }
  
         default:
             if (addr < ARRAY_SIZE(xt->regs))
-- 
2.51.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.