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