All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Frediano Ziglio <freddy77@gmail.com>,
	Stefan Hajnoczi <stefanha@redhat.com>
Subject: [Qemu-devel] [PULL v4 02/11] tests: rtl8139: test timers and interrupt
Date: Thu, 12 Mar 2015 14:33:19 +0000	[thread overview]
Message-ID: <1426170808-6343-3-git-send-email-stefanha@redhat.com> (raw)
In-Reply-To: <1426170808-6343-1-git-send-email-stefanha@redhat.com>

From: Frediano Ziglio <freddy77@gmail.com>

Test behaviour of timers and interrupts related to timeouts.

Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1420742303-3030-1-git-send-email-freddy77@gmail.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/Makefile       |   2 +-
 tests/rtl8139-test.c | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 182 insertions(+), 1 deletion(-)

diff --git a/tests/Makefile b/tests/Makefile
index 588f438..1ef95c9 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -332,7 +332,7 @@ tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
 tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
 tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
 tests/e1000-test$(EXESUF): tests/e1000-test.o
-tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o
+tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o $(libqos-pc-obj-y)
 tests/pcnet-test$(EXESUF): tests/pcnet-test.o
 tests/eepro100-test$(EXESUF): tests/eepro100-test.o
 tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
diff --git a/tests/rtl8139-test.c b/tests/rtl8139-test.c
index f6a1be3..4e0bf02 100644
--- a/tests/rtl8139-test.c
+++ b/tests/rtl8139-test.c
@@ -10,19 +10,200 @@
 #include <glib.h>
 #include <string.h>
 #include "libqtest.h"
+#include "libqos/pci-pc.h"
 #include "qemu/osdep.h"
+#include "qemu-common.h"
 
 /* Tests only initialization so far. TODO: Replace with functional tests */
 static void nop(void)
 {
 }
 
