From 6ee5e80fda0456a6aff1dd48b1aff841a18b6e10 Mon Sep 17 00:00:00 2001 From: Alvin Chang Date: Thu, 12 Oct 2023 00:00:24 +0800 Subject: [PATCH] core: riscv: Fix logic of thread_{get/set}_exceptions() In ARM, the bits in DAIF register are used to mask the interrupts. While in RISC-V, the bits in CSR mie/sie are used to enable(unmask) corresponding interrupt sources. To not modify the function of thread_get_exceptions(), we invert the bits after reading the value of CSR mie/sie, as mask. To not modify the function of thread_set_exceptions(), we invert the bits in given "exceptions" before writing "exceptions" into CSR mie/sie. Therefore, the intended masked exception bits will be cleared when we write the final value into CSR mie/sie to mask those interrupts. Signed-off-by: Alvin Chang --- core/arch/riscv/kernel/thread_arch.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/core/arch/riscv/kernel/thread_arch.c b/core/arch/riscv/kernel/thread_arch.c index c8f2c61d7f5..cf4028ffe8a 100644 --- a/core/arch/riscv/kernel/thread_arch.c +++ b/core/arch/riscv/kernel/thread_arch.c @@ -32,9 +32,12 @@ #include #include +/* This function returns current masked exception bits. */ uint32_t __nostackcheck thread_get_exceptions(void) { - return read_csr(CSR_XIE) & THREAD_EXCP_ALL; + uint32_t xie = read_csr(CSR_XIE) & THREAD_EXCP_ALL; + + return xie ^ THREAD_EXCP_ALL; } void __nostackcheck thread_set_exceptions(uint32_t exceptions) @@ -43,6 +46,18 @@ void __nostackcheck thread_set_exceptions(uint32_t exceptions) if (!(exceptions & THREAD_EXCP_FOREIGN_INTR)) assert_have_no_spinlock(); + /* + * In ARM, the bits in DAIF register are used to mask the interrupts. + * While in RISC-V, the bits in CSR mie/sie are used to enable(unmask) + * corresponding interrupt sources. To not modify the meaning of + * thread_set_exceptions(), we should "invert" the bits in "exceptions". + * The corresponding bits in "exceptions" will be inverted so they will + * be cleared when we write the final value into CSR mie/sie. So that we + * can mask those interrupts. + */ + exceptions &= THREAD_EXCP_ALL; + exceptions ^= THREAD_EXCP_ALL; + barrier(); write_csr(CSR_XIE, exceptions); barrier();