summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTzung-Bi Shih <tzungbi@chromium.org>2021-02-18 16:17:21 +0800
committerCommit Bot <commit-bot@chromium.org>2021-02-19 09:20:24 +0000
commitfe1800f01d7151064f780d8623b71778b7a81f78 (patch)
tree619d2cbc6325bf143a9600c7114e8a8bab7d3f6b
parent80cacc3d251ba738e2c8e6a84305ac06395898ef (diff)
downloadchrome-ec-fe1800f01d7151064f780d8623b71778b7a81f78.tar.gz
core/riscv-rv32i: set in_interrupt at beginning of exception handler
There are 3 paths when receiving an excaption in core/riscv-rv32i/init.S: 1. __irq_handler 2. excep_handler 3. unhandled_interrupt Originally, in_interrupt_context() returns true only if it goes to 1st path. However, the rest paths are also in interrupt context, especially some function may rely on in_interrupt_context(), for example, uart_flush_output() in common/uart_buffering.c. Note that, only the 1st goes back to normal context. The rest of paths are all going to panic and reset. Sets in_interrupt at the beginning of exception handler instead of start_irq_handler() so that the flag is ON when receiving an exception. BRANCH=none BUG=b:180571536 BUG=b:163300760 TEST=make BOARD=asurada_scp Signed-off-by: Tzung-Bi Shih <tzungbi@chromium.org> Change-Id: Iba689c506c02c4b5bb1668766f1d7ab5f86f72a4 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2702999 Reviewed-by: Eric Yilun Lin <yllin@chromium.org>
-rw-r--r--core/riscv-rv32i/init.S7
-rw-r--r--core/riscv-rv32i/task.c5
2 files changed, 8 insertions, 4 deletions
diff --git a/core/riscv-rv32i/init.S b/core/riscv-rv32i/init.S
index eee72503d3..f81890bd5e 100644
--- a/core/riscv-rv32i/init.S
+++ b/core/riscv-rv32i/init.S
@@ -165,6 +165,10 @@ __irq_isr:
bltu sp, t0, __sp_16byte_aligned
mv sp, t0
__sp_16byte_aligned:
+ /* in_interrupt = 1 */
+ li t0, 1
+ la t1, in_interrupt
+ sb t0, 0(t1)
/*
* This ensures sp is 16-byte aligned. This only applies to when there
* is an interrupt before tasks start. Otherwise stack_end is already
@@ -212,6 +216,9 @@ __irq_handler:
.global __irq_exit
__irq_exit:
jal end_irq_handler
+ /* in_interrupt = 0 */
+ la t0, in_interrupt
+ sb zero, 0(t0)
/* restore sp from scratch register */
csrr sp, mscratch
#ifdef CONFIG_FPU
diff --git a/core/riscv-rv32i/task.c b/core/riscv-rv32i/task.c
index 58a5e06ba3..f7ac6afb1e 100644
--- a/core/riscv-rv32i/task.c
+++ b/core/riscv-rv32i/task.c
@@ -165,7 +165,7 @@ static uint32_t tasks_enabled = BIT(TASK_ID_HOOKS) | BIT(TASK_ID_IDLE);
int start_called; /* Has task swapping started */
/* in interrupt context */
-static volatile int in_interrupt;
+volatile bool in_interrupt;
/* Interrupt number of EC modules */
volatile int ec_int;
/* Interrupt group of EC INTC modules */
@@ -319,8 +319,6 @@ void __ram_code update_exc_start_time(void)
*/
int __ram_code start_irq_handler(void)
{
- in_interrupt = 1;
-
/* If this is a SW interrupt */
if (get_mcause() == 11) {
ec_int = sw_int_num;
@@ -369,7 +367,6 @@ void __ram_code end_irq_handler(void)
task_switches++;
}
#endif
- in_interrupt = 0;
}
static uint32_t __ram_code __wait_evt(int timeout_us, task_id_t resched)