@@ -512,19 +512,30 @@ static int add_trigger(struct target *target, struct trigger *trigger)
512512
513513int riscv_add_breakpoint (struct target * target , struct breakpoint * breakpoint )
514514{
515+ assert (breakpoint );
515516 if (breakpoint -> type == BKPT_SOFT ) {
516- if (target_read_memory (target , breakpoint -> address , breakpoint -> length , 1 ,
517+ /// @todo check RVC for size/alignment
518+ if (!(breakpoint -> length == 4 || breakpoint -> length == 2 )) {
519+ LOG_ERROR ("Invalid breakpoint length %d" , breakpoint -> length );
520+ return ERROR_FAIL ;
521+ }
522+
523+ if (0 != (breakpoint -> address % 2 )) {
524+ LOG_ERROR ("Invalid breakpoint alignment for address 0x%" TARGET_PRIxADDR , breakpoint -> address );
525+ return ERROR_FAIL ;
526+ }
527+
528+ if (target_read_memory (target , breakpoint -> address , 2 , breakpoint -> length / 2 ,
517529 breakpoint -> orig_instr ) != ERROR_OK ) {
518530 LOG_ERROR ("Failed to read original instruction at 0x%" TARGET_PRIxADDR ,
519531 breakpoint -> address );
520532 return ERROR_FAIL ;
521533 }
522534
523- int retval ;
524- if (breakpoint -> length == 4 )
525- retval = target_write_u32 (target , breakpoint -> address , ebreak ());
526- else
527- retval = target_write_u16 (target , breakpoint -> address , ebreak_c ());
535+ uint8_t buff [4 ];
536+ buf_set_u32 (buff , 0 , breakpoint -> length * CHAR_BIT , breakpoint -> length == 4 ? ebreak () : ebreak_c ());
537+ int const retval = target_write_memory (target , breakpoint -> address , 2 , breakpoint -> length / 2 , buff );
538+
528539 if (retval != ERROR_OK ) {
529540 LOG_ERROR ("Failed to write %d-byte breakpoint instruction at 0x%"
530541 TARGET_PRIxADDR , breakpoint -> length , breakpoint -> address );
@@ -534,17 +545,15 @@ int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
534545 } else if (breakpoint -> type == BKPT_HARD ) {
535546 struct trigger trigger ;
536547 trigger_from_breakpoint (& trigger , breakpoint );
537- int result = add_trigger (target , & trigger );
548+ int const result = add_trigger (target , & trigger );
538549 if (result != ERROR_OK )
539550 return result ;
540-
541551 } else {
542552 LOG_INFO ("OpenOCD only supports hardware and software breakpoints." );
543553 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE ;
544554 }
545555
546556 breakpoint -> set = true;
547-
548557 return ERROR_OK ;
549558}
550559
@@ -597,7 +606,7 @@ int riscv_remove_breakpoint(struct target *target,
597606 struct breakpoint * breakpoint )
598607{
599608 if (breakpoint -> type == BKPT_SOFT ) {
600- if (target_write_memory (target , breakpoint -> address , breakpoint -> length , 1 ,
609+ if (target_write_memory (target , breakpoint -> address , 2 , breakpoint -> length / 2 ,
601610 breakpoint -> orig_instr ) != ERROR_OK ) {
602611 LOG_ERROR ("Failed to restore instruction for %d-byte breakpoint at "
603612 "0x%" TARGET_PRIxADDR , breakpoint -> length , breakpoint -> address );
0 commit comments