Skip to content

Commit 09bf86e

Browse files
committed
Keep around cmderr for callers to inspect.
Use this to only change abstract register access behavior when cmderr explicitly says the requested operation is unsupported.
1 parent 856f70f commit 09bf86e

File tree

1 file changed

+39
-26
lines changed

1 file changed

+39
-26
lines changed

src/target/riscv/riscv-013.c

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ typedef struct {
192192
bool abstract_write_csr_supported;
193193
bool abstract_read_fpr_supported;
194194
bool abstract_write_fpr_supported;
195+
196+
// When a function returns some error due to a failure indicated by the
197+
// target in cmderr, the caller can look here to see what that error was.
198+
// (Compare with errno.)
199+
unsigned cmderr;
195200
} riscv013_info_t;
196201

197202
static void decode_dmi(char *text, unsigned address, unsigned data)
@@ -546,6 +551,7 @@ uint32_t abstract_register_size(unsigned width)
546551

547552
static int wait_for_idle(struct target *target, uint32_t *abstractcs)
548553
{
554+
RISCV013_INFO(info);
549555
time_t start = time(NULL);
550556
while (1) {
551557
*abstractcs = dmi_read(target, DMI_ABSTRACTCS);
@@ -555,7 +561,8 @@ static int wait_for_idle(struct target *target, uint32_t *abstractcs)
555561
}
556562

557563
if (time(NULL) - start > WALL_CLOCK_TIMEOUT) {
558-
if (get_field(*abstractcs, DMI_ABSTRACTCS_CMDERR) != CMDERR_NONE) {
564+
info->cmderr = get_field(*abstractcs, DMI_ABSTRACTCS_CMDERR);
565+
if (info->cmderr != CMDERR_NONE) {
559566
const char *errors[8] = {
560567
"none",
561568
"busy",
@@ -567,8 +574,7 @@ static int wait_for_idle(struct target *target, uint32_t *abstractcs)
567574
"other" };
568575

569576
LOG_ERROR("Abstract command ended in error '%s' (abstractcs=0x%x)",
570-
errors[get_field(*abstractcs, DMI_ABSTRACTCS_CMDERR)],
571-
*abstractcs);
577+
errors[info->cmderr], *abstractcs);
572578
}
573579

574580
LOG_ERROR("Timed out waiting for busy to go low. (abstractcs=0x%x)",
@@ -580,6 +586,7 @@ static int wait_for_idle(struct target *target, uint32_t *abstractcs)
580586

581587
static int execute_abstract_command(struct target *target, uint32_t command)
582588
{
589+
RISCV013_INFO(info);
583590
LOG_DEBUG("command=0x%x", command);
584591
dmi_write(target, DMI_COMMAND, command);
585592

@@ -589,12 +596,12 @@ static int execute_abstract_command(struct target *target, uint32_t command)
589596
}
590597

591598
uint32_t cs = dmi_read(target, DMI_ABSTRACTCS);
592-
unsigned cmderr = get_field(cs, DMI_ABSTRACTCS_CMDERR);
593-
if (cmderr != 0) {
599+
info->cmderr = get_field(cs, DMI_ABSTRACTCS_CMDERR);
600+
if (info->cmderr != 0) {
594601
LOG_DEBUG("command 0x%x failed; abstractcs=0x%x", command, cs);
595602
// Clear the error.
596603
dmi_write(target, DMI_ABSTRACTCS, set_field(0, DMI_ABSTRACTCS_CMDERR,
597-
cmderr));
604+
info->cmderr));
598605
return ERROR_FAIL;
599606
}
600607

@@ -675,12 +682,14 @@ static int register_read_abstract(struct target *target, uint64_t *value,
675682

676683
int result = execute_abstract_command(target, command);
677684
if (result != ERROR_OK) {
678-
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
679-
r->abstract_read_fpr_supported = false;
680-
LOG_INFO("Disabling abstract command reads from FPRs.");
681-
} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {
682-
r->abstract_read_csr_supported = false;
683-
LOG_INFO("Disabling abstract command reads from CSRs.");
685+
if (r->cmderr == CMDERR_NOT_SUPPORTED) {
686+
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
687+
r->abstract_read_fpr_supported = false;
688+
LOG_INFO("Disabling abstract command reads from FPRs.");
689+
} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {
690+
r->abstract_read_csr_supported = false;
691+
LOG_INFO("Disabling abstract command reads from CSRs.");
692+
}
684693
}
685694
return result;
686695
}
@@ -693,7 +702,7 @@ static int register_read_abstract(struct target *target, uint64_t *value,
693702
static int register_write_abstract(struct target *target, uint32_t number,
694703
uint64_t value, unsigned size)
695704
{
696-
RISCV013_INFO(r);
705+
RISCV013_INFO(info);
697706

698707
uint32_t command = set_field(0, DMI_COMMAND_CMDTYPE, 0);
699708
switch (size) {
@@ -715,12 +724,12 @@ static int register_write_abstract(struct target *target, uint32_t number,
715724
command = set_field(command, AC_ACCESS_REGISTER_REGNO,
716725
0x1000 + number - GDB_REGNO_XPR0);
717726
} else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
718-
if (!r->abstract_read_fpr_supported)
727+
if (!info->abstract_read_fpr_supported)
719728
return ERROR_FAIL;
720729
command = set_field(command, AC_ACCESS_REGISTER_REGNO,
721730
0x1020 + number - GDB_REGNO_FPR0);
722731
} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {
723-
if (!r->abstract_read_csr_supported)
732+
if (!info->abstract_read_csr_supported)
724733
return ERROR_FAIL;
725734
command = set_field(command, AC_ACCESS_REGISTER_REGNO,
726735
number - GDB_REGNO_CSR0);
@@ -734,12 +743,14 @@ static int register_write_abstract(struct target *target, uint32_t number,
734743

735744
int result = execute_abstract_command(target, command);
736745
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.");
746+
if (info->cmderr == CMDERR_NOT_SUPPORTED) {
747+
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
748+
info->abstract_write_fpr_supported = false;
749+
LOG_INFO("Disabling abstract command writes to FPRs.");
750+
} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {
751+
info->abstract_write_csr_supported = false;
752+
LOG_INFO("Disabling abstract command writes to CSRs.");
753+
}
743754
}
744755
return result;
745756
}
@@ -1415,7 +1426,7 @@ static int examine(struct target *target)
14151426
r->xlen[i], r->debug_buffer_addr[i]);
14161427

14171428
if (riscv_program_gah(&program64, r->debug_buffer_addr[i])) {
1418-
LOG_ERROR("This implementation will not work with hart %d with debug_buffer_addr of 0x%lx\n", i,
1429+
LOG_ERROR("This implementation will not work with hart %d with debug_buffer_addr of 0x%lx\n", i,
14191430
(long)r->debug_buffer_addr[i]);
14201431
abort();
14211432
}
@@ -1479,7 +1490,7 @@ static int assert_reset(struct target *target)
14791490
static int deassert_reset(struct target *target)
14801491
{
14811492
RISCV_INFO(r);
1482-
RISCV013_INFO(info);
1493+
RISCV013_INFO(info);
14831494
select_dmi(target);
14841495

14851496
/*FIXME -- this only works for Single Hart*/
@@ -1637,7 +1648,7 @@ static int read_memory(struct target *target, target_addr_t address,
16371648
size_t reads = 0;
16381649
size_t rereads = reads;
16391650
for (riscv_addr_t i = start; i < count; ++i) {
1640-
size_t index =
1651+
size_t index =
16411652
riscv_batch_add_dmi_read(
16421653
batch,
16431654
riscv013_debug_buffer_register(target, r_data));
@@ -1690,7 +1701,8 @@ static int read_memory(struct target *target, target_addr_t address,
16901701
uint32_t abstractcs = dmi_read(target, DMI_ABSTRACTCS);
16911702
while (get_field(abstractcs, DMI_ABSTRACTCS_BUSY))
16921703
abstractcs = dmi_read(target, DMI_ABSTRACTCS);
1693-
switch (get_field(abstractcs, DMI_ABSTRACTCS_CMDERR)) {
1704+
info->cmderr = get_field(abstractcs, DMI_ABSTRACTCS_CMDERR);
1705+
switch (info->cmderr) {
16941706
case CMDERR_NONE:
16951707
LOG_DEBUG("successful (partial?) memory write");
16961708
break;
@@ -1874,7 +1886,8 @@ static int write_memory(struct target *target, target_addr_t address,
18741886
uint32_t abstractcs = dmi_read(target, DMI_ABSTRACTCS);
18751887
while (get_field(abstractcs, DMI_ABSTRACTCS_BUSY))
18761888
abstractcs = dmi_read(target, DMI_ABSTRACTCS);
1877-
switch (get_field(abstractcs, DMI_ABSTRACTCS_CMDERR)) {
1889+
info->cmderr = get_field(abstractcs, DMI_ABSTRACTCS_CMDERR);
1890+
switch (info->cmderr) {
18781891
case CMDERR_NONE:
18791892
LOG_DEBUG("successful (partial?) memory write");
18801893
break;

0 commit comments

Comments
 (0)