diff mbox series

QTest framework does not capture toggled irq line

Message ID 4daf0424-b767-b5d9-bacb-0fe879c92963@linaro.org
State New
Headers show
Series QTest framework does not capture toggled irq line | expand

Commit Message

Gustavo Romero Nov. 10, 2023, 3:40 a.m. UTC
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?


Cheers,
Gustavo

Comments

Thomas Huth Nov. 10, 2023, 6:16 a.m. UTC | #1
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
Gustavo Romero Nov. 12, 2023, 2:55 a.m. UTC | #2
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 mbox series

Patch

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.