All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tim Deegan <Tim.Deegan@citrix.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] Rework the RTL8139C timer interrupts and enable them by default
Date: Mon, 15 Dec 2008 15:42:58 +0000	[thread overview]
Message-ID: <20081215154258.GD23562@york.uk.xensource.com> (raw)

Reorganise the RTL8139 rolling timer so that it calculates the counter
on read instead of updating it in real time, and only sets a timer when
the guest has programmed a timer interrupt.

Enable it by default since it should have no overhead for guests that
don't use it, and OpenBSD's rtl8139 driver relies on it.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
---
 rtl8139.c |   87 ++++++++++++++++++++++++++++++--------------------------------
 1 file changed, 43 insertions(+), 44 deletions(-)

Index: hw/rtl8139.c
===================================================================
--- hw/rtl8139.c	(revision 6042)
+++ hw/rtl8139.c	(working copy)
@@ -59,8 +59,8 @@
 /* Calculate CRCs properly on Rx packets */
 #define RTL8139_CALCULATE_RXCRC 1
 
-/* Uncomment to enable on-board timer interrupts */
-//#define RTL8139_ONBOARD_TIMER 1
+/* Enable on-board timer interrupts */
+#define RTL8139_ONBOARD_TIMER 1
 
 #if defined(RTL8139_CALCULATE_RXCRC)
 /* For crc32 */
@@ -497,6 +497,37 @@
 
 } RTL8139State;
 
+/* Fix up the TCTR field to match the current system time */
+static inline void rtl8139_update_tctr(RTL8139State *s, int64_t current_time)
+{
+    if (s->clock_enabled)
+        s->TCTR = muldiv64(current_time - s->TCTR_base, PCI_FREQUENCY, ticks_per_sec);
+}
+
+/* Queue a timer interrupt based on the state of the TCTR and TimerInt */
+static inline void rtl8139_set_tctr_timer(RTL8139State *s)
+{
+#if RTL8139_ONBOARD_TIMER
+    int64_t next_time;
+    int64_t curr_time = qemu_get_clock(vm_clock);
+
+    if (!s->clock_enabled || s->TimerInt == 0) 
+    {
+        DEBUG_PRINT(("RTL8139: >>> set timer: clock not running or timeout not set\n"));
+        return;
+    }
+
+    rtl8139_update_tctr(s, curr_time);
+    next_time = curr_time +
+        muldiv64((1 + s->TimerInt - s->TCTR), ticks_per_sec, PCI_FREQUENCY);
+
+    if (next_time <= curr_time)
+        next_time = curr_time + 1;
+
+    qemu_mod_timer(s->timer, next_time);
+#endif
+}
+
 static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
 {
     DEBUG_PRINT(("RTL8139: eeprom command 0x%02x\n", command));
@@ -2788,11 +2819,13 @@
             DEBUG_PRINT(("RTL8139: TCTR Timer reset on write\n"));
             s->TCTR = 0;
             s->TCTR_base = qemu_get_clock(vm_clock);
+            rtl8139_set_tctr_timer(s);
             break;
 
         case FlashReg:
             DEBUG_PRINT(("RTL8139: FlashReg TimerInt write val=0x%08x\n", val));
             s->TimerInt = val;
+            rtl8139_set_tctr_timer(s);
             break;
 
         default:
@@ -3002,6 +3035,7 @@
             break;
 
         case Timer:
+            rtl8139_update_tctr(s, qemu_get_clock(vm_clock));
             ret = s->TCTR;
             DEBUG_PRINT(("RTL8139: TCTR Timer read val=0x%08x\n", ret));
             break;
@@ -3287,6 +3321,7 @@
         qemu_get_be32s(f, &s->TimerInt);
         s->TCTR_base=qemu_get_be64(f);
 
+        rtl8139_set_tctr_timer(s);
         RTL8139TallyCounters_load(f, &s->tally_counters);
     }
     else
@@ -3347,56 +3382,23 @@
     rtl8139_mmio_writel,
 };
 
-static inline int64_t rtl8139_get_next_tctr_time(RTL8139State *s, int64_t current_time)
-{
-    int64_t next_time = current_time +
-        muldiv64(1, ticks_per_sec, PCI_FREQUENCY);
-    if (next_time <= current_time)
-        next_time = current_time + 1;
-    return next_time;
-}
-
 #ifdef RTL8139_ONBOARD_TIMER
 static void rtl8139_timer(void *opaque)
 {
     RTL8139State *s = opaque;
 
-    int is_timeout = 0;
-
-    int64_t  curr_time;
-    uint32_t curr_tick;
-
-    if (!s->clock_enabled)
+    if (!s->clock_enabled || s->TimerInt == 0)
     {
-        DEBUG_PRINT(("RTL8139: >>> timer: clock is not running\n"));
+        DEBUG_PRINT(("RTL8139: >>> timer: clock not running or timeout not set\n"));
         return;
     }
 
-    curr_time = qemu_get_clock(vm_clock);
+    s->IntrStatus |= PCSTimeout;
+    rtl8139_update_irq(s);
 
-    curr_tick = muldiv64(curr_time - s->TCTR_base, PCI_FREQUENCY, ticks_per_sec);
+    rtl8139_set_tctr_timer(s);
 
-    if (s->TimerInt && curr_tick >= s->TimerInt)
-    {
-        if (s->TCTR < s->TimerInt || curr_tick < s->TCTR)
-        {
-            is_timeout = 1;
-        }
-    }
-
-    s->TCTR = curr_tick;
-
-//  DEBUG_PRINT(("RTL8139: >>> timer: tick=%08u\n", s->TCTR));
-
-    if (is_timeout)
-    {
-        DEBUG_PRINT(("RTL8139: >>> timer: timeout tick=%08u\n", s->TCTR));
-        s->IntrStatus |= PCSTimeout;
-        rtl8139_update_irq(s);
-    }
-
-    qemu_mod_timer(s->timer,
-        rtl8139_get_next_tctr_time(s,curr_time));
+    DEBUG_PRINT(("RTL8139: >>> timer: timeout tick=%08u (%08u)\n", s->TCTR, s->TimerInt));
 }
 #endif /* RTL8139_ONBOARD_TIMER */
 
@@ -3458,8 +3460,5 @@
 
 #ifdef RTL8139_ONBOARD_TIMER
     s->timer = qemu_new_timer(vm_clock, rtl8139_timer, s);
-
-    qemu_mod_timer(s->timer,
-        rtl8139_get_next_tctr_time(s,qemu_get_clock(vm_clock)));
 #endif /* RTL8139_ONBOARD_TIMER */
 }

                 reply	other threads:[~2008-12-15 15:43 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20081215154258.GD23562@york.uk.xensource.com \
    --to=tim.deegan@citrix.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.