qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH 0/9] qtest fixes and alternative IRQ intercept proposal
@ 2012-01-18 10:33 Paolo Bonzini
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 1/9] qtest: always send a response Paolo Bonzini
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Paolo Bonzini @ 2012-01-18 10:33 UTC (permalink / raw)
  To: qemu-devel

Anthony,

here are some random qtest patches, for incorporation in your series or
just as food for thought.

Patch 1 makes the tests fail with an assertion failure if libqtest screws
up, rather than just having them sit waiting for a response that will
never come.

Patch 2 makes "-qtest stdio" a bit more useful.

Patch 3 is a fix for the Makefile, which happens when tests fail.

Patch 4 is a fix for some bogus code in the rtc test that GCC flagged.

Patch 5 actually implements the idea of not using TCG for the CPU threads.
Since this is quite easy to do I don't see why not (for example, would you
like to have qtest depend on TCG if your disable-tcg series ever lands?).

Patches 6-9 replace the qtest interrupt controller with interception
on the qtest side.  The idea is to pass a device to a qtest command.
qtest then patches the qemu_irqs for the gpio pins so that, when they
trigger, the notification is sent on the qtest chardev.  Right you can
attach only to one device, and only to either the output side or the
input side.  But even this is already enormously more flexible and IMO
cleaner than the qtest_interrupt_controller.

Attaching to the output side would usually be better for unit testing
of a single device, but not many devices on a PC register gpio pins.
Luckily, one such device is (on the input side) the ioapic, so that
irq_intercept_in("ioapic") provides the exact same behavior as the
qtest_interrupt_controller in your code.

In the future, once gpio pins are converted Pin properties, the commands
could be modified like

   irq_intercept_{in,out} QOM-PATH PROPERTY NUM

which maps the given property to a qtest interrupt number.  In the
meanwhile, the interface works nicely and provides a bit more QOM
dogfooding (as shown by the need for patch 6).

All patches except patch 6 are meant to be squashed in yours; sending
them this way is easier for review and just one "git rebase -i" apart
from the desired result.  Hence the scant commit messages. :)

Paolo Bonzini (9):
  qtest: always send a response
  qtest: enable echo
  qtest: fix Makefile
  rtc-test: fix set_alarm_time
  qtest: do not use TCG CPU threads
  pc: attach ioapic to the QOM composition tree
  qtest: IRQ interception infrastructure
  libqtest: add IRQ intercept commands
  rtc-test: add IRQ intercept

 cpu-exec.c       |    4 --
 cpus.c           |   62 ++++++++++++++++++++++++++++++++--
 hw/irq.c         |   18 ++++++++++
 hw/irq.h         |    3 ++
 hw/pc_piix.c     |    9 +++--
 qtest.c          |  100 +++++++++++++++++++++++++++++++++++++----------------
 qtest.h          |    2 -
 tests/Makefile   |    2 +-
 tests/libqtest.c |   12 ++++++
 tests/libqtest.h |    6 +++
 tests/rtc-test.c |   23 +++----------
 11 files changed, 179 insertions(+), 62 deletions(-)

-- 
1.7.7.1

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 1/9] qtest: always send a response
  2012-01-18 10:33 [Qemu-devel] [RFC PATCH 0/9] qtest fixes and alternative IRQ intercept proposal Paolo Bonzini
@ 2012-01-18 10:33 ` Paolo Bonzini
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 2/9] qtest: enable echo Paolo Bonzini
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2012-01-18 10:33 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 qtest.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/qtest.c b/qtest.c
index f41a9c3..abfdab9 100644
--- a/qtest.c
+++ b/qtest.c
@@ -241,7 +241,8 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
         qtest_send_prefix(chr);
         qtest_send(chr, "OK\n");
     } else {
-        fprintf(stderr, "Unknown command `%s'\n", words[0]);
+        qtest_send_prefix(chr);
+        qtest_send(chr, "FAIL Unknown command `%s'\n", words[0]);
     }
 }
 
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 2/9] qtest: enable echo
  2012-01-18 10:33 [Qemu-devel] [RFC PATCH 0/9] qtest fixes and alternative IRQ intercept proposal Paolo Bonzini
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 1/9] qtest: always send a response Paolo Bonzini
@ 2012-01-18 10:33 ` Paolo Bonzini
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 3/9] qtest: fix Makefile Paolo Bonzini
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2012-01-18 10:33 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 qtest.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/qtest.c b/qtest.c
index abfdab9..c2fbf50 100644
--- a/qtest.c
+++ b/qtest.c
@@ -341,6 +341,7 @@ int qtest_init(void)
     chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
 
     qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr);
+    qemu_chr_fe_set_echo(chr, true);
 
     inbuf = g_string_new("");
 
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 3/9] qtest: fix Makefile
  2012-01-18 10:33 [Qemu-devel] [RFC PATCH 0/9] qtest fixes and alternative IRQ intercept proposal Paolo Bonzini
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 1/9] qtest: always send a response Paolo Bonzini
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 2/9] qtest: enable echo Paolo Bonzini
@ 2012-01-18 10:33 ` Paolo Bonzini
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 4/9] rtc-test: fix set_alarm_time Paolo Bonzini
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2012-01-18 10:33 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 tests/Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/tests/Makefile b/tests/Makefile
index a6b993c..6acb3e2 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -77,7 +77,7 @@ check-qtest-%: $(HW_TESTS)
 	@for test in $^; do \
 	    arch=`echo $@ | cut -f3- -d-`; \
 	    echo "Running '$$test' with qemu-system-$$arch..."; \
