forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -48,6 +48,8 @@ extern "C" {
|
|||||||
#include <stdio.h> /* for printk */
|
#include <stdio.h> /* for printk */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define RISCV_MSTATUS_MIE 0x8
|
||||||
|
|
||||||
#define CPU_INLINE_ENABLE_DISPATCH FALSE
|
#define CPU_INLINE_ENABLE_DISPATCH FALSE
|
||||||
#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
|
#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE
|
||||||
#define CPU_ISR_PASSES_FRAME_POINTER 1
|
#define CPU_ISR_PASSES_FRAME_POINTER 1
|
||||||
@@ -115,22 +117,21 @@ Context_Control_fp _CPU_Null_fp_context;
|
|||||||
|
|
||||||
#define _CPU_Initialize_vectors()
|
#define _CPU_Initialize_vectors()
|
||||||
|
|
||||||
/*
|
static inline uint32_t riscv_interrupt_disable( void )
|
||||||
* Disable all interrupts for an RTEMS critical section. The previous
|
|
||||||
* level is returned in _level.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline unsigned long riscv_interrupt_disable( void )
|
|
||||||
{
|
{
|
||||||
unsigned long status = read_csr(mstatus);
|
unsigned long mstatus;
|
||||||
clear_csr(mstatus, MSTATUS_MIE);
|
|
||||||
return status;
|
__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 ) \
|
#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 )
|
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 )
|
RTEMS_INLINE_ROUTINE void _CPU_ISR_Set_level( uint32_t level )
|
||||||
{
|
{
|
||||||
if ( ( level & CPU_MODES_INTERRUPT_MASK) == 0 ) {
|
if ( ( level & CPU_MODES_INTERRUPT_MASK) == 0 ) {
|
||||||
__asm__ volatile (
|
__asm__ volatile (
|
||||||
"csrrs zero, mstatus, " RTEMS_XSTRING( MSTATUS_MIE )
|
"csrrs zero, mstatus, " RTEMS_XSTRING( RISCV_MSTATUS_MIE )
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
__asm__ volatile (
|
__asm__ volatile (
|
||||||
"csrrc zero, mstatus, " RTEMS_XSTRING( MSTATUS_MIE )
|
"csrrc zero, mstatus, " RTEMS_XSTRING( RISCV_MSTATUS_MIE )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user