diff options
author | Tim Newsome <tim@sifive.com> | 2020-01-13 15:23:59 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-13 15:23:59 -0800 |
commit | 2940a9a604003aabbe2db727f0877f029a36db7c (patch) | |
tree | 8389648eeddb694b3f83d41a6260dd08352c3f14 | |
parent | d15d781737d7e9d6d70bb7987e2f38c5079dd9d5 (diff) | |
download | riscv-isa-sim-2940a9a604003aabbe2db727f0877f029a36db7c.zip riscv-isa-sim-2940a9a604003aabbe2db727f0877f029a36db7c.tar.gz riscv-isa-sim-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.
-rw-r--r-- | riscv/jtag_dtm.cc | 67 |
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; } } |