@@ -1669,22 +1669,38 @@ static int remove_trigger(struct target *target, int unique_id)
16691669
16701670 bool done = false;
16711671 for (unsigned int i = 0 ; i < r -> trigger_count ; i ++ ) {
1672- if (r -> trigger_unique_id [i ] == unique_id ) {
1673- riscv_reg_set (target , GDB_REGNO_TSELECT , i );
1674- riscv_reg_set (target , GDB_REGNO_TDATA1 , 0 );
1675- r -> trigger_unique_id [i ] = -1 ;
1676- LOG_TARGET_DEBUG (target , "Stop using resource %d for bp %d" ,
1677- i , unique_id );
1678- done = true;
1672+ if (r -> trigger_unique_id [i ] != unique_id )
1673+ continue ;
1674+ done = false;
1675+ result = riscv_reg_set (target , GDB_REGNO_TSELECT , i );
1676+ if (result == ERROR_OK )
1677+ result = riscv_reg_set (target , GDB_REGNO_TDATA1 , 0 );
1678+ if (result != ERROR_OK ) {
1679+ LOG_TARGET_ERROR (target ,
1680+ "Could not free resource %d for bp %d. "
1681+ "Target is in a potentially unrecoverable state!" ,
1682+ i , unique_id );
1683+ return ERROR_FAIL ;
16791684 }
1685+ r -> trigger_unique_id [i ] = -1 ;
1686+ LOG_TARGET_DEBUG (target , "Stop using resource %d for bp %d" ,
1687+ i , unique_id );
1688+ done = true;
16801689 }
16811690 if (!done ) {
16821691 LOG_TARGET_ERROR (target ,
16831692 "Couldn't find the hardware resources used by hardware trigger." );
16841693 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE ;
16851694 }
16861695
1687- riscv_reg_set (target , GDB_REGNO_TSELECT , tselect );
1696+ result = riscv_reg_set (target , GDB_REGNO_TSELECT , tselect );
1697+ if (result != ERROR_OK ) {
1698+ LOG_TARGET_ERROR (target ,
1699+ "Could not restore tselect after bp %d removal. "
1700+ "Target is in a potentially unrecoverable state!" ,
1701+ unique_id );
1702+ return ERROR_FAIL ;
1703+ }
16881704
16891705 return ERROR_OK ;
16901706}
@@ -1713,6 +1729,8 @@ static int riscv_remove_breakpoint(struct target *target,
17131729 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE ;
17141730 }
17151731
1732+ /* FIXME: we should clear this flag even if remove_trigger fails for cases
1733+ * when all HW resources from Trigger Module were de-allocated */
17161734 breakpoint -> is_set = false;
17171735
17181736 return ERROR_OK ;
@@ -1763,6 +1781,8 @@ int riscv_remove_watchpoint(struct target *target,
17631781 int result = remove_trigger (target , trigger .unique_id );
17641782 if (result != ERROR_OK )
17651783 return result ;
1784+ /* FIXME: we should clear this flag even if remove_trigger fails for cases
1785+ * when all HW resources from Trigger Module were de-allocated */
17661786 watchpoint -> is_set = false;
17671787
17681788 return ERROR_OK ;
0 commit comments