@@ -579,6 +579,10 @@ static int register_write_direct(struct target *target, unsigned number,
579579 uint64_t value )
580580{
581581 struct riscv_program program ;
582+
583+ LOG_DEBUG ("[%d] reg[0x%x] <- 0x%" PRIx64 , riscv_current_hartid (target ),
584+ number , value );
585+
582586 riscv_program_init (& program , target );
583587
584588 riscv_addr_t input = riscv_program_alloc_d (& program );
@@ -641,7 +645,8 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
641645 * value = 0 ;
642646 * value |= ((uint64_t )(riscv_program_read_ram (& program , output + 4 ))) << 32 ;
643647 * value |= riscv_program_read_ram (& program , output );
644- LOG_DEBUG ("register 0x%x = 0x%" PRIx64 , number , * value );
648+ LOG_DEBUG ("[%d] reg[0x%x] = 0x%" PRIx64 , riscv_current_hartid (target ),
649+ number , * value );
645650 return ERROR_OK ;
646651}
647652
@@ -794,6 +799,14 @@ static void deinit_target(struct target *target)
794799static int add_trigger (struct target * target , struct trigger * trigger )
795800{
796801 riscv013_info_t * info = get_info (target );
802+
803+ // While we're using threads to fake harts, both gdb and OpenOCD assume
804+ // that hardware breakpoints are shared among threads. Make this true by
805+ // setting the same breakpoints on all harts.
806+
807+ // Assume that all triggers are configured the same on all harts.
808+ riscv_set_current_hartid (target , 0 );
809+
797810 maybe_read_tselect (target );
798811
799812 int i ;
@@ -817,42 +830,59 @@ static int add_trigger(struct target *target, struct trigger *trigger)
817830 continue ;
818831 }
819832
820- // address/data match trigger
821- tdata1 |= MCONTROL_DMODE (riscv_xlen (target ));
822- tdata1 = set_field (tdata1 , MCONTROL_ACTION ,
823- MCONTROL_ACTION_DEBUG_MODE );
824- tdata1 = set_field (tdata1 , MCONTROL_MATCH , MCONTROL_MATCH_EQUAL );
825- tdata1 |= MCONTROL_M ;
826- if (info -> misa & (1 << ('H' - 'A' )))
827- tdata1 |= MCONTROL_H ;
828- if (info -> misa & (1 << ('S' - 'A' )))
829- tdata1 |= MCONTROL_S ;
830- if (info -> misa & (1 << ('U' - 'A' )))
831- tdata1 |= MCONTROL_U ;
832-
833- if (trigger -> execute )
834- tdata1 |= MCONTROL_EXECUTE ;
835- if (trigger -> read )
836- tdata1 |= MCONTROL_LOAD ;
837- if (trigger -> write )
838- tdata1 |= MCONTROL_STORE ;
839-
840- register_write_direct (target , GDB_REGNO_TDATA1 , tdata1 );
841-
842833 uint64_t tdata1_rb ;
843- register_read_direct (target , & tdata1_rb , GDB_REGNO_TDATA1 );
844- LOG_DEBUG ("tdata1=0x%" PRIx64 , tdata1_rb );
834+ for (int hartid = 0 ; hartid < riscv_count_harts (target ); ++ hartid ) {
835+ riscv_set_current_hartid (target , hartid );
836+
837+ if (hartid > 0 ) {
838+ register_write_direct (target , GDB_REGNO_TSELECT , i );
839+ }
840+
841+ // address/data match trigger
842+ tdata1 |= MCONTROL_DMODE (riscv_xlen (target ));
843+ tdata1 = set_field (tdata1 , MCONTROL_ACTION ,
844+ MCONTROL_ACTION_DEBUG_MODE );
845+ tdata1 = set_field (tdata1 , MCONTROL_MATCH , MCONTROL_MATCH_EQUAL );
846+ tdata1 |= MCONTROL_M ;
847+ if (info -> misa & (1 << ('H' - 'A' )))
848+ tdata1 |= MCONTROL_H ;
849+ if (info -> misa & (1 << ('S' - 'A' )))
850+ tdata1 |= MCONTROL_S ;
851+ if (info -> misa & (1 << ('U' - 'A' )))
852+ tdata1 |= MCONTROL_U ;
853+
854+ if (trigger -> execute )
855+ tdata1 |= MCONTROL_EXECUTE ;
856+ if (trigger -> read )
857+ tdata1 |= MCONTROL_LOAD ;
858+ if (trigger -> write )
859+ tdata1 |= MCONTROL_STORE ;
860+
861+ register_write_direct (target , GDB_REGNO_TDATA1 , tdata1 );
862+
863+ register_read_direct (target , & tdata1_rb , GDB_REGNO_TDATA1 );
864+ LOG_DEBUG ("tdata1=0x%" PRIx64 , tdata1_rb );
865+
866+ if (tdata1 != tdata1_rb ) {
867+ LOG_DEBUG ("Trigger %d doesn't support what we need; After writing 0x%"
868+ PRIx64 " to tdata1 it contains 0x%" PRIx64 ,
869+ i , tdata1 , tdata1_rb );
870+ register_write_direct (target , GDB_REGNO_TDATA1 , 0 );
871+ if (hartid > 0 ) {
872+ LOG_ERROR ("Setting hardware breakpoints requires "
873+ "homogeneous harts." );
874+ return ERROR_FAIL ;
875+ }
876+ break ;
877+ }
878+
879+ register_write_direct (target , GDB_REGNO_TDATA2 , trigger -> address );
880+ }
845881
846882 if (tdata1 != tdata1_rb ) {
847- LOG_DEBUG ("Trigger %d doesn't support what we need; After writing 0x%"
848- PRIx64 " to tdata1 it contains 0x%" PRIx64 ,
849- i , tdata1 , tdata1_rb );
850- register_write_direct (target , GDB_REGNO_TDATA1 , 0 );
851883 continue ;
852884 }
853885
854- register_write_direct (target , GDB_REGNO_TDATA2 , trigger -> address );
855-
856886 LOG_DEBUG ("Using resource %d for bp %d" , i ,
857887 trigger -> unique_id );
858888 info -> trigger_unique_id [i ] = trigger -> unique_id ;
@@ -870,6 +900,9 @@ static int remove_trigger(struct target *target, struct trigger *trigger)
870900{
871901 riscv013_info_t * info = get_info (target );
872902
903+ // Assume that all triggers are configured the same on all harts.
904+ riscv_set_current_hartid (target , 0 );
905+
873906 maybe_read_tselect (target );
874907
875908 int i ;
@@ -884,8 +917,11 @@ static int remove_trigger(struct target *target, struct trigger *trigger)
884917 return ERROR_FAIL ;
885918 }
886919 LOG_DEBUG ("Stop using resource %d for bp %d" , i , trigger -> unique_id );
887- register_write_direct (target , GDB_REGNO_TSELECT , i );
888- register_write_direct (target , GDB_REGNO_TDATA1 , 0 );
920+ for (int hartid = 0 ; hartid < riscv_count_harts (target ); ++ hartid ) {
921+ riscv_set_current_hartid (target , hartid );
922+ register_write_direct (target , GDB_REGNO_TSELECT , i );
923+ register_write_direct (target , GDB_REGNO_TDATA1 , 0 );
924+ }
889925 info -> trigger_unique_id [i ] = -1 ;
890926
891927 return ERROR_OK ;
0 commit comments