-	    $(SRC_PATH)/scripts/qtest $$arch-softmmu/qemu-system-$$arch $$test || exit $?; \
+	    $(SRC_PATH)/scripts/qtest $$arch-softmmu/qemu-system-$$arch $$test || exit $$?; \
 	done
 
 check-qtest: $(patsubst %,check-qtest-%, $(TARGETS))
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 4/9] rtc-test: fix set_alarm_time
  2012-01-18 10:33 [Qemu-devel] [RFC PATCH 0/9] qtest fixes and alternative IRQ intercept proposal Paolo Bonzini
                   ` (2 preceding siblings ...)
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 3/9] qtest: fix Makefile Paolo Bonzini
@ 2012-01-18 10:33 ` Paolo Bonzini
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 5/9] qtest: do not use TCG CPU threads Paolo Bonzini
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2012-01-18 10:33 UTC (permalink / raw)
  To: qemu-devel

GCC (correctly) reports uninitialized variables.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 tests/rtc-test.c |   22 ++++------------------
 1 files changed, 4 insertions(+), 18 deletions(-)

diff --git a/tests/rtc-test.c b/tests/rtc-test.c
index 7f0b590..1645b34 100644
--- a/tests/rtc-test.c
+++ b/tests/rtc-test.c
@@ -195,26 +195,12 @@ static void dec_check_time(void)
 
 static void set_alarm_time(struct tm *tm)
 {
-    int sec, min, hour;
-    int hour_offset;
-
-    sec = tm->tm_sec - 1;
+    int sec;
 
+    sec = tm->tm_sec;
 
     if ((cmos_read(RTC_REG_B) & REG_B_DM) == 0) {
         sec = dec2bcd(sec);
-        min = dec2bcd(min);
-        hour = dec2bcd(hour);
-        hour_offset = 80;
-    } else {
-        hour_offset = 0x80;
-    }
-
-    if ((cmos_read(RTC_REG_B) & REG_B_24H) != 0) {
-        if (hour >= 12) {
-            hour -= 12;
-            hour += hour_offset;
-        }
     }
 
     cmos_write(RTC_SECONDS_ALARM, sec);
@@ -236,11 +222,11 @@ static void alarm_time(void)
 
     g_assert(!get_irq(RTC_ISA_IRQ));
 
-    now.tm_sec += 1;
+    now.tm_sec = (now.tm_sec + 2) % 60;
     set_alarm_time(&now);
     cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) | REG_B_AIE);
 
