All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Frediano Ziglio <freddy77@gmail.com>, Fam Zheng <famz@redhat.com>,
	Stefan Hajnoczi <stefanha@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [RFC PATCH v3] tests: rtl8139: test timers and interrupt
Date: Tue, 20 Jan 2015 14:36:36 +0100	[thread overview]
Message-ID: <54BE59E4.7090600@redhat.com> (raw)
In-Reply-To: <1420742303-3030-1-git-send-email-freddy77@gmail.com>



On 08/01/2015 19:38, Frediano Ziglio wrote:
> Test behaviour of timers and interrupts related to timeouts.
> 
> Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
> ---
>  tests/Makefile       |   2 +-
>  tests/rtl8139-test.c | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 182 insertions(+), 1 deletion(-)
> 
> This patch was derived from a test I did while implementing timer in
> rtl8139 code. Now that there is support for integrated testing I converted
> it. The test was tested on a real NIC.
> 
> As if it's the first test I wrote I don't know if syntax and details are
> fine. For instance should I remove nop test? Should I split my test?

Respectively, no and if you want.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

As the last person who touched the rtl8139 timer code, I'm glad I didn't
break anything. :)

Paolo

> 
> Changed from v2:
> - style (variable declaration, Perl script not able to spot it)
> 
> Changed from v1:
> - style
> 
> diff --git a/tests/Makefile b/tests/Makefile
> index e4ddb6a..8858407 100644
> --- a/tests/Makefile
> +++ b/tests/Makefile
> @@ -320,7 +320,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();
> 

  reply	other threads:[~2015-01-20 13:36 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-08 18:38 [Qemu-devel] [RFC PATCH v3] tests: rtl8139: test timers and interrupt Frediano Ziglio
2015-01-20 13:36 ` Paolo Bonzini [this message]
2015-01-20 14:46   ` Paolo Bonzini
2015-01-22 12:33   ` Frediano Ziglio
2015-01-22 12:35     ` Paolo Bonzini
2015-02-06 14:48 ` Paolo Bonzini
2015-02-06 16:54 ` Stefan Hajnoczi
2015-02-06 17:07   ` Frediano Ziglio
2015-02-09 10:21     ` Stefan Hajnoczi

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=54BE59E4.7090600@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=famz@redhat.com \
    --cc=freddy77@gmail.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /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.