From bc3bdf243806251ac251259267807c86d6d600dd Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 28 Jun 2018 14:59:38 +0200 Subject: riscv: Optimize and fix interrupt disable/enable Use the atomic read and clear operation to disable interrupts. Do not write the complete mstatus. Instead, set only the MIE bit depending on the level parameter. Update #3433. --- cpukit/score/cpu/riscv/include/rtems/score/cpu.h | 31 ++++++++++++------------ 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h index 361af2e392..15a75c8af3 100644 --- a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h +++ b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h @@ -48,6 +48,8 @@ extern "C" { #include /* for printk */ #endif +#define RISCV_MSTATUS_MIE 0x8 + #define CPU_INLINE_ENABLE_DISPATCH FALSE #define CPU_UNROLL_ENQUEUE_PRIORITY TRUE #define CPU_ISR_PASSES_FRAME_POINTER 1 @@ -115,22 +117,21 @@ Context_Control_fp _CPU_Null_fp_context; #define _CPU_Initialize_vectors() -/* - * Disable all interrupts for an RTEMS critical section. The previous - * level is returned in _level. - * - */ - -static inline unsigned long riscv_interrupt_disable( void ) +static inline uint32_t riscv_interrupt_disable( void ) { - unsigned long status = read_csr(mstatus); - clear_csr(mstatus, MSTATUS_MIE); - return status; + unsigned long mstatus; + + __asm__ volatile ( + "csrrc %0, mstatus, " RTEMS_XSTRING( RISCV_MSTATUS_MIE ) : + "=&r" ( mstatus ) + ); + + return mstatus & RISCV_MSTATUS_MIE; } -static inline void riscv_interrupt_enable(unsigned long level) +static inline void riscv_interrupt_enable( uint32_t level ) { - write_csr(mstatus, level); + __asm__ volatile ( "csrrs zero, mstatus, %0" : : "r" ( level ) ); } #define _CPU_ISR_Disable( _level ) \ @@ -147,18 +148,18 @@ static inline void riscv_interrupt_enable(unsigned long level) RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( unsigned long level ) { - return ( level & MSTATUS_MIE ) != 0; + return ( level & RISCV_MSTATUS_MIE ) != 0; } RTEMS_INLINE_ROUTINE void _CPU_ISR_Set_level( uint32_t level ) { if ( ( level & CPU_MODES_INTERRUPT_MASK) == 0 ) { __asm__ volatile ( - "csrrs zero, mstatus, " RTEMS_XSTRING( MSTATUS_MIE ) + "csrrs zero, mstatus, " RTEMS_XSTRING( RISCV_MSTATUS_MIE ) ); } else { __asm__ volatile ( - "csrrc zero, mstatus, " RTEMS_XSTRING( MSTATUS_MIE ) + "csrrc zero, mstatus, " RTEMS_XSTRING( RISCV_MSTATUS_MIE ) ); } } -- cgit v1.2.3