-    for (i = 0; i < 1 + wiggle; i++) {
+    for (i = 0; i < 2 + wiggle; i++) {
         if (get_irq(RTC_ISA_IRQ)) {
             break;
         }
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 5/9] qtest: do not use TCG CPU threads
  2012-01-18 10:33 [Qemu-devel] [RFC PATCH 0/9] qtest fixes and alternative IRQ intercept proposal Paolo Bonzini
                   ` (3 preceding siblings ...)
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 4/9] rtc-test: fix set_alarm_time Paolo Bonzini
@ 2012-01-18 10:33 ` Paolo Bonzini
  2012-01-18 10:53   ` Andreas Färber
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 6/9] pc: attach ioapic to the QOM composition tree Paolo Bonzini
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Paolo Bonzini @ 2012-01-18 10:33 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpu-exec.c |    4 ---
 cpus.c     |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index bf5a2aa..4cb079f 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -189,10 +189,6 @@ int cpu_exec(CPUState *env)
     uint8_t *tc_ptr;
     unsigned long next_tb;
 
-    if (qtest_enabled()) {
-        env->halted = 1;
-    }
-
     if (env->halted) {
         if (!cpu_has_work(env)) {
             return EXCP_HALTED;
diff --git a/cpus.c b/cpus.c
index 2dae549..c4ca26a 100644
--- a/cpus.c
+++ b/cpus.c
@@ -740,6 +740,48 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
     return NULL;
 }
 
+static void *qemu_dummy_cpu_thread_fn(void *arg)
+{
+#ifdef _WIN32
+    fprintf(stderr, "qtest is not supported under Windows\n");
+    exit(1);
+#else
+    CPUState *env = arg;
+    sigset_t waitset;
+    int r;
+
+    qemu_mutex_lock_iothread();
+    qemu_thread_get_self(env->thread);
+    env->thread_id = qemu_get_thread_id();
+
+    sigemptyset(&waitset);
+    sigaddset(&waitset, SIG_IPI);
+
+    /* signal CPU creation */
+    env->created = 1;
+    qemu_cond_signal(&qemu_cpu_cond);
+
+    cpu_single_env = env;
+    while (1) {
+        cpu_single_env = NULL;
+        qemu_mutex_unlock_iothread();
+        do {
+            int sig;
+            r = sigwait(&waitset, &sig);
+        } while (r == -1 && (errno == EAGAIN || errno == EINTR));
+        if (r == -1) {
+            perror("sigwait");
+            exit(1);
+        }
+        qemu_mutex_lock_iothread();
+        cpu_single_env = env;
+        qemu_wait_io_event_common(env);
+    }
+
+    return NULL; 
+#endif
+}
+
 static void tcg_exec_all(void);
 
 static void *qemu_tcg_cpu_thread_fn(void *arg)
@@ -797,7 +839,7 @@ void qemu_cpu_kick(void *_env)
     CPUState *env = _env;
 
     qemu_cond_broadcast(env->halt_cond);
-    if (kvm_enabled() && !env->thread_kicked) {
+    if (!tcg_enabled() && !env->thread_kicked) {
         qemu_cpu_kick_thread(env);
         env->thread_kicked = true;
     }
@@ -826,7 +868,7 @@ int qemu_cpu_is_self(void *_env)
 
 void qemu_mutex_lock_iothread(void)
 {
-    if (kvm_enabled()) {
+    if (!tcg_enabled()) {
         qemu_mutex_lock(&qemu_global_mutex);
     } else {
         iothread_requesting_mutex = true;
@@ -929,6 +971,18 @@ static void qemu_kvm_start_vcpu(CPUState *env)
     }
 }
 
+static void qemu_dummy_start_vcpu(CPUState *env)
+{
+    env->thread = g_malloc0(sizeof(QemuThread));
+    env->halt_cond = g_malloc0(sizeof(QemuCond));
+    qemu_cond_init(env->halt_cond);
+    qemu_thread_create(env->thread, qemu_dummy_cpu_thread_fn, env,
+                       QEMU_THREAD_JOINABLE);
+    while (env->created == 0) {
+        qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
+    }
+}
+
 void qemu_init_vcpu(void *_env)
 {
     CPUState *env = _env;
@@ -938,8 +992,10 @@ void qemu_init_vcpu(void *_env)
     env->stopped = 1;
     if (kvm_enabled()) {
         qemu_kvm_start_vcpu(env);
-    } else {
+    } else if (tcg_enabled()) {
         qemu_tcg_init_vcpu(env);
+    } else {
+        qemu_dummy_start_vcpu(env);
     }
 }
 
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 6/9] pc: attach ioapic to the QOM composition tree
  2012-01-18 10:33 [Qemu-devel] [RFC PATCH 0/9] qtest fixes and alternative IRQ intercept proposal Paolo Bonzini
                   ` (4 preceding siblings ...)
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 5/9] qtest: do not use TCG CPU threads Paolo Bonzini
@ 2012-01-18 10:33 ` Paolo Bonzini
  2012-01-24 15:12   ` Jan Kiszka
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 7/9] qtest: IRQ interception infrastructure Paolo Bonzini
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Paolo Bonzini @ 2012-01-18 10:33 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/pc_piix.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 2aba89c..3f92bf9 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -54,7 +54,7 @@ static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 };
 static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
 static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
 
-static void ioapic_init(GSIState *gsi_state)
+static DeviceState *ioapic_init(GSIState *gsi_state)
 {
     DeviceState *dev;
     SysBusDevice *d;
@@ -68,6 +68,7 @@ static void ioapic_init(GSIState *gsi_state)
     for (i = 0; i < IOAPIC_NUM_PINS; i++) {
         gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
     }
+    return dev;
 }
 
 /* PC hardware initialisation */
