@@ -402,10 +402,101 @@ int esp_riscv_alloc_trigger_addr(struct target *target)
402402 return ERROR_OK ;
403403}
404404
405+ static void esp_riscv_set_bp_wp_address (struct target * target , int id , target_addr_t address , bool is_bp )
406+ {
407+ if (target -> smp ) {
408+ struct target_list * head ;
409+ foreach_smp_target (head , target -> smp_targets ) {
410+ struct esp_riscv_common * esp_riscv = target_to_esp_riscv (head -> target );
411+ target_addr_t * target_bp_wp_addr = is_bp ? esp_riscv -> target_bp_addr : esp_riscv -> target_wp_addr ;
412+ target_bp_wp_addr [id ] = address ;
413+ }
414+ return ;
415+ }
416+
417+ struct esp_riscv_common * esp_riscv = target_to_esp_riscv (target );
418+ target_addr_t * target_bp_wp_addr = is_bp ? esp_riscv -> target_bp_addr : esp_riscv -> target_wp_addr ;
419+ target_bp_wp_addr [id ] = address ;
420+ }
421+
422+ static int esp_riscv_set_bp (struct target * target )
423+ {
424+ struct esp_riscv_common * esp_riscv = target_to_esp_riscv (target );
425+ /* Enough space to hold 3 long words for both riscv32 and riscv64 archs. */
426+ uint8_t fields [ESP_RISCV_SET_BREAKPOINT_ARG_MAX * sizeof (uint64_t )];
427+ int res = semihosting_read_fields (target , ESP_RISCV_SET_BREAKPOINT_ARG_MAX , fields );
428+ if (res != ERROR_OK )
429+ return res ;
430+ int id = semihosting_get_field (target , ESP_RISCV_SET_BREAKPOINT_ARG_ID , fields );
431+ if (id >= esp_riscv -> max_bp_num ) {
432+ LOG_ERROR ("Unsupported breakpoint ID (%d)!" , id );
433+ return ERROR_FAIL ;
434+ }
435+ int set = semihosting_get_field (target , ESP_RISCV_SET_BREAKPOINT_ARG_SET , fields );
436+ LOG_TARGET_DEBUG (target , "set:%d target_bp_addr[%d]:" TARGET_ADDR_FMT , set , id , esp_riscv -> target_bp_addr [id ]);
437+ /* Remove existing bp if present. */
438+ if (esp_riscv -> target_bp_addr [id ]) {
439+ breakpoint_remove (target , esp_riscv -> target_bp_addr [id ]);
440+ esp_riscv_set_bp_wp_address (target , id , 0 , true);
441+ }
442+ if (set ) {
443+ target_addr_t address = semihosting_get_field (target , ESP_RISCV_SET_BREAKPOINT_ARG_ADDR , fields );
444+ res = breakpoint_add (target , address , 2 , BKPT_HARD );
445+ if (res == ERROR_OK )
446+ esp_riscv_set_bp_wp_address (target , id , address , true);
447+ }
448+ return res ;
449+ }
450+
451+ static int esp_riscv_set_wp (struct target * target )
452+ {
453+ struct esp_riscv_common * esp_riscv = target_to_esp_riscv (target );
454+ /* Enough space to hold 5 long words for both riscv32 and riscv64 archs. */
455+ uint8_t fields [ESP_RISCV_SET_WATCHPOINT_ARG_MAX * sizeof (uint64_t )];
456+ int res = semihosting_read_fields (target , ESP_RISCV_SET_WATCHPOINT_ARG_MAX , fields );
457+ if (res != ERROR_OK )
458+ return res ;
459+ int id = semihosting_get_field (target , ESP_RISCV_SET_WATCHPOINT_ARG_ID , fields );
460+ if (id >= esp_riscv -> max_wp_num ) {
461+ LOG_ERROR ("Unsupported watchpoint ID (%d)!" , id );
462+ return ERROR_FAIL ;
463+ }
464+ int set = semihosting_get_field (target , ESP_RISCV_SET_WATCHPOINT_ARG_SET , fields );
465+ LOG_TARGET_DEBUG (target , "set:%d target_wp_addr[%d]:" TARGET_ADDR_FMT , set , id , esp_riscv -> target_wp_addr [id ]);
466+ /* Remove existing wp if present. */
467+ if (esp_riscv -> target_wp_addr [id ]) {
468+ watchpoint_remove (target , esp_riscv -> target_wp_addr [id ]);
469+ esp_riscv_set_bp_wp_address (target , id , 0 , false);
470+ }
471+ if (set ) {
472+ target_addr_t address = semihosting_get_field (target , ESP_RISCV_SET_WATCHPOINT_ARG_ADDR , fields );
473+ int size = semihosting_get_field (target , ESP_RISCV_SET_WATCHPOINT_ARG_SIZE , fields );
474+ int flags = semihosting_get_field (target , ESP_RISCV_SET_WATCHPOINT_ARG_FLAGS , fields );
475+ enum watchpoint_rw wp_type ;
476+ switch (flags & (ESP_SEMIHOSTING_WP_FLG_RD | ESP_SEMIHOSTING_WP_FLG_WR )) {
477+ case ESP_SEMIHOSTING_WP_FLG_RD :
478+ wp_type = WPT_READ ;
479+ break ;
480+ case ESP_SEMIHOSTING_WP_FLG_WR :
481+ wp_type = WPT_WRITE ;
482+ break ;
483+ case ESP_SEMIHOSTING_WP_FLG_RD | ESP_SEMIHOSTING_WP_FLG_WR :
484+ wp_type = WPT_ACCESS ;
485+ break ;
486+ default :
487+ LOG_ERROR ("Unsupported watchpoint type (0x%x)!" , flags );
488+ return ERROR_FAIL ;
489+ }
490+ res = watchpoint_add (target , address , size , wp_type , 0 , WATCHPOINT_IGNORE_DATA_VALUE_MASK );
491+ if (res == ERROR_OK )
492+ esp_riscv_set_bp_wp_address (target , id , address , false);
493+ }
494+ return res ;
495+ }
496+
405497int esp_riscv_semihosting (struct target * target )
406498{
407499 int res = ERROR_OK ;
408- struct esp_riscv_common * esp_riscv = target_to_esp_riscv (target );
409500 struct semihosting * semihosting = target -> semihosting ;
410501
411502 /*
@@ -436,106 +527,15 @@ int esp_riscv_semihosting(struct target *target)
436527 return res ;
437528 break ;
438529 case ESP_SEMIHOSTING_SYS_BREAKPOINT_SET :
439- {
440- /* Enough space to hold 3 long words for both riscv32 and riscv64 archs. */
441- uint8_t fields [ESP_RISCV_SET_BREAKPOINT_ARG_MAX * sizeof (uint64_t )];
442- res = semihosting_read_fields (target ,
443- ESP_RISCV_SET_BREAKPOINT_ARG_MAX ,
444- fields );
530+ res = esp_riscv_set_bp (target );
445531 if (res != ERROR_OK )
446532 return res ;
447- int id = semihosting_get_field (target ,
448- ESP_RISCV_SET_BREAKPOINT_ARG_ID ,
449- fields );
450- if (id >= esp_riscv -> max_bp_num ) {
451- LOG_ERROR ("Unsupported breakpoint ID (%d)!" , id );
452- return ERROR_FAIL ;
453- }
454- int set = semihosting_get_field (target ,
455- ESP_RISCV_SET_BREAKPOINT_ARG_SET ,
456- fields );
457- if (set ) {
458- if (esp_riscv -> target_bp_addr [id ]) {
459- breakpoint_remove (target , esp_riscv -> target_bp_addr [id ]);
460- }
461- esp_riscv -> target_bp_addr [id ] = semihosting_get_field (target ,
462- ESP_RISCV_SET_BREAKPOINT_ARG_ADDR ,
463- fields );
464- res = breakpoint_add (target ,
465- esp_riscv -> target_bp_addr [id ],
466- 2 ,
467- BKPT_HARD );
468- if (res != ERROR_OK )
469- return res ;
470- } else {
471- breakpoint_remove (target , esp_riscv -> target_bp_addr [id ]);
472- esp_riscv -> target_bp_addr [id ] = 0 ;
473- }
474533 break ;
475- }
476534 case ESP_SEMIHOSTING_SYS_WATCHPOINT_SET :
477- {
478- /* Enough space to hold 5 long words for both riscv32 and riscv64 archs. */
479- uint8_t fields [ESP_RISCV_SET_WATCHPOINT_ARG_MAX * sizeof (uint64_t )];
480- res = semihosting_read_fields (target ,
481- ESP_RISCV_SET_WATCHPOINT_ARG_MAX ,
482- fields );
535+ res = esp_riscv_set_wp (target );
483536 if (res != ERROR_OK )
484537 return res ;
485- int id = semihosting_get_field (target ,
486- ESP_RISCV_SET_WATCHPOINT_ARG_ID ,
487- fields );
488- if (id >= esp_riscv -> max_wp_num ) {
489- LOG_ERROR ("Unsupported watchpoint ID (%d)!" , id );
490- return ERROR_FAIL ;
491- }
492- int set = semihosting_get_field (target ,
493- ESP_RISCV_SET_WATCHPOINT_ARG_SET ,
494- fields );
495- if (set ) {
496- if (esp_riscv -> target_wp_addr [id ]) {
497- watchpoint_remove (target , esp_riscv -> target_wp_addr [id ]);
498- }
499- esp_riscv -> target_wp_addr [id ] = semihosting_get_field (target ,
500- ESP_RISCV_SET_WATCHPOINT_ARG_ADDR ,
501- fields );
502- int size = semihosting_get_field (target ,
503- ESP_RISCV_SET_WATCHPOINT_ARG_SIZE ,
504- fields );
505- int flags = semihosting_get_field (target ,
506- ESP_RISCV_SET_WATCHPOINT_ARG_FLAGS ,
507- fields );
508- enum watchpoint_rw wp_type ;
509- switch (flags &
510- (ESP_SEMIHOSTING_WP_FLG_RD | ESP_SEMIHOSTING_WP_FLG_WR )) {
511- case ESP_SEMIHOSTING_WP_FLG_RD :
512- wp_type = WPT_READ ;
513- break ;
514- case ESP_SEMIHOSTING_WP_FLG_WR :
515- wp_type = WPT_WRITE ;
516- break ;
517- case ESP_SEMIHOSTING_WP_FLG_RD | ESP_SEMIHOSTING_WP_FLG_WR :
518- wp_type = WPT_ACCESS ;
519- break ;
520- default :
521- LOG_ERROR ("Unsupported watchpoint type (0x%x)!" ,
522- flags );
523- return ERROR_FAIL ;
524- }
525- res = watchpoint_add (target ,
526- esp_riscv -> target_wp_addr [id ],
527- size ,
528- wp_type ,
529- 0 ,
530- WATCHPOINT_IGNORE_DATA_VALUE_MASK );
531- if (res != ERROR_OK )
532- return res ;
533- } else {
534- watchpoint_remove (target , esp_riscv -> target_wp_addr [id ]);
535- esp_riscv -> target_wp_addr [id ] = 0 ;
536- }
537538 break ;
538- }
539539 default :
540540 return ERROR_FAIL ;
541541 }
0 commit comments