@@ -187,55 +187,60 @@ typedef struct {
187187
188188 // Some memoized values
189189 int progbuf_size , progbuf_addr , data_addr , data_size ;
190+
191+ bool abstract_read_csr_supported ;
192+ bool abstract_write_csr_supported ;
193+ bool abstract_read_fpr_supported ;
194+ bool abstract_write_fpr_supported ;
190195} riscv013_info_t ;
191196
192197static void decode_dmi (char * text , unsigned address , unsigned data )
193198{
199+ static const struct {
200+ unsigned address ;
201+ uint64_t mask ;
202+ const char * name ;
203+ } description [] = {
204+ { DMI_DMSTATUS , DMI_DMSTATUS_ALLRESUMEACK , "allresumeack" },
205+ { DMI_DMSTATUS , DMI_DMSTATUS_ANYRESUMEACK , "anyresumeack" },
206+ { DMI_DMSTATUS , DMI_DMSTATUS_ALLNONEXISTENT , "allnonexistent" },
207+ { DMI_DMSTATUS , DMI_DMSTATUS_ANYNONEXISTENT , "anynonexistent" },
208+ { DMI_DMSTATUS , DMI_DMSTATUS_ALLUNAVAIL , "allunavail" },
209+ { DMI_DMSTATUS , DMI_DMSTATUS_ANYUNAVAIL , "anyunavail" },
210+ { DMI_DMSTATUS , DMI_DMSTATUS_ALLRUNNING , "allrunning" },
211+ { DMI_DMSTATUS , DMI_DMSTATUS_ANYRUNNING , "anyrunning" },
212+ { DMI_DMSTATUS , DMI_DMSTATUS_ALLHALTED , "allhalted" },
213+ { DMI_DMSTATUS , DMI_DMSTATUS_ANYHALTED , "anyhalted" },
214+ { DMI_DMSTATUS , DMI_DMSTATUS_AUTHENTICATED , "authenticated" },
215+ { DMI_DMSTATUS , DMI_DMSTATUS_AUTHBUSY , "authbusy" },
216+ { DMI_DMSTATUS , DMI_DMSTATUS_CFGSTRVALID , "cfgstrvalid" },
217+ { DMI_DMSTATUS , DMI_DMSTATUS_VERSION , "version" },
218+
219+ { DMI_ABSTRACTCS , DMI_ABSTRACTCS_PROGSIZE , "progsize" },
220+ { DMI_ABSTRACTCS , DMI_ABSTRACTCS_BUSY , "busy" },
221+ { DMI_ABSTRACTCS , DMI_ABSTRACTCS_CMDERR , "cmderr" },
222+ { DMI_ABSTRACTCS , DMI_ABSTRACTCS_DATACOUNT , "datacount" },
223+
224+ { DMI_COMMAND , DMI_COMMAND_CMDTYPE , "cmdtype" },
225+ };
226+
194227 text [0 ] = 0 ;
195- switch (address ) {
196- case DMI_DMSTATUS :
197- if (get_field (data , DMI_DMSTATUS_ALLRESUMEACK )) {
198- strcat (text , " allresumeack" );
199- }
200- if (get_field (data , DMI_DMSTATUS_ANYRESUMEACK )) {
201- strcat (text , " anyresumeack" );
202- }
203- if (get_field (data , DMI_DMSTATUS_ALLNONEXISTENT )) {
204- strcat (text , " allnonexistent" );
205- }
206- if (get_field (data , DMI_DMSTATUS_ANYNONEXISTENT )) {
207- strcat (text , " anynonexistent" );
208- }
209- if (get_field (data , DMI_DMSTATUS_ALLUNAVAIL )) {
210- strcat (text , " allunavail" );
211- }
212- if (get_field (data , DMI_DMSTATUS_ANYUNAVAIL )) {
213- strcat (text , " anyunavail" );
214- }
215- if (get_field (data , DMI_DMSTATUS_ALLRUNNING )) {
216- strcat (text , " allrunning" );
217- }
218- if (get_field (data , DMI_DMSTATUS_ANYRUNNING )) {
219- strcat (text , " anyrunning" );
220- }
221- if (get_field (data , DMI_DMSTATUS_ALLHALTED )) {
222- strcat (text , " allhalted" );
223- }
224- if (get_field (data , DMI_DMSTATUS_ANYHALTED )) {
225- strcat (text , " anyhalted" );
226- }
227- if (get_field (data , DMI_DMSTATUS_AUTHENTICATED )) {
228- strcat (text , " authenticated" );
229- }
230- if (get_field (data , DMI_DMSTATUS_AUTHBUSY )) {
231- strcat (text , " authbusy" );
232- }
233- if (get_field (data , DMI_DMSTATUS_CFGSTRVALID )) {
234- strcat (text , " cfgstrvalid" );
228+ for (unsigned i = 0 ; i < DIM (description ); i ++ ) {
229+ if (description [i ].address == address ) {
230+ uint64_t mask = description [i ].mask ;
231+ unsigned value = get_field (data , mask );
232+ if (value ) {
233+ if (i > 0 )
234+ * (text ++ ) = ' ' ;
235+ if (mask & (mask >> 1 )) {
236+ // If the field is more than 1 bit wide.
237+ sprintf (text , "%s=%d" , description [i ].name , value );
238+ } else {
239+ strcpy (text , description [i ].name );
240+ }
241+ text += strlen (text );
235242 }
236- sprintf (text + strlen (text ), " version=%d" , get_field (data ,
237- DMI_DMSTATUS_VERSION ));
238- break ;
243+ }
239244 }
240245}
241246
@@ -612,9 +617,109 @@ static int register_write_direct(struct target *target, unsigned number,
612617 return ERROR_OK ;
613618}
614619
620+ static int execute_abstract_command (struct target * target , uint32_t command )
621+ {
622+ LOG_DEBUG ("command=0x%x" , command );
623+ dmi_write (target , DMI_COMMAND , command );
624+
625+ {
626+ uint32_t dmstatus = 0 ;
627+ wait_for_idle (target , & dmstatus );
628+ }
629+
630+ uint32_t cs = dmi_read (target , DMI_ABSTRACTCS );
631+ unsigned cmderr = get_field (cs , DMI_ABSTRACTCS_CMDERR );
632+ if (cmderr != 0 ) {
633+ LOG_DEBUG ("command 0x%x failed; abstractcs=0x%x" , command , cs );
634+ // Clear the error.
635+ dmi_write (target , DMI_ABSTRACTCS , set_field (0 , DMI_ABSTRACTCS_CMDERR ,
636+ cmderr ));
637+ return ERROR_FAIL ;
638+ }
639+
640+ return ERROR_OK ;
641+ }
642+
643+ static uint64_t read_abstract_arg (struct target * target , unsigned index )
644+ {
645+ uint64_t value = 0 ;
646+ unsigned xlen = riscv_xlen (target );
647+ unsigned offset = index * xlen / 32 ;
648+ switch (xlen ) {
649+ default :
650+ LOG_ERROR ("Unsupported xlen: %d" , xlen );
651+ return ~0 ;
652+ case 64 :
653+ value |= ((uint64_t ) dmi_read (target , DMI_DATA0 + offset + 1 )) << 32 ;
654+ case 32 :
655+ value |= dmi_read (target , DMI_DATA0 + offset );
656+ }
657+ return value ;
658+ }
659+
660+ static int register_read_abstract (struct target * target , uint64_t * value ,
661+ uint32_t number , unsigned size )
662+ {
663+ RISCV013_INFO (r );
664+
665+ uint32_t command = set_field (0 , DMI_COMMAND_CMDTYPE , 0 );
666+ switch (size ) {
667+ case 32 :
668+ command = set_field (command , AC_ACCESS_REGISTER_SIZE , 2 );
669+ break ;
670+ case 64 :
671+ command = set_field (command , AC_ACCESS_REGISTER_SIZE , 3 );
672+ break ;
673+ default :
674+ LOG_ERROR ("Unsupported abstract register read size: %d" , size );
675+ return ERROR_FAIL ;
676+ }
677+ command = set_field (command , AC_ACCESS_REGISTER_POSTEXEC , 0 );
678+ command = set_field (command , AC_ACCESS_REGISTER_TRANSFER , 1 );
679+ command = set_field (command , AC_ACCESS_REGISTER_WRITE , 0 );
680+
681+ if (number <= GDB_REGNO_XPR31 ) {
682+ command = set_field (command , AC_ACCESS_REGISTER_REGNO ,
683+ 0x1000 + number - GDB_REGNO_XPR0 );
684+ } else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 ) {
685+ if (!r -> abstract_read_fpr_supported )
686+ return ERROR_FAIL ;
687+ command = set_field (command , AC_ACCESS_REGISTER_REGNO ,
688+ 0x1020 + number - GDB_REGNO_FPR0 );
689+ } else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095 ) {
690+ if (!r -> abstract_read_csr_supported )
691+ return ERROR_FAIL ;
692+ command = set_field (command , AC_ACCESS_REGISTER_REGNO ,
693+ number - GDB_REGNO_CSR0 );
694+ } else {
695+ return ERROR_FAIL ;
696+ }
697+
698+ int result = execute_abstract_command (target , command );
699+ if (result != ERROR_OK ) {
700+ if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 ) {
701+ r -> abstract_read_fpr_supported = false;
702+ LOG_INFO ("Disabling abstract command reads from FPRs." );
703+ } else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095 ) {
704+ r -> abstract_read_csr_supported = false;
705+ LOG_INFO ("Disabling abstract command reads from CSRs." );
706+ }
707+ return result ;
708+ }
709+
710+ * value = read_abstract_arg (target , 0 );
711+
712+ return ERROR_OK ;
713+ }
714+
615715/** Actually read registers from the target right now. */
616716static int register_read_direct (struct target * target , uint64_t * value , uint32_t number )
617717{
718+ int result = register_read_abstract (target , value , number ,
719+ riscv_xlen (target ));
720+ if (result == ERROR_OK )
721+ return ERROR_OK ;
722+
618723 struct riscv_program program ;
619724 riscv_program_init (& program , target );
620725 riscv_addr_t output = riscv_program_alloc_d (& program );
@@ -742,6 +847,13 @@ static int init_target(struct command_context *cmd_ctx,
742847 info -> dmi_busy_delay = 0 ;
743848 info -> ac_busy_delay = 0 ;
744849
850+ // Assume all these abstract commands are supported until we learn
851+ // otherwise.
852+ info -> abstract_read_csr_supported = true;
853+ info -> abstract_write_csr_supported = true;
854+ info -> abstract_read_fpr_supported = true;
855+ info -> abstract_write_fpr_supported = true;
856+
745857 target -> reg_cache = calloc (1 , sizeof (* target -> reg_cache ));
746858 target -> reg_cache -> name = "RISC-V Registers" ;
747859 target -> reg_cache -> num_regs = GDB_REGNO_COUNT ;
@@ -1207,9 +1319,9 @@ static int examine(struct target *target)
12071319 riscv_program_insert (& program64 , sd (GDB_REGNO_S0 , GDB_REGNO_S0 , offset ));
12081320 riscv_program_csrrw (& program64 , GDB_REGNO_S0 , GDB_REGNO_S0 , GDB_REGNO_DSCRATCH );
12091321 riscv_program_fence (& program64 );
1210- riscv_program_exec (& program64 , target );
1322+ int result = riscv_program_exec (& program64 , target );
12111323
1212- if (get_field ( dmi_read ( target , DMI_ABSTRACTCS ), DMI_ABSTRACTCS_CMDERR ) == 0 ) {
1324+ if (result == ERROR_OK ) {
12131325 r -> debug_buffer_addr [i ] =
12141326 (dmi_read (target , DMI_PROGBUF0 + (8 + offset ) / 4 ) << 32 )
12151327 + dmi_read (target , DMI_PROGBUF0 + (4 + offset ) / 4 )
@@ -1742,7 +1854,7 @@ struct target_type riscv013_target =
17421854 .arch_state = arch_state ,
17431855};
17441856
1745- /*** 0.13-specific implementations of various RISC-V hepler functions. ***/
1857+ /*** 0.13-specific implementations of various RISC-V helper functions. ***/
17461858static riscv_reg_t riscv013_get_register (struct target * target , int hid , int rid )
17471859{
17481860 LOG_DEBUG ("reading register 0x%08x on hart %d" , rid , hid );
@@ -1914,28 +2026,13 @@ riscv_insn_t riscv013_read_debug_buffer(struct target *target, unsigned index)
19142026
19152027int riscv013_execute_debug_buffer (struct target * target )
19162028{
1917- riscv013_clear_abstract_error (target );
1918-
19192029 uint32_t run_program = 0 ;
19202030 run_program = set_field (run_program , AC_ACCESS_REGISTER_SIZE , 2 );
19212031 run_program = set_field (run_program , AC_ACCESS_REGISTER_POSTEXEC , 1 );
19222032 run_program = set_field (run_program , AC_ACCESS_REGISTER_TRANSFER , 0 );
19232033 run_program = set_field (run_program , AC_ACCESS_REGISTER_REGNO , 0x1000 );
1924- dmi_write (target , DMI_COMMAND , run_program );
19252034
1926- {
1927- uint32_t dmstatus = 0 ;
1928- wait_for_idle (target , & dmstatus );
1929- }
1930-
1931- uint32_t cs = dmi_read (target , DMI_ABSTRACTCS );
1932- if (get_field (cs , DMI_ABSTRACTCS_CMDERR ) != 0 ) {
1933- LOG_ERROR ("unable to execute program: (abstractcs=0x%08x)" , cs );
1934- dmi_read (target , DMI_DMSTATUS );
1935- return ERROR_FAIL ;
1936- }
1937-
1938- return ERROR_OK ;
2035+ return execute_abstract_command (target , run_program );
19392036}
19402037
19412038void riscv013_fill_dmi_write_u64 (struct target * target , char * buf , int a , uint64_t d )
0 commit comments