summaryrefslogtreecommitdiff
path: root/cts
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2016-10-18 09:27:34 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-11-09 23:26:30 -0800
commitb2f14a26b9e5b72486e9a7ad0e232fed269704c2 (patch)
tree0bad437caabacc37e80b4756c11c105da9992ebc /cts
parentd57ca415774be9bf136d9350b9ca52bb29c0ebfb (diff)
downloadchrome-ec-b2f14a26b9e5b72486e9a7ad0e232fed269704c2.tar.gz
eCTS: Add nested interrupt test (Low->High)
Add a nested interrupt test to eCTS. Lower priority IRQ is fired, followed by higher priority IRQ. Handler executions should be nested. P1 *-----* / \ P2 *----* *----* / \ task_cts ----* *---- A B C D BUG=chromium:653195 BRANCH=none TEST=cts.py -m gpio, interrupt, timer; make buildall Change-Id: I34dc7b4e819051b9070a11e69d13d6be704f2e5f Reviewed-on: https://chromium-review.googlesource.com/408797 Commit-Ready: Daisuke Nojiri <dnojiri@chromium.org> Tested-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'cts')
-rw-r--r--cts/interrupt/cts.testlist12
-rw-r--r--cts/interrupt/dut.c53
-rw-r--r--cts/interrupt/th.c25
3 files changed, 81 insertions, 9 deletions
diff --git a/cts/interrupt/cts.testlist b/cts/interrupt/cts.testlist
index 6153c2b52d..01d6c1b06e 100644
--- a/cts/interrupt/cts.testlist
+++ b/cts/interrupt/cts.testlist
@@ -13,6 +13,18 @@ CTS_TEST(test_task_wait_event)
/* Test task_disable_irq */
CTS_TEST(test_task_disable_irq)
+/* Test nested interrupt. Lower priority IRQ is fired, followed by
+ * higher priority IRQ. Handler executions should be nested.
+ *
+ * P1 *-----*
+ * / \
+ * P2 *----* *----*
+ * / \
+ * task_cts ----* *----
+ * A B C D
+ */
+CTS_TEST(test_nested_interrupt_low_high)
+
/*
* Other ideas
*
diff --git a/cts/interrupt/dut.c b/cts/interrupt/dut.c
index 43740147a7..9bf7eabde6 100644
--- a/cts/interrupt/dut.c
+++ b/cts/interrupt/dut.c
@@ -3,6 +3,7 @@
* found in the LICENSE file.
*/
+#include <string.h>
#include "common.h"
#include "gpio.h"
#include "registers.h"
@@ -13,6 +14,8 @@
static int got_interrupt;
static int wake_me_up;
+static int state_index;
+static char state[4];
/*
* Raw busy loop. Returns 1 if loop finishes before interrupt is triggered.
@@ -39,14 +42,35 @@ static int busy_loop(void)
/*
* Interrupt handler.
*/
-void cts_irq(enum gpio_signal signal)
+void cts_irq1(enum gpio_signal signal)
{
+ state[state_index++] = 'B';
/* test some APIs */
got_interrupt = in_interrupt_context();
/* Wake up the CTS task */
if (wake_me_up)
task_wake(TASK_ID_CTS);
+ state[state_index++] = 'C';
+}
+
+void cts_irq2(enum gpio_signal signal)
+{
+ state[state_index++] = 'A';
+ busy_loop();
+ state[state_index++] = 'D';
+}
+
+static void clear_state(void)
+{
+ uint32_t *event;
+
+ got_interrupt = 0;
+ wake_me_up = 0;
+ state_index = 0;
+ memset(state, '_', sizeof(state));
+ event = task_get_event_bitmap(TASK_ID_CTS);
+ *event = 0;
}
enum cts_rc test_task_wait_event(void)
@@ -106,6 +130,27 @@ enum cts_rc test_interrupt_disable(void)
return CTS_RC_SUCCESS;
}
+enum cts_rc test_nested_interrupt_low_high(void)
+{
+ uint32_t event;
+
+ event = task_wait_event(CTS_INTERRUPT_TRIGGER_DELAY_US * 4);
+ if (event != TASK_EVENT_TIMER) {
+ CPRINTS("Woke up by 0x%08x", event);
+ return CTS_RC_FAILURE;
+ }
+ if (!got_interrupt) {
+ CPRINTS("Interrupt context not detected");
+ return CTS_RC_TIMEOUT;
+ }
+ if (memcmp(state, "ABCD", sizeof(state))) {
+ CPRINTS("State transition differs from expectation");
+ return CTS_RC_FAILURE;
+ }
+
+ return CTS_RC_SUCCESS;
+}
+
#include "cts_testlist.h"
void cts_task(void)
@@ -113,11 +158,11 @@ void cts_task(void)
enum cts_rc rc;
int i;
- gpio_enable_interrupt(GPIO_CTS_IRQ);
+ gpio_enable_interrupt(GPIO_CTS_IRQ1);
+ gpio_enable_interrupt(GPIO_CTS_IRQ2);
interrupt_enable();
for (i = 0; i < CTS_TEST_ID_COUNT; i++) {
- got_interrupt = 0;
- wake_me_up = 0;
+ clear_state();
sync();
rc = tests[i].run();
interrupt_enable();
diff --git a/cts/interrupt/th.c b/cts/interrupt/th.c
index 3bcf2168b6..87582490ed 100644
--- a/cts/interrupt/th.c
+++ b/cts/interrupt/th.c
@@ -9,34 +9,48 @@
#include "timer.h"
#include "watchdog.h"
-static void trigger_interrupt(void)
+static void trigger_interrupt1(void)
{
usleep(CTS_INTERRUPT_TRIGGER_DELAY_US);
gpio_set_level(GPIO_OUTPUT_TEST, 0);
usleep(CTS_INTERRUPT_TRIGGER_DELAY_US);
}
+static void trigger_interrupt2(void)
+{
+ usleep(CTS_INTERRUPT_TRIGGER_DELAY_US);
+ gpio_set_level(GPIO_CTS_IRQ2, 0);
+ usleep(CTS_INTERRUPT_TRIGGER_DELAY_US);
+}
+
enum cts_rc test_task_wait_event(void)
{
- trigger_interrupt();
+ trigger_interrupt1();
return CTS_RC_SUCCESS;
}
enum cts_rc test_task_disable_irq(void)
{
- trigger_interrupt();
+ trigger_interrupt1();
return CTS_RC_SUCCESS;
}
enum cts_rc test_interrupt_enable(void)
{
- trigger_interrupt();
+ trigger_interrupt1();
return CTS_RC_SUCCESS;
}
enum cts_rc test_interrupt_disable(void)
{
- trigger_interrupt();
+ trigger_interrupt1();
+ return CTS_RC_SUCCESS;
+}
+
+enum cts_rc test_nested_interrupt_low_high(void)
+{
+ trigger_interrupt2();
+ trigger_interrupt1();
return CTS_RC_SUCCESS;
}
@@ -51,6 +65,7 @@ void cts_task(void)
for (i = 0; i < CTS_TEST_ID_COUNT; i++) {
gpio_set_level(GPIO_OUTPUT_TEST, 1);
+ gpio_set_level(GPIO_CTS_IRQ2, 1);
sync();
rc = tests[i].run();
CPRINTF("\n%s %d\n", tests[i].name, rc);