@@ -578,45 +578,6 @@ static int wait_for_idle(struct target *target, uint32_t *abstractcs)
578578 }
579579}
580580
581- static int register_read_direct (struct target * target , uint64_t * value , uint32_t number );
582-
583- static int register_write_direct (struct target * target , unsigned number ,
584- uint64_t value )
585- {
586- struct riscv_program program ;
587-
588- LOG_DEBUG ("[%d] reg[0x%x] <- 0x%" PRIx64 , riscv_current_hartid (target ),
589- number , value );
590-
591- riscv_program_init (& program , target );
592-
593- riscv_addr_t input = riscv_program_alloc_d (& program );
594- riscv_program_write_ram (& program , input + 4 , value >> 32 );
595- riscv_program_write_ram (& program , input , value );
596-
597- assert (GDB_REGNO_XPR0 == 0 );
598- if (number <= GDB_REGNO_XPR31 ) {
599- riscv_program_lx (& program , number , input );
600- } else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 ) {
601- riscv_program_fld (& program , number , input );
602- } else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095 ) {
603- enum gdb_regno temp = riscv_program_gettemp (& program );
604- riscv_program_lx (& program , temp , input );
605- riscv_program_csrw (& program , temp , number );
606- } else {
607- LOG_ERROR ("Unsupported register (enum gdb_regno)(%d)" , number );
608- abort ();
609- }
610-
611- int exec_out = riscv_program_exec (& program , target );
612- if (exec_out != ERROR_OK ) {
613- riscv013_clear_abstract_error (target );
614- return ERROR_FAIL ;
615- }
616-
617- return ERROR_OK ;
618- }
619-
620581static int execute_abstract_command (struct target * target , uint32_t command )
621582{
622583 LOG_DEBUG ("command=0x%x" , command );
@@ -640,9 +601,9 @@ static int execute_abstract_command(struct target *target, uint32_t command)
640601 return ERROR_OK ;
641602}
642603
643- static uint64_t read_abstract_arg (struct target * target , unsigned index )
604+ static riscv_reg_t read_abstract_arg (struct target * target , unsigned index )
644605{
645- uint64_t value = 0 ;
606+ riscv_reg_t value = 0 ;
646607 unsigned xlen = riscv_xlen (target );
647608 unsigned offset = index * xlen / 32 ;
648609 switch (xlen ) {
@@ -657,6 +618,23 @@ static uint64_t read_abstract_arg(struct target *target, unsigned index)
657618 return value ;
658619}
659620
621+ static int write_abstract_arg (struct target * target , unsigned index ,
622+ riscv_reg_t value )
623+ {
624+ unsigned xlen = riscv_xlen (target );
625+ unsigned offset = index * xlen / 32 ;
626+ switch (xlen ) {
627+ default :
628+ LOG_ERROR ("Unsupported xlen: %d" , xlen );
629+ return ~0 ;
630+ case 64 :
631+ dmi_write (target , DMI_DATA0 + offset + 1 , value >> 32 );
632+ case 32 :
633+ dmi_write (target , DMI_DATA0 + offset , value );
634+ }
635+ return ERROR_OK ;
636+ }
637+
660638static int register_read_abstract (struct target * target , uint64_t * value ,
661639 uint32_t number , unsigned size )
662640{
@@ -712,30 +690,91 @@ static int register_read_abstract(struct target *target, uint64_t *value,
712690 return ERROR_OK ;
713691}
714692
715- /** Actually read registers from the target right now. */
716- static int register_read_direct ( struct target * target , uint64_t * value , uint32_t number )
693+ static int register_write_abstract ( struct target * target , uint32_t number ,
694+ uint64_t value , unsigned size )
717695{
718- int result = register_read_abstract (target , value , number ,
696+ RISCV013_INFO (r );
697+
698+ uint32_t command = set_field (0 , DMI_COMMAND_CMDTYPE , 0 );
699+ switch (size ) {
700+ case 32 :
701+ command = set_field (command , AC_ACCESS_REGISTER_SIZE , 2 );
702+ break ;
703+ case 64 :
704+ command = set_field (command , AC_ACCESS_REGISTER_SIZE , 3 );
705+ break ;
706+ default :
707+ LOG_ERROR ("Unsupported abstract register read size: %d" , size );
708+ return ERROR_FAIL ;
709+ }
710+ command = set_field (command , AC_ACCESS_REGISTER_POSTEXEC , 0 );
711+ command = set_field (command , AC_ACCESS_REGISTER_TRANSFER , 1 );
712+ command = set_field (command , AC_ACCESS_REGISTER_WRITE , 1 );
713+
714+ if (number <= GDB_REGNO_XPR31 ) {
715+ command = set_field (command , AC_ACCESS_REGISTER_REGNO ,
716+ 0x1000 + number - GDB_REGNO_XPR0 );
717+ } else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 ) {
718+ if (!r -> abstract_read_fpr_supported )
719+ return ERROR_FAIL ;
720+ command = set_field (command , AC_ACCESS_REGISTER_REGNO ,
721+ 0x1020 + number - GDB_REGNO_FPR0 );
722+ } else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095 ) {
723+ if (!r -> abstract_read_csr_supported )
724+ return ERROR_FAIL ;
725+ command = set_field (command , AC_ACCESS_REGISTER_REGNO ,
726+ number - GDB_REGNO_CSR0 );
727+ } else {
728+ return ERROR_FAIL ;
729+ }
730+
731+ if (write_abstract_arg (target , 0 , value ) != ERROR_OK ) {
732+ return ERROR_FAIL ;
733+ }
734+
735+ int result = execute_abstract_command (target , command );
736+ if (result != ERROR_OK ) {
737+ if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 ) {
738+ r -> abstract_write_fpr_supported = false;
739+ LOG_INFO ("Disabling abstract command writes to FPRs." );
740+ } else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095 ) {
741+ r -> abstract_write_csr_supported = false;
742+ LOG_INFO ("Disabling abstract command writes to CSRs." );
743+ }
744+ return result ;
745+ }
746+
747+ return ERROR_OK ;
748+ }
749+
750+ static int register_write_direct (struct target * target , unsigned number ,
751+ uint64_t value )
752+ {
753+ LOG_DEBUG ("[%d] reg[0x%x] <- 0x%" PRIx64 , riscv_current_hartid (target ),
754+ number , value );
755+
756+ int result = register_write_abstract (target , number , value ,
719757 riscv_xlen (target ));
720758 if (result == ERROR_OK )
721759 return ERROR_OK ;
722760
723761 struct riscv_program program ;
762+
724763 riscv_program_init (& program , target );
725- riscv_addr_t output = riscv_program_alloc_d (& program );
726- riscv_program_write_ram (& program , output + 4 , 0 );
727- riscv_program_write_ram (& program , output , 0 );
764+
765+ riscv_addr_t input = riscv_program_alloc_d (& program );
766+ riscv_program_write_ram (& program , input + 4 , value >> 32 );
767+ riscv_program_write_ram (& program , input , value );
728768
729769 assert (GDB_REGNO_XPR0 == 0 );
730770 if (number <= GDB_REGNO_XPR31 ) {
731- riscv_program_sx (& program , number , output );
771+ riscv_program_lx (& program , number , input );
732772 } else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 ) {
733- riscv_program_fsd (& program , number , output );
773+ riscv_program_fld (& program , number , input );
734774 } else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095 ) {
735- LOG_DEBUG ("reading CSR index=0x%03x" , number - GDB_REGNO_CSR0 );
736775 enum gdb_regno temp = riscv_program_gettemp (& program );
737- riscv_program_csrr (& program , temp , number );
738- riscv_program_sx (& program , temp , output );
776+ riscv_program_lx (& program , temp , input );
777+ riscv_program_csrw (& program , temp , number );
739778 } else {
740779 LOG_ERROR ("Unsupported register (enum gdb_regno)(%d)" , number );
741780 abort ();
@@ -747,9 +786,48 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
747786 return ERROR_FAIL ;
748787 }
749788
750- * value = 0 ;
751- * value |= ((uint64_t )(riscv_program_read_ram (& program , output + 4 ))) << 32 ;
752- * value |= riscv_program_read_ram (& program , output );
789+ return ERROR_OK ;
790+ }
791+
792+ /** Actually read registers from the target right now. */
793+ static int register_read_direct (struct target * target , uint64_t * value , uint32_t number )
794+ {
795+ int result = register_read_abstract (target , value , number ,
796+ riscv_xlen (target ));
797+
798+ if (result != ERROR_OK ) {
799+ struct riscv_program program ;
800+ riscv_program_init (& program , target );
801+ riscv_addr_t output = riscv_program_alloc_d (& program );
802+ riscv_program_write_ram (& program , output + 4 , 0 );
803+ riscv_program_write_ram (& program , output , 0 );
804+
805+ assert (GDB_REGNO_XPR0 == 0 );
806+ if (number <= GDB_REGNO_XPR31 ) {
807+ riscv_program_sx (& program , number , output );
808+ } else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 ) {
809+ riscv_program_fsd (& program , number , output );
810+ } else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095 ) {
811+ LOG_DEBUG ("reading CSR index=0x%03x" , number - GDB_REGNO_CSR0 );
812+ enum gdb_regno temp = riscv_program_gettemp (& program );
813+ riscv_program_csrr (& program , temp , number );
814+ riscv_program_sx (& program , temp , output );
815+ } else {
816+ LOG_ERROR ("Unsupported register (enum gdb_regno)(%d)" , number );
817+ abort ();
818+ }
819+
820+ int exec_out = riscv_program_exec (& program , target );
821+ if (exec_out != ERROR_OK ) {
822+ riscv013_clear_abstract_error (target );
823+ return ERROR_FAIL ;
824+ }
825+
826+ * value = 0 ;
827+ * value |= ((uint64_t )(riscv_program_read_ram (& program , output + 4 ))) << 32 ;
828+ * value |= riscv_program_read_ram (& program , output );
829+ }
830+
753831 LOG_DEBUG ("[%d] reg[0x%x] = 0x%" PRIx64 , riscv_current_hartid (target ),
754832 number , * value );
755833 return ERROR_OK ;
0 commit comments