@@ -168,7 +169,9 @@ static void pc_init1(MemoryRegion *system_memory,
         gsi_state->i8259_irq[i] = i8259[i];
     }
     if (pci_enabled) {
-        ioapic_init(gsi_state);
+        dev = ioapic_init(gsi_state);
+        qdev_property_add_child(qdev_resolve_path("/i440fx/piix3", NULL),
+                                "ioapic", dev, NULL);
     }
 
     pc_register_ferr_irq(gsi[13]);
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 7/9] qtest: IRQ interception infrastructure
  2012-01-18 10:33 [Qemu-devel] [RFC PATCH 0/9] qtest fixes and alternative IRQ intercept proposal Paolo Bonzini
                   ` (5 preceding siblings ...)
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 6/9] pc: attach ioapic to the QOM composition tree Paolo Bonzini
@ 2012-01-18 10:33 ` Paolo Bonzini
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 8/9] libqtest: add IRQ intercept commands Paolo Bonzini
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2012-01-18 10:33 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/irq.c     |   18 +++++++++++
 hw/irq.h     |    3 ++
 hw/pc_piix.c |    2 -
 qtest.c      |   96 ++++++++++++++++++++++++++++++++++++++++-----------------
 qtest.h      |    2 -
 5 files changed, 88 insertions(+), 33 deletions(-)

diff --git a/hw/irq.c b/hw/irq.c
index 62f766e..48c48e1 100644
--- a/hw/irq.c
+++ b/hw/irq.c
@@ -104,3 +104,20 @@ qemu_irq *qemu_irq_proxy(qemu_irq **target, int n)
 {
     return qemu_allocate_irqs(proxy_irq_handler, target, n);
 }
+
+void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
+{
+    int i;
+    qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n);
+    for (i = 0; i < n; i++) {
+        *old_irqs[i] = *gpio_in[i];
+        gpio_in[i]->handler = handler;
+        gpio_in[i]->opaque = old_irqs;
+    }
+}
+
+void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n)
+{
+    qemu_irq *old_irqs = *gpio_out;
+    *gpio_out = qemu_allocate_irqs(handler, old_irqs, n);
+}
diff --git a/hw/irq.h b/hw/irq.h
index 64da2fd..d2ff320 100644
--- a/hw/irq.h
+++ b/hw/irq.h
@@ -38,4 +38,9 @@ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
  */
 qemu_irq *qemu_irq_proxy(qemu_irq **target, int n);
 
+/* For internal use in qtest.  Similar to qemu_irq_split, but operating
+   on an existing vector of qemu_irq.  */
+void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
+void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n);
+
 #endif
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 3f92bf9..9dea2dc 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -158,8 +158,6 @@ static void pc_init1(MemoryRegion *system_memory,
 
     if (xen_enabled()) {
         i8259 = xen_interrupt_controller_init();
-    } else if (qtest_enabled()) {
-        i8259 = qtest_interrupt_controller_init();
     } else {
         cpu_irq = pc_allocate_cpu_irq();
         i8259 = i8259_init(isa_bus, cpu_irq[0]);
diff --git a/qtest.c b/qtest.c
index c2fbf50..010befe 100644
--- a/qtest.c
+++ b/qtest.c
@@ -12,6 +12,7 @@
  */
 
 #include "qtest.h"
+#include "hw/qdev.h"
 #include "qemu-char.h"
 #include "ioport.h"
 #include "memory.h"
@@ -24,6 +25,7 @@ const char *qtest_chrdev;
 const char *qtest_log;
 int qtest_allowed = 0;
 
+static DeviceState *irq_intercept_dev;
 static FILE *qtest_log_fp;
 static CharDriverState *qtest_chr;
 static GString *inbuf;
@@ -66,18 +68,30 @@ static bool qtest_opened;
  *  > write ADDR SIZE DATA
  *  < OK
  *
- * Valid async messages:
- *
- *  IRQ raise NUM
- *  IRQ lower NUM
- *
  * ADDR, SIZE, VALUE are all integers parsed with strtoul() with a base of 0.
  *
  * DATA is an arbitrarily long hex number prefixed with '0x'.  If it's smaller
  * than the expected size, the value will be zero filled at the end of the data
  * sequence.
  *
- * NUM is an IRQ number.
+ * IRQ management:
+ *
+ *  > irq_intercept_in QOM-PATH
+ *  < OK
+ *
+ *  > irq_intercept_out QOM-PATH
+ *  < OK
+ *
+ * Attach to the gpio-in (resp. gpio-out) pins exported by the device at
+ * QOM-PATH.  When the pin is triggered, one of the following async messages
+ * will be printed to the qtest stream:
+ *
+ *  IRQ raise NUM
+ *  IRQ lower NUM
+ *
+ * where NUM is an IRQ number.  For the PC, interrupts can be intercepted
+ * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
+ * NUM=0 even though it is remapped to GSI 2).
  */
 
 static int hex2nib(char ch)
@@ -133,6 +146,20 @@ static void qtest_send(CharDriverState *chr, const char *fmt, ...)
     }
 }
 
