aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2020-01-13 15:23:59 -0800
committerGitHub <noreply@github.com>2020-01-13 15:23:59 -0800
commit2940a9a604003aabbe2db727f0877f029a36db7c (patch)
tree8389648eeddb694b3f83d41a6260dd08352c3f14 /riscv
parentd15d781737d7e9d6d70bb7987e2f38c5079dd9d5 (diff)
downloadspike-2940a9a604003aabbe2db727f0877f029a36db7c.zip
spike-2940a9a604003aabbe2db727f0877f029a36db7c.tar.gz
spike-2940a9a604003aabbe2db727f0877f029a36db7c.tar.bz2
Make minimum RTI behavior more realistic. (#375)
* Make minimum RTI behavior more realistic. Now DMI will return busy when you'd expect it to, instead of a few scans later. This only matters when testing OpenOCD. There is no other reason to use --dmi-rti. * dmireset only resets busy.
Diffstat (limited to 'riscv')
-rw-r--r--riscv/jtag_dtm.cc67
1 files changed, 35 insertions, 32 deletions
diff --git a/riscv/jtag_dtm.cc b/riscv/jtag_dtm.cc
index 576e495..1baeca8 100644
--- a/riscv/jtag_dtm.cc
+++ b/riscv/jtag_dtm.cc
@@ -20,9 +20,10 @@ enum {
#define DTMCONTROL_VERSION 0xf
#define DTMCONTROL_ABITS (0x3f << 4)
-#define DTMCONTROL_DBUSSTAT (3<<10)
+#define DTMCONTROL_DMISTAT (3<<10)
#define DTMCONTROL_IDLE (7<<12)
-#define DTMCONTROL_DBUSRESET (1<<16)
+#define DTMCONTROL_DMIRESET (1<<16)
+#define DTMCONTROL_DMIHARDRESET (1<<17)
#define DMI_OP 3
#define DMI_DATA (0xffffffffLL<<2)
@@ -144,7 +145,12 @@ void jtag_dtm_t::capture_dr()
dr_length = 32;
break;
case IR_DBUS:
- dr = dmi;
+ if (rti_remaining > 0 || busy_stuck) {
+ dr = DMI_OP_STATUS_BUSY;
+ busy_stuck = true;
+ } else {
+ dr = dmi;
+ }
dr_length = abits + 34;
break;
default:
@@ -160,39 +166,36 @@ void jtag_dtm_t::update_dr()
D(fprintf(stderr, "Update DR; IR=0x%x, DR=0x%lx (%d bits)\n",
ir, dr, dr_length));
if (ir == IR_DTMCONTROL) {
- if (dr & DTMCONTROL_DBUSRESET)
+ if (dr & DTMCONTROL_DMIRESET)
+ busy_stuck = false;
+ if (dr & DTMCONTROL_DMIHARDRESET)
reset();
- } else if (ir == IR_DBUS) {
- if (rti_remaining > 0 || busy_stuck) {
- dmi = DMI_OP_STATUS_BUSY;
- busy_stuck = true;
- } else {
- unsigned op = get_field(dr, DMI_OP);
- uint32_t data = get_field(dr, DMI_DATA);
- unsigned address = get_field(dr, DMI_ADDRESS);
-
- dmi = dr;
-
- bool success = true;
- if (op == DMI_OP_READ) {
- uint32_t value;
- if (dm->dmi_read(address, &value)) {
- dmi = set_field(dmi, DMI_DATA, value);
- } else {
- success = false;
- }
- } else if (op == DMI_OP_WRITE) {
- success = dm->dmi_write(address, data);
- }
-
- if (success) {
- dmi = set_field(dmi, DMI_OP, DMI_OP_STATUS_SUCCESS);
+ } else if (ir == IR_DBUS && !busy_stuck) {
+ unsigned op = get_field(dr, DMI_OP);
+ uint32_t data = get_field(dr, DMI_DATA);
+ unsigned address = get_field(dr, DMI_ADDRESS);
+
+ dmi = dr;
+
+ bool success = true;
+ if (op == DMI_OP_READ) {
+ uint32_t value;
+ if (dm->dmi_read(address, &value)) {
+ dmi = set_field(dmi, DMI_DATA, value);
} else {
- dmi = set_field(dmi, DMI_OP, DMI_OP_STATUS_FAILED);
+ success = false;
}
- D(fprintf(stderr, "dmi=0x%lx\n", dmi));
+ } else if (op == DMI_OP_WRITE) {
+ success = dm->dmi_write(address, data);
+ }
- rti_remaining = required_rti_cycles;
+ if (success) {
+ dmi = set_field(dmi, DMI_OP, DMI_OP_STATUS_SUCCESS);
+ } else {
+ dmi = set_field(dmi, DMI_OP, DMI_OP_STATUS_FAILED);
}
+ D(fprintf(stderr, "dmi=0x%lx\n", dmi));
+
+ rti_remaining = required_rti_cycles;
}
}