summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2015-07-14 14:57:28 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-07-17 00:05:46 +0000
commita21650f05f62f78e8d021a42a7fc5067dad0aa87 (patch)
treef1fa607f2c5807ff3b54f60d4d6443382cdd009d /core
parent482a0811d65d91ca3c030f577d07f4f674058419 (diff)
downloadchrome-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')
-rw-r--r--core/host/host_task.h11
-rw-r--r--core/host/main.c7
-rw-r--r--core/host/task.c12
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);