+static void qtest_irq_handler(void *opaque, int n, int level)
+{
+    qemu_irq *old_irqs = opaque;
+    qemu_set_irq(old_irqs[n], level);
+
+    if (irq_levels[n] != level) {
+        CharDriverState *chr = qtest_chr;
+        irq_levels[n] = level;
+        qtest_send_prefix(chr);
+        qtest_send(chr, "IRQ %s %d\n",
+                   level ? "raise" : "lower", n);
+    }
+}
+
 static void qtest_process_command(CharDriverState *chr, gchar **words)
 {
     const gchar *command;
@@ -155,9 +182,40 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
     }
 
     g_assert(command);
-    if (strcmp(words[0], "outb") == 0 ||
-        strcmp(words[0], "outw") == 0 ||
-        strcmp(words[0], "outl") == 0) {
+    if (strcmp(words[0], "irq_intercept_out") == 0
+        || strcmp(words[0], "irq_intercept_in") == 0) {
+	DeviceState *dev;
+
+        g_assert(words[1]);
+        dev = qdev_resolve_path(words[1], NULL);
+        if (!dev) {
+            qtest_send_prefix(chr);
+            qtest_send(chr, "FAIL Unknown device\n");
+	    return;
+        }
+
+        if (irq_intercept_dev) {
+            qtest_send_prefix(chr);
+            if (irq_intercept_dev != dev) {
+                qtest_send(chr, "FAIL IRQ intercept already enabled\n");
+            } else {
+                qtest_send(chr, "OK\n");
+            }
+	    return;
+        }
+
+        if (words[0][14] == 'o') {
+            qemu_irq_intercept_out(&dev->gpio_out, qtest_irq_handler, dev->num_gpio_out);
+        } else {
+            qemu_irq_intercept_in(dev->gpio_in, qtest_irq_handler, dev->num_gpio_in);
+        }
+        irq_intercept_dev = dev;
+        qtest_send_prefix(chr);
+        qtest_send(chr, "OK\n");
+
+    } else if (strcmp(words[0], "outb") == 0 ||
+               strcmp(words[0], "outw") == 0 ||
+               strcmp(words[0], "outl") == 0) {
         uint16_t addr;
         uint32_t value;
 
@@ -312,26 +370,6 @@ static void qtest_event(void *opaque, int event)
     }
 }
 
