* [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
* 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 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
* 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
* [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
* [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