diff options
author | Steffen Görtz <contrib@steffen-goertz.de> | 2019-01-07 15:23:47 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-01-07 15:23:47 +0000 |
commit | 9813dc6ac3954d58ba16b3920556f106f97e1c67 (patch) | |
tree | e3a5ef5827aa29ec852dafc7d7509c6356d7abbd | |
parent | ead07aa4ef753f0facd19a7218402f7d19eff60a (diff) |
qtest: Add set_irq_in command to set IRQ/GPIO level
Adds a new qtest command "set_irq_in" which allows
to set qemu gpio lines to a given level.
Based on https://lists.gnu.org/archive/html/qemu-devel/2012-12/msg02363.html
which never got merged.
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20190103091119.9367-2-stefanha@redhat.com
Originally-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | qtest.c | 43 | ||||
-rw-r--r-- | tests/libqtest.c | 10 | ||||
-rw-r--r-- | tests/libqtest.h | 13 |
3 files changed, 66 insertions, 0 deletions
@@ -164,6 +164,17 @@ static bool qtest_opened; * 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). + * + * Setting interrupt level: + * + * > set_irq_in QOM-PATH NAME NUM LEVEL + * < OK + * + * where NAME is the name of the irq/gpio list, NUM is an IRQ number and + * LEVEL is an signed integer IRQ level. + * + * Forcibly set the given interrupt pin to the given level. + * */ static int hex2nib(char ch) @@ -326,7 +337,39 @@ static void qtest_process_command(CharBackend *chr, gchar **words) irq_intercept_dev = dev; qtest_send_prefix(chr); qtest_send(chr, "OK\n"); + } else if (strcmp(words[0], "set_irq_in") == 0) { + DeviceState *dev; + qemu_irq irq; + char *name; + int ret; + int num; + int level; + + g_assert(words[1] && words[2] && words[3] && words[4]); + dev = DEVICE(object_resolve_path(words[1], NULL)); + if (!dev) { + qtest_send_prefix(chr); + qtest_send(chr, "FAIL Unknown device\n"); + return; + } + + if (strcmp(words[2], "unnamed-gpio-in") == 0) { + name = NULL; + } else { + name = words[2]; + } + + ret = qemu_strtoi(words[3], NULL, 0, &num); + g_assert(!ret); + ret = qemu_strtoi(words[4], NULL, 0, &level); + g_assert(!ret); + + irq = qdev_get_gpio_in_named(dev, name, num); + + qemu_set_irq(irq, level); + 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) { diff --git a/tests/libqtest.c b/tests/libqtest.c index 1d75d3c936..55750dd68d 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -753,6 +753,16 @@ void qtest_irq_intercept_in(QTestState *s, const char *qom_path) qtest_rsp(s, 0); } +void qtest_set_irq_in(QTestState *s, const char *qom_path, const char *name, + int num, int level) +{ + if (!name) { + name = "unnamed-gpio-in"; + } + qtest_sendf(s, "set_irq_in %s %s %d %d\n", qom_path, name, num, level); + 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 9758c51be6..7ea94139b0 100644 --- a/tests/libqtest.h +++ b/tests/libqtest.h @@ -231,6 +231,19 @@ void qtest_irq_intercept_in(QTestState *s, const char *string); void qtest_irq_intercept_out(QTestState *s, const char *string); /** + * qtest_set_irq_in: + * @s: QTestState instance to operate on. + * @string: QOM path of a device + * @name: IRQ name + * @irq: IRQ number + * @level: IRQ level + * + * Force given device/irq GPIO-in pin to the given level. + */ +void qtest_set_irq_in(QTestState *s, const char *string, const char *name, + int irq, int level); + +/** * qtest_outb: * @s: #QTestState instance to operate on. * @addr: I/O port to write to. |