-static void qtest_set_irq(void *opaque, int irq, int level)
-{
-    CharDriverState *chr = qtest_chr;
-    bool changed;
-
-    changed = (irq_levels[irq] != level);
-    irq_levels[irq] = level;
-
-    if (changed) {
-        qtest_send_prefix(chr);
-        qtest_send(chr, "IRQ %s %d\n",
-                   level ? "raise" : "lower", irq);
-    }
-}
-
-qemu_irq *qtest_interrupt_controller_init(void)
-{
-    return qemu_allocate_irqs(qtest_set_irq, NULL, MAX_IRQ);
-}
-
 int qtest_init(void)
 {
     CharDriverState *chr;
diff --git a/qtest.h b/qtest.h
index f0e1377..1478343 100644
--- a/qtest.h
+++ b/qtest.h
@@ -32,6 +32,4 @@ static inline int qtest_available(void)
 
 int qtest_init(void);
 
-qemu_irq *qtest_interrupt_controller_init(void);
-
 #endif
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 8/9] libqtest: add IRQ intercept commands
  2012-01-18 10:33 [Qemu-devel] [RFC PATCH 0/9] qtest fixes and alternative IRQ intercept proposal Paolo Bonzini
                   ` (6 preceding siblings ...)
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 7/9] qtest: IRQ interception infrastructure Paolo Bonzini
@ 2012-01-18 10:33 ` Paolo Bonzini
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 9/9] rtc-test: add IRQ intercept Paolo Bonzini
  2012-01-18 14:31 ` [Qemu-devel] [RFC PATCH 10/9] qtest: add clock management Paolo Bonzini
  9 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2012-01-18 10:33 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 tests/libqtest.c |   12 ++++++++++++
 tests/libqtest.h |    6 ++++++
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/tests/libqtest.c b/tests/libqtest.c
index dd07b07..1d1b06e 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -235,6 +235,18 @@ bool qtest_get_irq(QTestState *s, int num)
     return s->irq_level[num];
 }
 
+void qtest_irq_intercept_out(QTestState *s, const char *qom_path)
+{
+    qtest_sendf(s, "irq_intercept_out %s\n", qom_path);
+    qtest_rsp(s, 0);
+}
+
+void qtest_irq_intercept_in(QTestState *s, const char *qom_path)
+{
+    qtest_sendf(s, "irq_intercept_in %s\n", qom_path);
+    qtest_rsp(s, 0);
+}
+
 static void qtest_out(QTestState *s, const char *cmd, uint16_t addr, uint32_t value)
 {
     qtest_sendf(s, "%s 0x%x 0x%x\n", cmd, addr, value);
diff --git a/tests/libqtest.h b/tests/libqtest.h
index dd82926..b5ca04e 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -26,6 +26,10 @@ void qtest_quit(QTestState *s);
 
 bool qtest_get_irq(QTestState *s, int num);
 
+void qtest_irq_intercept_in(QTestState *s, const char *string);
+
+void qtest_irq_intercept_out(QTestState *s, const char *string);
+
 void qtest_outb(QTestState *s, uint16_t addr, uint8_t value);
 
 void qtest_outw(QTestState *s, uint16_t addr, uint16_t value);
@@ -51,6 +55,8 @@ void qtest_add_func(const char *str, void (*fn));
         )
 
 #define get_irq(num) qtest_get_irq(global_qtest, (num))
+#define irq_intercept_in(num) qtest_irq_intercept_in(global_qtest, (num))
+#define irq_intercept_out(num) qtest_irq_intercept_out(global_qtest, (num))
 #define outb(addr, val) qtest_outb(global_qtest, (addr), (val))
 #define outw(addr, val) qtest_outw(global_qtest, (addr), (val))
 #define outl(addr, val) qtest_outl(global_qtest, (addr), (val))
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 9/9] rtc-test: add IRQ intercept
  2012-01-18 10:33 [Qemu-devel] [RFC PATCH 0/9] qtest fixes and alternative IRQ intercept proposal Paolo Bonzini
                   ` (7 preceding siblings ...)
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 8/9] libqtest: add IRQ intercept commands Paolo Bonzini
@ 2012-01-18 10:33 ` Paolo Bonzini
  2012-01-18 14:31 ` [Qemu-devel] [RFC PATCH 10/9] qtest: add clock management Paolo Bonzini
  9 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2012-01-18 10:33 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 tests/rtc-test.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/tests/rtc-test.c b/tests/rtc-test.c
index 1645b34..8280f45 100644
--- a/tests/rtc-test.c
+++ b/tests/rtc-test.c
@@ -249,6 +249,7 @@ int main(int argc, char **argv)
     /* These tests only work on i386 and x86_64 */
     if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
         s = qtest_start("-vnc none");
+        qtest_irq_intercept_in(s, "ioapic");
 
         qtest_add_func("/rtc/bcd/check-time", bcd_check_time);
         qtest_add_func("/rtc/dec/check-time", dec_check_time);
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 5/9] qtest: do not use TCG CPU threads
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 5/9] qtest: do not use TCG CPU threads Paolo Bonzini
@ 2012-01-18 10:53   ` Andreas Färber
  2012-01-18 11:14     ` Paolo Bonzini
  0 siblings, 1 reply; 14+ messages in thread
From: Andreas Färber @ 2012-01-18 10:53 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

Am 18.01.2012 11:33, schrieb Paolo Bonzini:
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  cpu-exec.c |    4 ---
>  cpus.c     |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 59 insertions(+), 7 deletions(-)

> diff --git a/cpus.c b/cpus.c
> index 2dae549..c4ca26a 100644
> --- a/cpus.c
> +++ b/cpus.c

