diff options
author | Aseda Aboagye <aaboagye@google.com> | 2015-07-14 14:57:28 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-07-17 00:05:46 +0000 |
commit | a21650f05f62f78e8d021a42a7fc5067dad0aa87 (patch) | |
tree | f1fa607f2c5807ff3b54f60d4d6443382cdd009d /core/host | |
parent | 482a0811d65d91ca3c030f577d07f4f674058419 (diff) | |
download | chrome-ec-a21650f05f62f78e8d021a42a7fc5067dad0aa87.tar.gz |
emulator: Fix handling of early IRQs.
Since the interrupt generator is now spawned right after the hooks task
and the generator can generate interrupts whenever it wants, it's
possible for an interrupt to fire before task switching is enabled.
When this happens, the main thread needs to be suspended so that the IRQ
can be serviced.
BRANCH=None
BUG=None
TEST="make clobber && make -j buildall tests" several times."
Change-Id: I5fb4f17666e3db9c670c4352bb36b84e4606dfa0
Signed-off-by: Aseda Aboagye <aaboagye@google.com>
Reviewed-on: https://chromium-review.googlesource.com/285634
Tested-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Commit-Queue: Aseda Aboagye <aaboagye@chromium.org>
Trybot-Ready: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'core/host')
-rw-r--r-- | core/host/host_task.h | 11 | ||||
-rw-r--r-- | core/host/main.c | 7 | ||||
-rw-r--r-- | core/host/task.c | 12 |
3 files changed, 26 insertions, 4 deletions
diff --git a/core/host/host_task.h b/core/host/host_task.h index e4e0712ea2..cc9b4ae9ea 100644 --- a/core/host/host_task.h +++ b/core/host/host_task.h @@ -23,4 +23,15 @@ pthread_t task_get_thread(task_id_t tskid); */ task_id_t task_get_running(void); +/** + * Initializes the interrupt semaphore and associates a signal handler with + * SIGNAL_INTERRUPT. + */ +void task_register_interrupt(void); + +/** + * Returns the process ID of the calling process. + */ +pid_t getpid(void); + #endif /* __CROS_EC_HOST_TASK_H */ diff --git a/core/host/main.c b/core/host/main.c index fbb28d9127..64976c0c89 100644 --- a/core/host/main.c +++ b/core/host/main.c @@ -8,6 +8,7 @@ #include "console.h" #include "flash.h" #include "hooks.h" +#include "host_task.h" #include "keyboard_scan.h" #include "stack_trace.h" #include "system.h" @@ -31,6 +32,12 @@ int main(int argc, char **argv) { __prog_name = argv[0]; + /* + * In order to properly service IRQs before task switching is enabled, + * we must set up our signal handler for the main thread. + */ + task_register_interrupt(); + task_register_tracedump(); register_test_end_hook(); diff --git a/core/host/task.c b/core/host/task.c index 28c0cb0297..9c2e650c84 100644 --- a/core/host/task.c +++ b/core/host/task.c @@ -125,7 +125,7 @@ static void _task_execute_isr(int sig) in_interrupt = 0; } -static void task_register_interrupt(void) +void task_register_interrupt(void) { sem_init(&interrupt_sem, 0, 0); signal(SIGNAL_INTERRUPT, _task_execute_isr); @@ -133,6 +133,7 @@ static void task_register_interrupt(void) void task_trigger_test_interrupt(void (*isr)(void)) { + pid_t main_pid; pthread_mutex_lock(&interrupt_lock); if (interrupt_disabled) { pthread_mutex_unlock(&interrupt_lock); @@ -141,7 +142,12 @@ void task_trigger_test_interrupt(void (*isr)(void)) /* Suspend current task and excute ISR */ pending_isr = isr; - pthread_kill(tasks[running_task_id].thread, SIGNAL_INTERRUPT); + if (task_started) { + pthread_kill(tasks[running_task_id].thread, SIGNAL_INTERRUPT); + } else { + main_pid = getpid(); + kill(main_pid, SIGNAL_INTERRUPT); + } /* Wait for ISR to complete */ sem_wait(&interrupt_sem); @@ -416,8 +422,6 @@ int task_start(void) { int i = TASK_ID_HOOKS; - task_register_interrupt(); - pthread_mutex_init(&run_lock, NULL); pthread_mutex_init(&interrupt_lock, NULL); pthread_cond_init(&scheduler_cond, NULL); |