Message ID | 4daf0424-b767-b5d9-bacb-0fe879c92963@linaro.org |
---|---|
State | New |
Headers | show |
Series | QTest framework does not capture toggled irq line | expand |
On 10/11/2023 04.40, Gustavo Romero wrote: > Hi folks, > > I'm writing a test for a device that has one IRQ output line > that is toggled (raised then lowered) by the device to trigger > a CPU interrupt. > > Afaics the QTest framework does not provide a way to capture > when an output line is raised because the API functions, e.g. > qtest_get_irq(), read the current state of the intercepted > IRQ lines, which is already low when the function is called, > since the line is toggled by the device. > > I'd like to introduce a new API function to address this case, > called qtest_get_irq_trigger_counter(): ... > This change addresses the current QTest limitation. Is it acceptable? Hi Gustavo, that sounds reasonable to me. Thomas
On 11/10/23 3:16 AM, Thomas Huth wrote: > On 10/11/2023 04.40, Gustavo Romero wrote: >> Hi folks, >> >> I'm writing a test for a device that has one IRQ output line >> that is toggled (raised then lowered) by the device to trigger >> a CPU interrupt. >> >> Afaics the QTest framework does not provide a way to capture >> when an output line is raised because the API functions, e.g. >> qtest_get_irq(), read the current state of the intercepted >> IRQ lines, which is already low when the function is called, >> since the line is toggled by the device. >> >> I'd like to introduce a new API function to address this case, >> called qtest_get_irq_trigger_counter(): > ... >> This change addresses the current QTest limitation. Is it acceptable? > > Hi Gustavo, > > that sounds reasonable to me. Thanks, Thomas! I've posted the patch here: https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg02867.html Cheers, Gustavo
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index 471529e6cc..9ed2a43155 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -79,6 +79,7 @@ struct QTestState diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index 471529e6cc..9ed2a43155 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -79,6 +79,7 @@ struct QTestState int expected_status; bool big_endian; bool irq_level[MAX_IRQ]; + uint64_t irq_trigger_counter[MAX_IRQ]; GString *rx; QTestTransportOps ops; GList *pending_events; @@ -481,6 +482,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) s->rx = g_string_new(""); for (i = 0; i < MAX_IRQ; i++) { s->irq_level[i] = false; + s->irq_trigger_counter[i] = 0; } /* @@ -663,6 +665,7 @@ redo: if (strcmp(words[1], "raise") == 0) { s->irq_level[irq] = true; + s->irq_trigger_counter[irq]++; } else { s->irq_level[irq] = false; } @@ -953,6 +956,14 @@ bool qtest_get_irq(QTestState *s, int num) return s->irq_level[num]; } +uint64_t qtest_get_irq_trigger_counter(QTestState *s, int irq_num) +{ + /* dummy operation in order to make sure irq is up to date */ + qtest_inb(s, 0); + + return s->irq_trigger_counter[irq_num]; +} + void qtest_module_load(QTestState *s, const char *prefix, const char *libname) { qtest_sendf(s, "module_load %s %s\n", prefix, libname); @@ -1693,6 +1704,7 @@ QTestState *qtest_inproc_init(QTestState **s, bool log, const char* arch, qts->wstatus = 0; for (int i = 0; i < MAX_IRQ; i++) { qts->irq_level[i] = false; + qts->irq_trigger_counter[i] = 0; } qtest_client_set_rx_handler(qts, qtest_client_inproc_recv_line); diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h index e53e350e3a..0e763a4507 100644 --- a/tests/qtest/libqtest.h +++ b/tests/qtest/libqtest.h @@ -351,6 +351,16 @@ void qtest_module_load(QTestState *s, const char *prefix, const char *libname); */ bool qtest_get_irq(QTestState *s, int num); + +/** + * qtest_get_irq_counter: + * @s: #QTestState instance to operate on. + * @irq_num: Interrupt to observe. + * + * Returns: The number of times @irq_num got triggered (raised). + */ +uint64_t qtest_get_irq_trigger_counter(QTestState *s, int irq_num); + /** * qtest_irq_intercept_in: * @s: #QTestState instance to operate on.