Message ID | 1420742303-3030-1-git-send-email-freddy77@gmail.com |
---|---|
State | New |
Headers | show |
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(); >
On 20/01/2015 14:36, Paolo Bonzini wrote: > 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. :) Oh, that patch wasn't committed, it wast just an RFC... and it would have broken something. :) Your test was very helpful; I've sent a version that passes it now. Thanks! Paolo
2015-01-20 13:36 GMT+00:00 Paolo Bonzini <pbonzini@redhat.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 > Hi, sorry I didn't get everything. Was my patch/test fine or should I change something? I saw you posted a patch for timer. Was your patch tested with my code and you find some problems or was my patch that had some problems? Regards, Frediano >> >> 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(); >>
On 22/01/2015 13:33, Frediano Ziglio wrote: > Hi, > sorry I didn't get everything. Was my patch/test fine or should I > change something? Your patch is ok as far as I'm concerned. > I saw you posted a patch for timer. Was your patch > tested with my code and you find some problems or was my patch that > had some problems? I found bugs in an earlier version of my patch, thanks to your test. (I hadn't submitted that patch because indeed I wasn't confident that it worked). So now that I tested it, I could submit it in good conscience! Paolo
This patch is marked as RFC, but I think it should be included. Stefan/Jason, can you pull it in the next net pull request? Paolo 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? > > 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(); >
On Thu, Jan 08, 2015 at 06:38:23PM +0000, 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? > > Changed from v2: > - style (variable declaration, Perl script not able to spot it) > > Changed from v1: > - style Thanks, applied to my net tree: https://github.com/stefanha/qemu/commits/net
2015-02-06 16:54 GMT+00:00 Stefan Hajnoczi <stefanha@redhat.com>: > On Thu, Jan 08, 2015 at 06:38:23PM +0000, 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? >> >> Changed from v2: >> - style (variable declaration, Perl script not able to spot it) >> >> Changed from v1: >> - style > > Thanks, applied to my net tree: > https://github.com/stefanha/qemu/commits/net Hi, all the comments seems to refer to my patch for testing the card but from https://github.com/stefanha/qemu/commits/net looks like you applied Paolo patch. Is it expected? Regards, Frediano
On Fri, Feb 06, 2015 at 05:07:17PM +0000, Frediano Ziglio wrote: > 2015-02-06 16:54 GMT+00:00 Stefan Hajnoczi <stefanha@redhat.com>: > > On Thu, Jan 08, 2015 at 06:38:23PM +0000, 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? > >> > >> Changed from v2: > >> - style (variable declaration, Perl script not able to spot it) > >> > >> Changed from v1: > >> - style > > > > Thanks, applied to my net tree: > > https://github.com/stefanha/qemu/commits/net > > Hi, > all the comments seems to refer to my patch for testing the card but > from https://github.com/stefanha/qemu/commits/net looks like you > applied Paolo patch. > > Is it expected? Sorry, it didn't make it into last week's net pull request due to a mistake. It will be included in the next net pull request: https://github.com/stefanha/qemu/commits/net Stefan
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();
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? Changed from v2: - style (variable declaration, Perl script not able to spot it) Changed from v1: - style