@ -106,6 +106,21 @@ bool trigger_t::textra_match(processor_t * const proc) const noexcept
return true ;
}
bool trigger_t : : allow_action ( const state_t * const state ) const
{
if ( get_action ( ) = = ACTION_DEBUG_EXCEPTION ) {
const bool mstatus_mie = state - > mstatus - > read ( ) & MSTATUS_MIE ;
const bool sstatus_sie = state - > sstatus - > read ( ) & MSTATUS_SIE ;
const bool vsstatus_sie = state - > vsstatus - > read ( ) & MSTATUS_SIE ;
const bool medeleg_breakpoint = ( state - > medeleg - > read ( ) > > CAUSE_BREAKPOINT ) & 1 ;
const bool hedeleg_breakpoint = ( state - > hedeleg - > read ( ) > > CAUSE_BREAKPOINT ) & 1 ;
return ( state - > prv ! = PRV_M | | mstatus_mie ) & &
( state - > prv ! = PRV_S | | state - > v | | ! medeleg_breakpoint | | sstatus_sie ) & &
( state - > prv ! = PRV_S | | ! state - > v | | ! medeleg_breakpoint | | ! hedeleg_breakpoint | | vsstatus_sie ) ;
}
return true ;
}
reg_t disabled_trigger_t : : tdata1_read ( const processor_t * const proc ) const noexcept
{
auto xlen = proc - > get_xlen ( ) ;
@ -212,7 +227,7 @@ std::optional<match_result_t> mcontrol_common_t::detect_memory_access_match(proc
value & = 0xffffffff ;
}
if ( simple_match ( xlen , value ) ) {
if ( simple_match ( xlen , value ) & & allow_action ( proc - > get_state ( ) ) ) {
/* This is OK because this function is only called if the trigger was not
* inhibited by the previous trigger in the chain . */
hit = true ;
@ -289,7 +304,7 @@ void mcontrol6_t::tdata1_write(processor_t * const proc, const reg_t val, const
std : : optional < match_result_t > icount_t : : detect_icount_match ( processor_t * const proc ) noexcept
{
if ( ! common_match ( proc ) )
if ( ! common_match ( proc ) | | ! allow_action ( proc - > get_state ( ) ) )
return std : : nullopt ;
std : : optional < match_result_t > ret = std : : nullopt ;
@ -389,7 +404,7 @@ std::optional<match_result_t> trap_common_t::detect_trap_match(processor_t * con
bool interrupt = ( t . cause ( ) & ( ( reg_t ) 1 < < ( xlen - 1 ) ) ) ! = 0 ;
reg_t bit = t . cause ( ) & ~ ( ( reg_t ) 1 < < ( xlen - 1 ) ) ;
assert ( bit < xlen ) ;
if ( simple_match ( interrupt , bit ) ) {
if ( simple_match ( interrupt , bit ) & & allow_action ( proc - > get_state ( ) ) ) {
hit = true ;
return match_result_t ( TIMING_AFTER , action ) ;
}