> -    if (kvm_enabled() && !env->thread_kicked) {
> +    if (!tcg_enabled() && !env->thread_kicked) {

> -    if (kvm_enabled()) {
> +    if (!tcg_enabled()) {

>      if (kvm_enabled()) {
>          qemu_kvm_start_vcpu(env);
> -    } else {
> +    } else if (tcg_enabled()) {
>          qemu_tcg_init_vcpu(env);
> +    } else {
> +        qemu_dummy_start_vcpu(env);
>      }

Did you keep Xen in mind when changing the logic?

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 5/9] qtest: do not use TCG CPU threads
  2012-01-18 10:53   ` Andreas Färber
@ 2012-01-18 11:14     ` Paolo Bonzini
  0 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2012-01-18 11:14 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 01/18/2012 11:53 AM, Andreas Färber wrote:
> > -    if (kvm_enabled()&&  !env->thread_kicked) {
> >  +    if (!tcg_enabled()&&  !env->thread_kicked) {
> >  -    if (kvm_enabled()) {
> >  +    if (!tcg_enabled()) {
> >        if (kvm_enabled()) {
> >            qemu_kvm_start_vcpu(env);
> >  -    } else {
> >  +    } else if (tcg_enabled()) {
> >            qemu_tcg_init_vcpu(env);
> >  +    } else {
> >  +        qemu_dummy_start_vcpu(env);
> >        }
> Did you keep Xen in mind when changing the logic?

Yes, though I didn't test it.  There's no reason why Xen should depend 
on any TCG code.

Paolo

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Qemu-devel] [RFC PATCH 10/9] qtest: add clock management
  2012-01-18 10:33 [Qemu-devel] [RFC PATCH 0/9] qtest fixes and alternative IRQ intercept proposal Paolo Bonzini
                   ` (8 preceding siblings ...)
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 9/9] rtc-test: add IRQ intercept Paolo Bonzini
@ 2012-01-18 14:31 ` Paolo Bonzini
  9 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2012-01-18 14:31 UTC (permalink / raw)
  To: qemu-devel

This patch combines qtest and -icount together to turn the vm_clock
into a source that can be fully managed by the client.  To this end new
commands clock_step and clock_set are added.  Hooking them with libqtest
is left as an exercise to the reader.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpus.c       |   20 ++++++++++++++++++++
 cpus.h       |    2 ++
 qemu-timer.c |    2 +-
 qemu-timer.h |    1 +
 qtest.c      |   45 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 69 insertions(+), 1 deletions(-)

diff --git a/cpus.c b/cpus.c
index c4ca26a..2963797 100644
--- a/cpus.c
+++ b/cpus.c
@@ -34,6 +34,7 @@
 
 #include "qemu-thread.h"
 #include "cpus.h"
+#include "qtest.h"
 #include "main-loop.h"
 
 #ifndef _WIN32
@@ -238,6 +239,20 @@ static void icount_warp_rt(void *opaque)
     vm_clock_warp_start = -1;
 }
 
+void qtest_clock_warp(int64_t dest)
+{
+    int64_t clock = qemu_get_clock_ns(vm_clock);
+    assert(qtest_enabled());
+    while (clock < dest) {
+        int64_t deadline = qemu_clock_deadline(vm_clock);
+        int64_t warp = MIN(dest - clock, deadline);
+        qemu_icount_bias += warp;
+        qemu_run_timers(vm_clock);
+        clock = qemu_get_clock_ns(vm_clock);
+    }
+    qemu_notify_event();
+}
+
 void qemu_clock_warp(QEMUClock *clock)
 {
     int64_t deadline;
@@ -264,6 +279,11 @@ void qemu_clock_warp(QEMUClock *clock)
         return;
     }
 
+    if (qtest_enabled()) {
+        /* When testing, qtest commands advance icount.  */
+	return;
+    }
+
     vm_clock_warp_start = qemu_get_clock_ns(rt_clock);
     deadline = qemu_clock_deadline(vm_clock);
     if (deadline > 0) {
diff --git a/cpus.h b/cpus.h
index 4ea2fe2..b49c2f5 100644
--- a/cpus.h
+++ b/cpus.h
@@ -11,6 +11,8 @@ void cpu_synchronize_all_states(void);
 void cpu_synchronize_all_post_reset(void);
 void cpu_synchronize_all_post_init(void);
 
+void qtest_clock_warp(int64_t dest);
+
 /* vl.c */
 extern int smp_cores;
 extern int smp_threads;
diff --git a/qemu-timer.c b/qemu-timer.c
index cd026c6..cb246cb 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -397,7 +397,7 @@ int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
     return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale);
 }
 
-static void qemu_run_timers(QEMUClock *clock)
+void qemu_run_timers(QEMUClock *clock)
 {
     QEMUTimer **ptimer_head, *ts;
     int64_t current_time;
diff --git a/qemu-timer.h b/qemu-timer.h
index de17f3b..661bbe7 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -59,6 +59,7 @@ int qemu_timer_pending(QEMUTimer *ts);
 int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
 uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts);
 
+void qemu_run_timers(QEMUClock *clock);
 void qemu_run_all_timers(void);
 int qemu_alarm_pending(void);
 void configure_alarms(char const *opt);
diff --git a/qtest.c b/qtest.c
index 010befe..d7b38eb 100644
--- a/qtest.c
+++ b/qtest.c
@@ -18,6 +18,7 @@
 #include "memory.h"
 #include "hw/irq.h"
 #include "sysemu.h"
+#include "cpus.h"
 
 #define MAX_IRQ 256
 
@@ -44,6 +45,30 @@ static bool qtest_opened;
  *
  * Valid requests
  *
+ * Clock management:
+ *
+ * The qtest client is completely in charge of the vm_clock.  qtest commands
+ * let you adjust the value of the clock (monotonically).  All the commands
+ * return the current value of the clock in nanoseconds.
+ *
+ *  > clock_step
+ *  < OK VALUE
+ *
+ *     Advance the clock to the next deadline.  Useful when waiting for
+ *     asynchronous events.
+ *
+ *  > clock_step NS
+ *  < OK VALUE
+ *
+ *     Advance the clock by NS nanoseconds.
+ *
+ *  > clock_set NS
+ *  < OK VALUE
+ *
+ *     Advance the clock to NS nanoseconds (do nothing if it's already past).
+ *
+ * PIO and memory access:
+ *
  *  > outb ADDR VALUE
  *  < OK
  *
@@ -298,6 +323,25 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
 
         qtest_send_prefix(chr);
         qtest_send(chr, "OK\n");
+    } else if (strcmp(words[0], "clock_step") == 0) {
+        int64_t ns;
+
+        if (words[1]) {
+            ns = strtoll(words[1], NULL, 0);
+        } else {
+            ns = qemu_clock_deadline(vm_clock);
+        }
+        qtest_clock_warp(qemu_get_clock_ns(vm_clock) + ns);
+        qtest_send_prefix(chr);
+        qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock));
+    } else if (strcmp(words[0], "clock_set") == 0) {
+        int64_t ns;
+
+        g_assert(words[1]);
+        ns = strtoll(words[1], NULL, 0);
+        qtest_clock_warp(ns);
+        qtest_send_prefix(chr);
+        qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock));
     } else {
         qtest_send_prefix(chr);
         qtest_send(chr, "FAIL Unknown command `%s'\n", words[0]);
@@ -376,6 +420,7 @@ int qtest_init(void)
 
     g_assert(qtest_chrdev != NULL);
 
+    configure_icount("0");
     chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
 
     qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr);
