From 547ebd1b2719df88984b325d7e16f640ecd26be9 Mon Sep 17 00:00:00 2001 From: kenrabold Date: Mon, 16 Sep 2019 08:54:40 -0700 Subject: [PATCH] cpu/fe310: use WFI to wait for SW interrupt --- cpu/fe310/cpu.c | 22 ++++++++++++++++------ cpu/fe310/periph/pm.c | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/cpu/fe310/cpu.c b/cpu/fe310/cpu.c index f7cedd178e4c..fb9b5e7b20d9 100644 --- a/cpu/fe310/cpu.c +++ b/cpu/fe310/cpu.c @@ -187,11 +187,22 @@ void handle_trap(unsigned int mcause) break; } } + else { + /* Unknown trap */ + core_panic(PANIC_GENERAL_ERROR, "Unhandled trap"); + } /* ISR done - no more changes to thread states */ __in_isr = 0; } +void panic_arch(void) +{ +#ifdef DEVELHELP + while (1) {} +#endif +} + /** * @brief Noticeable marker marking the beginning of a stack segment * @@ -319,22 +330,18 @@ void *thread_isr_stack_start(void) } /** - * @brief Start or resume threading by loading a threads initial information - * from the stack. + * @brief Call context switching at thread exit * * This is called is two situations: 1) after the initial main and idle threads * have been created and 2) when a thread exits. * - * sched_active_thread is not valid when cpu_switch_context_exit() is - * called. sched_run() must be called to determine the next valid thread. - * This is exploited in the context switch code. */ void cpu_switch_context_exit(void) { /* enable interrupts */ irq_enable(); - /* start the thread by triggering a context switch */ + /* force a context switch to another thread */ thread_yield_higher(); UNREACHABLE(); } @@ -343,4 +350,7 @@ void thread_yield_higher(void) { /* Use SW intr to schedule context switch */ CLINT_REG(CLINT_MSIP) = 1; + + /* Latency of SW intr can be 4-7 cycles; wait for the SW intr */ + __asm__ volatile ("wfi"); } diff --git a/cpu/fe310/periph/pm.c b/cpu/fe310/periph/pm.c index c3739175a02b..0e49f68694d7 100644 --- a/cpu/fe310/periph/pm.c +++ b/cpu/fe310/periph/pm.c @@ -23,7 +23,7 @@ void pm_set_lowest(void) { - /* __asm__("wfi"); */ + __asm__ volatile ("wfi"); } void pm_off(void)