@@ -621,8 +621,17 @@ static int find_first_trigger_by_id(struct target *target, int unique_id)
621621 return -1 ;
622622}
623623
624- static int set_trigger (struct target * target , unsigned int idx , riscv_reg_t tdata1 , riscv_reg_t tdata2 ,
625- riscv_reg_t tdata1_ignore_mask )
624+ static unsigned int count_trailing_ones (riscv_reg_t reg )
625+ {
626+ assert (sizeof (riscv_reg_t ) * 8 == 64 );
627+ for (unsigned int i = 0 ; i < 64 ; i ++ ) {
628+ if ((1 & (reg >> i )) == 0 )
629+ return i ;
630+ }
631+ return 64 ;
632+ }
633+
634+ static int set_trigger (struct target * target , unsigned int idx , riscv_reg_t tdata1 , riscv_reg_t tdata2 )
626635{
627636 RISCV_INFO (r );
628637 assert (r -> reserved_triggers );
@@ -655,20 +664,51 @@ static int set_trigger(struct target *target, unsigned int idx, riscv_reg_t tdat
655664 return ERROR_FAIL ;
656665 if (riscv_reg_get (target , & tdata2_rb , GDB_REGNO_TDATA2 ) != ERROR_OK )
657666 return ERROR_FAIL ;
658- bool tdata1_config_denied = (tdata1 & ~tdata1_ignore_mask ) != (tdata1_rb & ~tdata1_ignore_mask );
659- bool tdata2_config_denied = tdata2 != tdata2_rb ;
660- if (tdata1_config_denied || tdata2_config_denied ) {
667+
668+ const uint32_t type = get_field (tdata1 , CSR_TDATA1_TYPE (riscv_xlen (target )));
669+ const bool is_mcontrol = type == CSR_TDATA1_TYPE_MCONTROL ;
670+
671+ /* Determine if tdata1 supports what we need.
672+ * For mcontrol triggers, we don't care about
673+ * the value in the read-only "maskmax" field.
674+ */
675+ const riscv_reg_t tdata1_ignore_mask = is_mcontrol ? CSR_MCONTROL_MASKMAX (riscv_xlen (target )) : 0 ;
676+ const bool tdata1_config_denied = (tdata1 & ~tdata1_ignore_mask ) != (tdata1_rb & ~tdata1_ignore_mask );
677+
678+ /* Determine if tdata1.maxmask is sufficient
679+ * (only relevant for mcontrol triggers and NAPOT match type)
680+ */
681+ bool unsupported_napot_range = false;
682+ riscv_reg_t maskmax_value = 0 ;
683+ if (!tdata1_config_denied ) {
684+ const bool is_napot_match = get_field (tdata1_rb , CSR_MCONTROL_MATCH ) == CSR_MCONTROL_MATCH_NAPOT ;
685+ if (is_mcontrol && is_napot_match ) {
686+ maskmax_value = get_field (tdata1_rb , CSR_MCONTROL_MASKMAX (riscv_xlen (target )));
687+ const unsigned int napot_size = count_trailing_ones (tdata2 ) + 1 ;
688+ if (maskmax_value < napot_size )
689+ unsupported_napot_range = true;
690+ }
691+ }
692+
693+ const bool tdata2_config_denied = tdata2 != tdata2_rb ;
694+ if (tdata1_config_denied || tdata2_config_denied || unsupported_napot_range ) {
661695 LOG_TARGET_DEBUG (target , "Trigger %u doesn't support what we need." , idx );
662696
663697 if (tdata1_config_denied )
664698 LOG_TARGET_DEBUG (target ,
665- "After writing 0x%" PRIx64 " to tdata1 it contains 0x%" PRIx64 "; tdata1_ignore_mask=0x%" PRIx64 ,
666- tdata1 , tdata1_rb , tdata1_ignore_mask );
699+ "After writing 0x%" PRIx64 " to tdata1 it contains 0x%" PRIx64 ,
700+ tdata1 , tdata1_rb );
667701
668702 if (tdata2_config_denied )
669703 LOG_TARGET_DEBUG (target ,
670- "wrote 0x%" PRIx64 " to tdata2 but read back 0x%" PRIx64 ,
704+ "After writing 0x%" PRIx64 " to tdata2 it contains 0x%" PRIx64 ,
671705 tdata2 , tdata2_rb );
706+
707+ if (unsupported_napot_range )
708+ LOG_TARGET_DEBUG (target ,
709+ "The requested NAPOT match range (tdata2=0x%" PRIx64 ") exceeds maskmax_value=0x%" PRIx64 ,
710+ tdata2 , maskmax_value );
711+
672712 if (riscv_reg_set (target , GDB_REGNO_TDATA1 , 0 ) != ERROR_OK )
673713 return ERROR_FAIL ;
674714 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE ;
@@ -717,7 +757,7 @@ static int maybe_add_trigger_t1(struct target *target, struct trigger *trigger)
717757 tdata1 = set_field (tdata1 , bpcontrol_bpaction , 0 ); /* cause bp exception */
718758 tdata1 = set_field (tdata1 , bpcontrol_bpmatch , 0 ); /* exact match */
719759 tdata2 = trigger -> address ;
720- ret = set_trigger (target , idx , tdata1 , tdata2 , 0 );
760+ ret = set_trigger (target , idx , tdata1 , tdata2 );
721761 if (ret != ERROR_OK )
722762 return ret ;
723763 r -> trigger_unique_id [idx ] = trigger -> unique_id ;
@@ -727,13 +767,11 @@ static int maybe_add_trigger_t1(struct target *target, struct trigger *trigger)
727767struct trigger_request_info {
728768 riscv_reg_t tdata1 ;
729769 riscv_reg_t tdata2 ;
730- riscv_reg_t tdata1_ignore_mask ;
731770};
732771
733772static void log_trigger_request_info (struct trigger_request_info trig_info )
734773{
735- LOG_DEBUG ("tdata1=%" PRIx64 ", tdata2=%" PRIx64 ", tdata1_ignore_mask=%" PRIx64 ,
736- trig_info .tdata1 , trig_info .tdata2 , trig_info .tdata1_ignore_mask );
774+ LOG_DEBUG ("tdata1=%" PRIx64 ", tdata2=%" PRIx64 , trig_info .tdata1 , trig_info .tdata2 );
737775};
738776
739777static struct tdata1_cache * tdata1_cache_alloc (struct list_head * tdata1_cache_head , riscv_reg_t tdata1 )
@@ -816,12 +854,12 @@ static bool wp_triggers_cache_search(struct target *target, unsigned int idx,
816854}
817855
818856static int try_use_trigger_and_cache_result (struct target * target , unsigned int idx , riscv_reg_t tdata1 ,
819- riscv_reg_t tdata2 , riscv_reg_t tdata1_ignore_mask )
857+ riscv_reg_t tdata2 )
820858{
821859 if (wp_triggers_cache_search (target , idx , tdata1 , tdata2 ))
822860 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE ;
823861
824- int ret = set_trigger (target , idx , tdata1 , tdata2 , tdata1_ignore_mask );
862+ int ret = set_trigger (target , idx , tdata1 , tdata2 );
825863
826864 /* Add these values to the cache to remember that they are not supported. */
827865 if (ret == ERROR_TARGET_RESOURCE_NOT_AVAILABLE )
@@ -844,8 +882,7 @@ static int try_setup_single_match_trigger(struct target *target,
844882 for (unsigned int idx = 0 ;
845883 find_next_free_trigger (target , trigger_type , false, & idx ) == ERROR_OK ;
846884 ++ idx ) {
847- ret = try_use_trigger_and_cache_result (target , idx , trig_info .tdata1 , trig_info .tdata2 ,
848- trig_info .tdata1_ignore_mask );
885+ ret = try_use_trigger_and_cache_result (target , idx , trig_info .tdata1 , trig_info .tdata2 );
849886
850887 if (ret == ERROR_OK ) {
851888 r -> trigger_unique_id [idx ] = trigger -> unique_id ;
@@ -873,24 +910,22 @@ static int try_setup_chained_match_triggers(struct target *target,
873910 for (unsigned int idx = 0 ;
874911 find_next_free_trigger (target , trigger_type , true, & idx ) == ERROR_OK ;
875912 ++ idx ) {
876- ret = try_use_trigger_and_cache_result (target , idx , t1 .tdata1 , t1 .tdata2 ,
877- t1 .tdata1_ignore_mask );
913+ ret = try_use_trigger_and_cache_result (target , idx , t1 .tdata1 , t1 .tdata2 );
878914
879915 if (ret == ERROR_TARGET_RESOURCE_NOT_AVAILABLE )
880916 continue ;
881917 else if (ret != ERROR_OK )
882918 return ret ;
883919
884- ret = try_use_trigger_and_cache_result (target , idx + 1 , t2 .tdata1 , t2 .tdata2 ,
885- t2 .tdata1_ignore_mask );
920+ ret = try_use_trigger_and_cache_result (target , idx + 1 , t2 .tdata1 , t2 .tdata2 );
886921
887922 if (ret == ERROR_OK ) {
888923 r -> trigger_unique_id [idx ] = trigger -> unique_id ;
889924 r -> trigger_unique_id [idx + 1 ] = trigger -> unique_id ;
890925 return ERROR_OK ;
891926 }
892927 /* Undo the setting of the previous trigger */
893- int ret_undo = set_trigger (target , idx , 0 , 0 , 0 );
928+ int ret_undo = set_trigger (target , idx , 0 , 0 );
894929 if (ret_undo != ERROR_OK )
895930 return ret_undo ;
896931
@@ -918,7 +953,6 @@ struct match_triggers_tdata1_fields {
918953 riscv_reg_t ge ;
919954 riscv_reg_t eq ;
920955 } match ;
921- riscv_reg_t tdata1_ignore_mask ;
922956};
923957
924958static struct match_triggers_tdata1_fields fill_match_triggers_tdata1_fields_t2 (struct target * target ,
@@ -951,8 +985,7 @@ static struct match_triggers_tdata1_fields fill_match_triggers_tdata1_fields_t2(
951985 .lt = field_value (CSR_MCONTROL_MATCH , CSR_MCONTROL_MATCH_LT ),
952986 .ge = field_value (CSR_MCONTROL_MATCH , CSR_MCONTROL_MATCH_GE ),
953987 .eq = field_value (CSR_MCONTROL_MATCH , CSR_MCONTROL_MATCH_EQUAL )
954- },
955- .tdata1_ignore_mask = CSR_MCONTROL_MASKMAX (riscv_xlen (target ))
988+ }
956989 };
957990 return result ;
958991}
@@ -989,8 +1022,7 @@ static struct match_triggers_tdata1_fields fill_match_triggers_tdata1_fields_t6(
9891022 .lt = field_value (CSR_MCONTROL6_MATCH , CSR_MCONTROL6_MATCH_LT ),
9901023 .ge = field_value (CSR_MCONTROL6_MATCH , CSR_MCONTROL6_MATCH_GE ),
9911024 .eq = field_value (CSR_MCONTROL6_MATCH , CSR_MCONTROL6_MATCH_EQUAL )
992- },
993- .tdata1_ignore_mask = 0
1025+ }
9941026 };
9951027 return result ;
9961028}
@@ -1009,8 +1041,7 @@ static int maybe_add_trigger_t2_t6_for_wp(struct target *target,
10091041 struct trigger_request_info napot = {
10101042 .tdata1 = fields .common | fields .size .any |
10111043 fields .chain .disable | fields .match .napot ,
1012- .tdata2 = trigger -> address | ((trigger -> length - 1 ) >> 1 ),
1013- .tdata1_ignore_mask = fields .tdata1_ignore_mask
1044+ .tdata2 = trigger -> address | ((trigger -> length - 1 ) >> 1 )
10141045 };
10151046 ret = try_setup_single_match_trigger (target , trigger , napot );
10161047 if (ret != ERROR_TARGET_RESOURCE_NOT_AVAILABLE )
@@ -1026,14 +1057,12 @@ static int maybe_add_trigger_t2_t6_for_wp(struct target *target,
10261057 struct trigger_request_info ge_1 = {
10271058 .tdata1 = fields .common | fields .size .any | fields .chain .enable |
10281059 fields .match .ge ,
1029- .tdata2 = trigger -> address ,
1030- .tdata1_ignore_mask = fields .tdata1_ignore_mask
1060+ .tdata2 = trigger -> address
10311061 };
10321062 struct trigger_request_info lt_2 = {
10331063 .tdata1 = fields .common | fields .size .any | fields .chain .disable |
10341064 fields .match .lt ,
1035- .tdata2 = trigger -> address + trigger -> length ,
1036- .tdata1_ignore_mask = fields .tdata1_ignore_mask
1065+ .tdata2 = trigger -> address + trigger -> length
10371066 };
10381067 ret = try_setup_chained_match_triggers (target , trigger , ge_1 , lt_2 );
10391068 if (ret != ERROR_TARGET_RESOURCE_NOT_AVAILABLE )
@@ -1043,14 +1072,12 @@ static int maybe_add_trigger_t2_t6_for_wp(struct target *target,
10431072 struct trigger_request_info lt_1 = {
10441073 .tdata1 = fields .common | fields .size .any | fields .chain .enable |
10451074 fields .match .lt ,
1046- .tdata2 = trigger -> address + trigger -> length ,
1047- .tdata1_ignore_mask = fields .tdata1_ignore_mask
1075+ .tdata2 = trigger -> address + trigger -> length
10481076 };
10491077 struct trigger_request_info ge_2 = {
10501078 .tdata1 = fields .common | fields .size .any | fields .chain .disable |
10511079 fields .match .ge ,
1052- .tdata2 = trigger -> address ,
1053- .tdata1_ignore_mask = fields .tdata1_ignore_mask
1080+ .tdata2 = trigger -> address
10541081 };
10551082 ret = try_setup_chained_match_triggers (target , trigger , lt_1 , ge_2 );
10561083 if (ret != ERROR_TARGET_RESOURCE_NOT_AVAILABLE )
@@ -1066,8 +1093,7 @@ static int maybe_add_trigger_t2_t6_for_wp(struct target *target,
10661093 struct trigger_request_info eq = {
10671094 .tdata1 = fields .common | fields .size .any | fields .chain .disable |
10681095 fields .match .eq ,
1069- .tdata2 = trigger -> address ,
1070- .tdata1_ignore_mask = fields .tdata1_ignore_mask
1096+ .tdata2 = trigger -> address
10711097 };
10721098 ret = try_setup_single_match_trigger (target , trigger , eq );
10731099 if (ret != ERROR_OK )
@@ -1104,8 +1130,7 @@ static int maybe_add_trigger_t2_t6_for_bp(struct target *target,
11041130 struct trigger_request_info eq = {
11051131 .tdata1 = fields .common | fields .size .any | fields .chain .disable |
11061132 fields .match .eq ,
1107- .tdata2 = trigger -> address ,
1108- .tdata1_ignore_mask = fields .tdata1_ignore_mask
1133+ .tdata2 = trigger -> address
11091134 };
11101135
11111136 return try_setup_single_match_trigger (target , trigger , eq );
@@ -1148,7 +1173,7 @@ static int maybe_add_trigger_t3(struct target *target, bool vs, bool vu,
11481173 ret = find_next_free_trigger (target , CSR_TDATA1_TYPE_ICOUNT , false, & idx );
11491174 if (ret != ERROR_OK )
11501175 return ret ;
1151- ret = set_trigger (target , idx , tdata1 , 0 , 0 );
1176+ ret = set_trigger (target , idx , tdata1 , 0 );
11521177 if (ret != ERROR_OK )
11531178 return ret ;
11541179 r -> trigger_unique_id [idx ] = unique_id ;
@@ -1181,7 +1206,7 @@ static int maybe_add_trigger_t4(struct target *target, bool vs, bool vu,
11811206 ret = find_next_free_trigger (target , CSR_TDATA1_TYPE_ITRIGGER , false, & idx );
11821207 if (ret != ERROR_OK )
11831208 return ret ;
1184- ret = set_trigger (target , idx , tdata1 , tdata2 , 0 );
1209+ ret = set_trigger (target , idx , tdata1 , tdata2 );
11851210 if (ret != ERROR_OK )
11861211 return ret ;
11871212 r -> trigger_unique_id [idx ] = unique_id ;
@@ -1213,7 +1238,7 @@ static int maybe_add_trigger_t5(struct target *target, bool vs, bool vu,
12131238 ret = find_next_free_trigger (target , CSR_TDATA1_TYPE_ETRIGGER , false, & idx );
12141239 if (ret != ERROR_OK )
12151240 return ret ;
1216- ret = set_trigger (target , idx , tdata1 , tdata2 , 0 );
1241+ ret = set_trigger (target , idx , tdata1 , tdata2 );
12171242 if (ret != ERROR_OK )
12181243 return ret ;
12191244 r -> trigger_unique_id [idx ] = unique_id ;
0 commit comments