-- 
1.7.7.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 6/9] pc: attach ioapic to the QOM composition tree
  2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 6/9] pc: attach ioapic to the QOM composition tree Paolo Bonzini
@ 2012-01-24 15:12   ` Jan Kiszka
  0 siblings, 0 replies; 14+ messages in thread
From: Jan Kiszka @ 2012-01-24 15:12 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On 2012-01-18 11:33, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/pc_piix.c |    7 +++++--
>  1 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
> index 2aba89c..3f92bf9 100644
> --- a/hw/pc_piix.c
> +++ b/hw/pc_piix.c
> @@ -54,7 +54,7 @@ static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 };
>  static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
>  static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
>  
> -static void ioapic_init(GSIState *gsi_state)
> +static DeviceState *ioapic_init(GSIState *gsi_state)
>  {
>      DeviceState *dev;
>      SysBusDevice *d;
> @@ -68,6 +68,7 @@ static void ioapic_init(GSIState *gsi_state)
>      for (i = 0; i < IOAPIC_NUM_PINS; i++) {
>          gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
>      }
> +    return dev;
>  }
>  
>  /* PC hardware initialisation */
> @@ -168,7 +169,9 @@ static void pc_init1(MemoryRegion *system_memory,
>          gsi_state->i8259_irq[i] = i8259[i];
>      }
>      if (pci_enabled) {
> -        ioapic_init(gsi_state);
> +        dev = ioapic_init(gsi_state);
> +        qdev_property_add_child(qdev_resolve_path("/i440fx/piix3", NULL),
> +                                "ioapic", dev, NULL);

That's not true. The IOAPIC was a separate IC, not part of the PIIX3. It
should be assigned to the board if you want to do it correctly. :)

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2012-01-24 15:12 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-18 10:33 [Qemu-devel] [RFC PATCH 0/9] qtest fixes and alternative IRQ intercept proposal Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 1/9] qtest: always send a response Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 2/9] qtest: enable echo Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 3/9] qtest: fix Makefile Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 4/9] rtc-test: fix set_alarm_time Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 5/9] qtest: do not use TCG CPU threads Paolo Bonzini
2012-01-18 10:53   ` Andreas Färber
2012-01-18 11:14     ` Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 6/9] pc: attach ioapic to the QOM composition tree Paolo Bonzini
2012-01-24 15:12   ` Jan Kiszka
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 7/9] qtest: IRQ interception infrastructure Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 8/9] libqtest: add IRQ intercept commands Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 9/9] rtc-test: add IRQ intercept Paolo Bonzini
2012-01-18 14:31 ` [Qemu-devel] [RFC PATCH 10/9] qtest: add clock management Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).