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);