+#define CLK 33000000
+#define NS_PER_SEC 1000000000ULL
+
+static QPCIBus *pcibus;
+static QPCIDevice *dev;
+static void *dev_base;
+
+static void save_fn(QPCIDevice *dev, int devfn, void *data)
+{
+    QPCIDevice **pdev = (QPCIDevice **) data;
+
+    *pdev = dev;
+}
+
+static QPCIDevice *get_device(void)
+{
+    QPCIDevice *dev;
+
+    pcibus = qpci_init_pc();
+    qpci_device_foreach(pcibus, 0x10ec, 0x8139, save_fn, &dev);
+    g_assert(dev != NULL);
+
+    return dev;
+}
+
+#define PORT(name, len, val) \
+static unsigned __attribute__((unused)) in_##name(void) \
+{ \
+    unsigned res = qpci_io_read##len(dev, dev_base+(val)); \
+    g_test_message("*%s -> %x\n", #name, res); \
+    return res; \
+} \
+static void out_##name(unsigned v) \
+{ \
+    g_test_message("%x -> *%s\n", v, #name); \
+    qpci_io_write##len(dev, dev_base+(val), v); \
+}
+
+PORT(Timer, l, 0x48)
+PORT(IntrMask, w, 0x3c)
+PORT(IntrStatus, w, 0x3E)
+PORT(TimerInt, l, 0x54)
+
+#define fatal(...) do { g_test_message(__VA_ARGS__); g_assert(0); } while (0)
+
+static void test_timer(void)
+{
+    const unsigned from = 0.95 * CLK;
+    const unsigned to = 1.6 * CLK;
+    unsigned prev, curr, next;
+    unsigned cnt, diff;
+
+    out_IntrMask(0);
+
+    in_IntrStatus();
+    in_Timer();
+    in_Timer();
+
+    /* Test 1. test counter continue and continue */
+    out_TimerInt(0); /* disable timer */
+    out_IntrStatus(0x4000);
+    out_Timer(12345); /* reset timer to 0 */
+    curr = in_Timer();
+    if (curr > 0.1 * CLK) {
+        fatal("time too big %u\n", curr);
+    }
+    for (cnt = 0; ; ) {
+        clock_step(1 * NS_PER_SEC);
+        prev = curr;
+        curr = in_Timer();
+
+        /* test skip is in a specific range */
+        diff = (curr-prev) & 0xffffffffu;
+        if (diff < from || diff > to) {
+            fatal("Invalid diff %u (%u-%u)\n", diff, from, to);
+        }
+        if (curr < prev && ++cnt == 3) {
+            break;
+        }
+    }
+
+    /* Test 2. Check we didn't get an interrupt with TimerInt == 0 */
+    if (in_IntrStatus() & 0x4000) {
+        fatal("got an interrupt\n");
+    }
+
+    /* Test 3. Setting TimerInt to 1 and Timer to 0 get interrupt */
+    out_TimerInt(1);
+    out_Timer(0);
+    clock_step(40);
+    if ((in_IntrStatus() & 0x4000) == 0) {
+        fatal("we should have an interrupt here!\n");
+    }
+
+    /* Test 3. Check acknowledge */
+    out_IntrStatus(0x4000);
+    if (in_IntrStatus() & 0x4000) {
+        fatal("got an interrupt\n");
+    }
+
+    /* Test. Status set after Timer reset */
+    out_Timer(0);
+    out_TimerInt(0);
+    out_IntrStatus(0x4000);
+    curr = in_Timer();
+    out_TimerInt(curr + 0.5 * CLK);
+    clock_step(1 * NS_PER_SEC);
+    out_Timer(0);
+    if ((in_IntrStatus() & 0x4000) == 0) {
+        fatal("we should have an interrupt here!\n");
+    }
+
+    /* Test. Status set after TimerInt reset */
+    out_Timer(0);
+    out_TimerInt(0);
+    out_IntrStatus(0x4000);
+    curr = in_Timer();
+    out_TimerInt(curr + 0.5 * CLK);
+    clock_step(1 * NS_PER_SEC);
+    out_TimerInt(0);
+    if ((in_IntrStatus() & 0x4000) == 0) {
+        fatal("we should have an interrupt here!\n");
+    }
+
+    /* Test 4. Increment TimerInt we should see an interrupt */
+    curr = in_Timer();
+    next = curr + 5.0 * CLK;
+    out_TimerInt(next);
+    for (cnt = 0; ; ) {
+        clock_step(1 * NS_PER_SEC);
+        prev = curr;
+        curr = in_Timer();
+        diff = (curr-prev) & 0xffffffffu;
+        if (diff < from || diff > to) {
+            fatal("Invalid diff %u (%u-%u)\n", diff, from, to);
+        }
+        if (cnt < 3 && curr > next) {
+            if ((in_IntrStatus() & 0x4000) == 0) {
+                fatal("we should have an interrupt here!\n");
+            }
+            out_IntrStatus(0x4000);
+            next = curr + 5.0 * CLK;
+            out_TimerInt(next);
+            if (++cnt == 3) {
+                out_TimerInt(1);
+            }
+        /* Test 5. Second time we pass from 0 should see an interrupt */
+        } else if (cnt >= 3 && curr < prev) {
+            /* here we should have an interrupt */
+            if ((in_IntrStatus() & 0x4000) == 0) {
+                fatal("we should have an interrupt here!\n");
+            }
+            out_IntrStatus(0x4000);
+            if (++cnt == 5) {
+                break;
+            }
+        }
+    }
+
+    g_test_message("Everythink is ok!\n");
+}
+
+
+static void test_init(void)
+{
+    uint64_t barsize;
+
+    dev = get_device();
+
+    dev_base = qpci_iomap(dev, 0, &barsize);
+
+    g_assert(dev_base != NULL);
+
+    qpci_device_enable(dev);
+
+    test_timer();
+}
+
 int main(int argc, char **argv)
 {
     int ret;
 
     g_test_init(&argc, &argv, NULL);
     qtest_add_func("/rtl8139/nop", nop);
+    qtest_add_func("/rtl8139/timer", test_init);
 
     qtest_start("-device rtl8139");
     ret = g_test_run();
-- 
2.1.0

  parent reply	other threads:[~2015-03-12 14:33 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-12 14:33 [Qemu-devel] [PULL v4 00/11] Net patches Stefan Hajnoczi
2015-03-12 14:33 ` [Qemu-devel] [PULL v4 01/11] net: synchronize net_host_device_remove with host_net_remove_completion Stefan Hajnoczi
2015-03-12 14:33 ` Stefan Hajnoczi [this message]
2015-03-12 14:33 ` [Qemu-devel] [PULL v4 03/11] net: add MAC address string printer Stefan Hajnoczi
2015-03-12 14:33 ` [Qemu-devel] [PULL v4 04/11] virtio-net: use qemu_mac_strdup_printf Stefan Hajnoczi
2015-03-12 14:33 ` [Qemu-devel] [PULL v4 05/11] rocker: add register programming guide Stefan Hajnoczi
2015-03-12 14:33 ` [Qemu-devel] [PULL v4 06/11] pci: add rocker device ID Stefan Hajnoczi
2015-03-12 14:33 ` [Qemu-devel] [PULL v4 07/11] pci: add network device class 'other' for network switches Stefan Hajnoczi
2015-03-12 14:33 ` [Qemu-devel] [PULL v4 08/11] rocker: add new rocker switch device Stefan Hajnoczi
2015-03-12 14:33 ` [Qemu-devel] [PULL v4 09/11] rocker: add tests Stefan Hajnoczi
2015-03-12 14:33 ` [Qemu-devel] [PULL v4 10/11] MAINTAINERS: add rocker Stefan Hajnoczi
2015-03-12 14:33 ` [Qemu-devel] [PULL v4 11/11] rocker: timestamp on the debug logs helps correlate with events in the VM Stefan Hajnoczi
2015-03-12 14:43 ` [Qemu-devel] [PULL v4 00/11] Net patches Peter Maydell
2015-03-12 15:03   ` Peter Maydell
2015-03-12 17:50     ` Stefan Hajnoczi
2015-03-12 20:17       ` Peter Maydell
2015-03-13  2:32       ` Fam Zheng
2015-03-13 10:16         ` Peter Maydell
2015-03-12 19:58     ` Stefan Hajnoczi
2015-03-12 20:48       ` Paolo Bonzini
2015-03-14  4:19       ` Scott Feldman
2015-03-16  9:41         ` Peter Maydell

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=1426170808-6343-3-git-send-email-stefanha@redhat.com \
    --to=stefanha@redhat.com \
    --cc=freddy77@gmail.com \
    --cc=peter.maydell@linaro.org \
    --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.