mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-10-14 15:02:54 +00:00
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>
This commit is contained in:
parent
ead07aa4ef
commit
9813dc6ac3
43
qtest.c
43
qtest.c
|
@ -164,6 +164,17 @@ static bool qtest_opened;
|
||||||
* where NUM is an IRQ number. For the PC, interrupts can be intercepted
|
* 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
|
* simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
|
||||||
* NUM=0 even though it is remapped to GSI 2).
|
* 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)
|
static int hex2nib(char ch)
|
||||||
|
@ -326,7 +337,39 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
|
||||||
irq_intercept_dev = dev;
|
irq_intercept_dev = dev;
|
||||||
qtest_send_prefix(chr);
|
qtest_send_prefix(chr);
|
||||||
qtest_send(chr, "OK\n");
|
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 ||
|
} else if (strcmp(words[0], "outb") == 0 ||
|
||||||
strcmp(words[0], "outw") == 0 ||
|
strcmp(words[0], "outw") == 0 ||
|
||||||
strcmp(words[0], "outl") == 0) {
|
strcmp(words[0], "outl") == 0) {
|
||||||
|
|
|
@ -753,6 +753,16 @@ void qtest_irq_intercept_in(QTestState *s, const char *qom_path)
|
||||||
qtest_rsp(s, 0);
|
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)
|
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);
|
qtest_sendf(s, "%s 0x%x 0x%x\n", cmd, addr, value);
|
||||||
|
|
|
@ -230,6 +230,19 @@ void qtest_irq_intercept_in(QTestState *s, const char *string);
|
||||||
*/
|
*/
|
||||||
void qtest_irq_intercept_out(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:
|
* qtest_outb:
|
||||||
* @s: #QTestState instance to operate on.
|
* @s: #QTestState instance to operate on.
|
||||||
|
|
Loading…
Reference in a new issue