[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v8 09/10] qtest: add set_irq_{in, out} infrastructur
From: |
Matthew Ogilvie |
Subject: |
[Qemu-devel] [PATCH v8 09/10] qtest: add set_irq_{in, out} infrastructure for testing interrupt controllers |
Date: |
Sun, 16 Dec 2012 16:56:28 -0700 |
Signed-off-by: Matthew Ogilvie <address@hidden>
---
hw/i8259.c | 6 ++++++
qtest.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/libqtest.c | 12 ++++++++++++
tests/libqtest.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+)
diff --git a/hw/i8259.c b/hw/i8259.c
index 9b2ec40..5f09f2f 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -453,6 +453,9 @@ qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq)
}
isa_pic = &dev->qdev;
+ object_property_add_link(OBJECT(bus),
+ "i8259-master", TYPE_DEVICE,
+ (Object **)&isa_pic, NULL);
dev = i8259_init_chip("isa-i8259", bus, false);
@@ -462,6 +465,9 @@ qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq)
}
slave_pic = DO_UPCAST(PICCommonState, dev, dev);
+ object_property_add_link(OBJECT(bus),
+ "i8259-slave", TYPE_DEVICE,
+ (Object **)&slave_pic, NULL);
return irq_set;
}
diff --git a/qtest.c b/qtest.c
index 6965910..d4c2dd7 100644
--- a/qtest.c
+++ b/qtest.c
@@ -117,6 +117,21 @@ 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).
+ *
+ * Testing interrupt handler chips like the i8259:
+ *
+ * > set_irq_in QOM-PATH IRQ LEVEL
+ * < OK
+ *
+ * > set_irq_out QOM-PATH IRQ LEVEL
+ * < OK
+ *
+ * Forcibly set the given interrupt pin to the given level (from the
+ * consumer's point of view).
+ *
+ * FUTURE: Some abstracted mechanism to initiate delivery of an
+ * interrupt to the CPU, returning the interrupt vector number
+ * that would be delivered to that CPU.
*/
static int hex2nib(char ch)
@@ -239,7 +254,43 @@ static void qtest_process_command(CharDriverState *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 ||
+ strcmp(words[0], "set_irq_out") == 0) {
+ DeviceState *dev;
+ qemu_irq *irqs;
+ int num_irqs;
+ int num;
+ int level;
+
+ g_assert(words[1] && words[2] && words[3]);
+
+ dev = DEVICE(object_resolve_path(words[1], NULL));
+ if (!dev) {
+ qtest_send_prefix(chr);
+ qtest_send(chr, "FAIL Unknown device\n");
+ return;
+ }
+ if (words[0][8] == 'o') {
+ irqs = dev->gpio_out;
+ num_irqs = dev->num_gpio_out;
+ } else {
+ irqs = dev->gpio_in;
+ num_irqs = dev->num_gpio_in;
+ }
+
+ num = strtol(words[2], NULL, 0);
+ if (num < 0 || num >= num_irqs) {
+ qtest_send_prefix(chr);
+ qtest_send(chr, "FAIL Bad IRQ number\n");
+ return;
+ }
+
+ level = strtol(words[3], NULL, 0);
+
+ qemu_set_irq(irqs[num], level != 0);
+ 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 71b84c1..f6160ad 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -379,6 +379,18 @@ 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, int num, int level)
+{
+ qtest_sendf(s, "set_irq_in %s %d %d\n", qom_path, num, level);
+ qtest_rsp(s, 0);
+}
+
+void qtest_set_irq_out(QTestState *s, const char *qom_path, int num, int level)
+{
+ qtest_sendf(s, "set_irq_out %s %d %d\n", qom_path, 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 c8ade85..a045fc7 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -76,6 +76,30 @@ 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
+ * @irq: IRQ number
+ * @level: level to set it to (0 or 1)
+ *
+ * Force given device/irq GPIO-in pin to the given level.
+ * Mostly useful for testing interrupt controllers, rather than other devices.
+ */
+void qtest_set_irq_in(QTestState *s, const char *string, int irq, int level);
+
+/**
+ * qtest_set_irq_out:
+ * @s: QTestState instance to operate on.
+ * @string: QOM path of a device
+ * @irq: IRQ number
+ * @level: level to set it to (0 or 1)
+ *
+ * Force given device/irq GPIO-out pin to the given level.
+ * Mostly useful for testing interrupt controllers, rather than other devices.
+ */
+void qtest_set_irq_out(QTestState *s, const char *string, int irq, int level);
+
+/**
* qtest_outb:
* @s: QTestState instance to operate on.
* @addr: I/O port to write to.
@@ -250,6 +274,30 @@ void qtest_add_func(const char *str, void (*fn));
#define irq_intercept_out(string) qtest_irq_intercept_out(global_qtest, string)
/**
+ * qtest_set_irq_in:
+ * @string: QOM path of a device
+ * @irq: IRQ number
+ * @level: level to set it to (0 or 1)
+ *
+ * Force given device/irq GPIO-in pin to the given level.
+ * Mostly useful for testing interrupt controllers, rather than other devices.
+ */
+#define set_irq_in(string, irq, level) \
+ qtest_set_irq_in(global_qtest, string, irq, level)
+
+/**
+ * qtest_set_irq_in:
+ * @string: QOM path of a device
+ * @irq: IRQ number
+ * @level: level to set it to (0 or 1)
+ *
+ * Force given device/irq GPIO-in pin to the given level.
+ * Mostly useful for testing interrupt controllers, rather than other devices.
+ */
+#define set_irq_out(string, irq, level) \
+ qtest_set_irq_out(global_qtest, string, irq, level)
+
+/**
* outb:
* @addr: I/O port to write to.
* @value: Value being written.
--
1.7.10.2.484.gcd07cc5
- [Qemu-devel] [PATCH v8 00/10] i8254, i8259 and running Microport UNIX (ca 1987), Matthew Ogilvie, 2012/12/16
- [Qemu-devel] [PATCH v8 01/10] fix some debug printf format strings, Matthew Ogilvie, 2012/12/16
- [Qemu-devel] [PATCH v8 02/10] vl: fix -hdachs/-hda argument order parsing issues, Matthew Ogilvie, 2012/12/16
- [Qemu-devel] [PATCH v8 04/10] vga: add some optional CGA compatibility hacks, Matthew Ogilvie, 2012/12/16
- [Qemu-devel] [PATCH v8 03/10] qemu-options.hx: mention retrace= VGA option, Matthew Ogilvie, 2012/12/16
- [Qemu-devel] [PATCH v8 05/10] fix i8254 output logic to match the spec, Matthew Ogilvie, 2012/12/16
- [Qemu-devel] [PATCH v8 06/10] i8259: fix so that dropping IRQ level always clears the interrupt request, Matthew Ogilvie, 2012/12/16
- [Qemu-devel] [PATCH v8 07/10] i8259: refactor pic_set_irq level logic, Matthew Ogilvie, 2012/12/16
- [Qemu-devel] [PATCH v8 08/10] qtest: fix qemu_irq_intercept_out(), Matthew Ogilvie, 2012/12/16
- [Qemu-devel] [PATCH v8 09/10] qtest: add set_irq_{in, out} infrastructure for testing interrupt controllers,
Matthew Ogilvie <=
- [Qemu-devel] [PATCH v8 10/10] add test/pic-test.c, Matthew Ogilvie, 2012/12/16