From cdcaf6ed8a1d18bdedb72fb665263c0dbff0ac8e Mon Sep 17 00:00:00 2001 From: Vic Yang Date: Mon, 20 May 2013 00:00:27 +0800 Subject: Add interrupt support for emulator This provides us a way to inject interrupts during a test. If a test has interrupt_generator() defined, it will run in a separate thread. The generator can then trigger interrupts when it decides to. The current running task is suspended while emulator is executing ISR. Also fixes a bug that tasks run without scheduler notifying them during emulator start-up. BUG=chrome-os-partner:19235 TEST=Repeatedly run all tests. BRANCH=None Change-Id: I0f921c47c0f848a9626da6272d9040e2b7c5ac86 Signed-off-by: Vic Yang Reviewed-on: https://chromium-review.googlesource.com/55671 --- test/build.mk | 3 +- test/host_command.c | 1 + test/interrupt.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ test/interrupt.tasklist | 17 ++++++++++ test/mutex.c | 1 + test/pingpong.c | 1 + 6 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 test/interrupt.c create mode 100644 test/interrupt.tasklist (limited to 'test') diff --git a/test/build.mk b/test/build.mk index 76a6a68d6f..170b0e37b0 100644 --- a/test/build.mk +++ b/test/build.mk @@ -22,7 +22,7 @@ test-list-$(BOARD_SAMUS)= test-list-host=mutex pingpong utils kb_scan kb_mkbp lid_sw power_button hooks test-list-host+=thermal flash queue kb_8042 extpwr_gpio console_edit system test-list-host+=sbs_charging adapter host_command thermal_falco led_spring -test-list-host+=bklight_lid bklight_passthru +test-list-host+=bklight_lid bklight_passthru interrupt adapter-y=adapter.o bklight_lid-y=bklight_lid.o @@ -33,6 +33,7 @@ flash-y=flash.o hooks-y=hooks.o host_command-y=host_command.o kb_8042-y=kb_8042.o +interrupt-y=interrupt.o kb_mkbp-y=kb_mkbp.o kb_scan-y=kb_scan.o led_spring-y=led_spring.o led_spring_impl.o diff --git a/test/host_command.c b/test/host_command.c index cd8d57413c..a98ee87ef6 100644 --- a/test/host_command.c +++ b/test/host_command.c @@ -169,6 +169,7 @@ static int test_hostcmd_invalid_checksum(void) void run_test(void) { + wait_for_task_started(); test_reset(); RUN_TEST(test_hostcmd_ok); diff --git a/test/interrupt.c b/test/interrupt.c new file mode 100644 index 0000000000..b7a42d1588 --- /dev/null +++ b/test/interrupt.c @@ -0,0 +1,82 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Test interrupt support of EC emulator. + */ +#include + +#include "common.h" +#include "console.h" +#include "test_util.h" +#include "task.h" +#include "timer.h" +#include "util.h" + +static int main_count; +static int has_error; +static int interrupt_count; + +/* period between 50us and 3.2ms */ +#define PERIOD_US(num) (((num % 64) + 1) * 50) + +void my_isr(void) +{ + int i = main_count; + udelay(3 * PERIOD_US(prng_no_seed())); + if (i != main_count || !in_interrupt_context()) + has_error = 1; + interrupt_count++; +} + +void interrupt_generator(void) +{ + while (1) { + udelay(3 * PERIOD_US(prng_no_seed())); + task_trigger_test_interrupt(my_isr); + } +} + +static int interrupt_test(void) +{ + timestamp_t deadline = get_time(); + deadline.val += SECOND / 2; + while (!timestamp_expired(deadline, NULL)) + ++main_count; + + ccprintf("Interrupt count: %d\n", interrupt_count); + ccprintf("Main thread tick: %d\n", main_count); + + TEST_ASSERT(!has_error); + TEST_ASSERT(!in_interrupt_context()); + + return EC_SUCCESS; +} + +static int interrupt_disable_test(void) +{ + timestamp_t deadline = get_time(); + int start_int_cnt, end_int_cnt; + deadline.val += SECOND / 2; + + interrupt_disable(); + start_int_cnt = interrupt_count; + while (!timestamp_expired(deadline, NULL)) + ; + end_int_cnt = interrupt_count; + interrupt_enable(); + + TEST_ASSERT(start_int_cnt == end_int_cnt); + + return EC_SUCCESS; +} + +void run_test(void) +{ + test_reset(); + + RUN_TEST(interrupt_test); + RUN_TEST(interrupt_disable_test); + + test_print_result(); +} diff --git a/test/interrupt.tasklist b/test/interrupt.tasklist new file mode 100644 index 0000000000..26cfc53453 --- /dev/null +++ b/test/interrupt.tasklist @@ -0,0 +1,17 @@ +/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * List of enabled tasks in the priority order + * + * The first one has the lowest priority. + * + * For each task, use the macro TASK_TEST(n, r, d, s) where : + * 'n' in the name of the task + * 'r' in the main routine of the task + * 'd' in an opaque parameter passed to the routine at startup + * 's' is the stack size in bytes; must be a multiple of 8 + */ +#define CONFIG_TEST_TASK_LIST /* No test task */ diff --git a/test/mutex.c b/test/mutex.c index 10cf300e22..96bc69feee 100644 --- a/test/mutex.c +++ b/test/mutex.c @@ -111,5 +111,6 @@ int mutex_main_task(void *unused) void run_test(void) { + wait_for_task_started(); task_wake(TASK_ID_MTX1); } diff --git a/test/pingpong.c b/test/pingpong.c index c11267db74..f08a9554a7 100644 --- a/test/pingpong.c +++ b/test/pingpong.c @@ -61,6 +61,7 @@ int task_tick(void *data) void run_test(void) { + wait_for_task_started(); task_wake(TASK_ID_TICK); task_wake(TASK_ID_TESTA); } -- cgit v1.2.1