aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2017-02-06 19:17:23 -0800
committerTim Newsome <tim@sifive.com>2017-02-06 19:17:23 -0800
commit4695be7cea868b34082787d5728c35577d0c05d1 (patch)
treeb9d730b3955e924e0b198ccc6c7d5014d06817f9
parent9be157042081e894e6c12dc96449cf865469bcfe (diff)
downloadspike-4695be7cea868b34082787d5728c35577d0c05d1.zip
spike-4695be7cea868b34082787d5728c35577d0c05d1.tar.gz
spike-4695be7cea868b34082787d5728c35577d0c05d1.tar.bz2
Refactor remote bitbang code.
-rw-r--r--riscv/jtag_dtm.cc81
-rw-r--r--riscv/jtag_dtm.h81
-rw-r--r--riscv/remote_bitbang.cc34
-rw-r--r--riscv/remote_bitbang.h138
-rw-r--r--riscv/riscv.mk.in2
-rw-r--r--spike_main/spike.cc3
6 files changed, 192 insertions, 147 deletions
diff --git a/riscv/jtag_dtm.cc b/riscv/jtag_dtm.cc
new file mode 100644
index 0000000..c099e33
--- /dev/null
+++ b/riscv/jtag_dtm.cc
@@ -0,0 +1,81 @@
+#include <stdio.h>
+
+#include "jtag_dtm.h"
+
+#if 1
+# define D(x) x
+#else
+# define D(x)
+#endif
+
+void jtag_dtm_t::set_pins(bool tck, bool tms, bool tdi) {
+ if (!_tck && tck) {
+ // Positive clock edge.
+
+ switch (state) {
+ case SHIFT_DR:
+ dr >>= 1;
+ dr |= (uint64_t) _tdi << (dr_length-1);
+ break;
+ case SHIFT_IR:
+ ir >>= 1;
+ ir |= _tdi << (ir_length-1);
+ break;
+ default:
+ break;
+ }
+ state = next[state][_tms];
+ switch (state) {
+ case TEST_LOGIC_RESET:
+ ir = idcode_ir;
+ break;
+ case CAPTURE_DR:
+ capture_dr();
+ break;
+ case SHIFT_DR:
+ _tdo = dr & 1;
+ break;
+ case UPDATE_DR:
+ update_dr();
+ break;
+ case CAPTURE_IR:
+ break;
+ case SHIFT_IR:
+ _tdo = ir & 1;
+ break;
+ case UPDATE_IR:
+ break;
+ default:
+ break;
+ }
+ }
+
+ _tck = tck;
+ _tms = tms;
+ _tdi = tdi;
+
+ D(fprintf(stderr, "state=%2d tck=%d tms=%d tdi=%d tdo=%d ir=0x%x dr=0x%lx\n",
+ state, _tck, _tms, _tdi, _tdo, ir, dr));
+}
+
+void jtag_dtm_t::capture_dr()
+{
+ switch (ir) {
+ case idcode_ir:
+ dr = 0xdeadbeef;
+ dr_length = 32;
+ break;
+ case dtmcontrol_ir:
+ dr = dtmcontrol;
+ dr_length = 32;
+ default:
+ D(fprintf(stderr, "Unsupported IR: 0x%x\n", ir));
+ break;
+ }
+ D(fprintf(stderr, "Capture DR; IR=0x%x, DR=0x%lx (%d bits)\n",
+ ir, dr, dr_length));
+}
+
+void jtag_dtm_t::update_dr()
+{
+}
diff --git a/riscv/jtag_dtm.h b/riscv/jtag_dtm.h
new file mode 100644
index 0000000..e425c8e
--- /dev/null
+++ b/riscv/jtag_dtm.h
@@ -0,0 +1,81 @@
+#ifndef JTAG_DTM_H
+#define JTAG_DTM_H
+
+#include <stdint.h>
+
+typedef enum {
+ TEST_LOGIC_RESET,
+ RUN_TEST_IDLE,
+ SELECT_DR_SCAN,
+ CAPTURE_DR,
+ SHIFT_DR,
+ EXIT1_DR,
+ PAUSE_DR,
+ EXIT2_DR,
+ UPDATE_DR,
+ SELECT_IR_SCAN,
+ CAPTURE_IR,
+ SHIFT_IR,
+ EXIT1_IR,
+ PAUSE_IR,
+ EXIT2_IR,
+ UPDATE_IR
+} jtag_state_t;
+
+class jtag_dtm_t
+{
+ static const unsigned idcode_ir = 1;
+ static const unsigned idcode_dr = 0xdeadbeef;
+ static const unsigned dtmcontrol_ir = 0x10;
+
+ public:
+ jtag_dtm_t() :
+ dtmcontrol(
+ (6 << 4) | // abits
+ 1 // version
+ ),
+ state(TEST_LOGIC_RESET) {}
+
+ void reset() {
+ state = TEST_LOGIC_RESET;
+ }
+
+ void set_pins(bool tck, bool tms, bool tdi);
+
+ bool tdo() const { return _tdo; }
+
+ private:
+ bool _tck, _tms, _tdi, _tdo;
+ uint32_t ir;
+ const unsigned ir_length = 5;
+ uint64_t dr;
+ unsigned dr_length;
+
+ uint32_t dtmcontrol;
+
+ jtag_state_t state;
+
+ void capture_dr();
+ void update_dr();
+
+ const jtag_state_t next[16][2] = {
+ /* TEST_LOGIC_RESET */ { RUN_TEST_IDLE, TEST_LOGIC_RESET },
+ /* RUN_TEST_IDLE */ { RUN_TEST_IDLE, SELECT_DR_SCAN },
+ /* SELECT_DR_SCAN */ { CAPTURE_DR, SELECT_IR_SCAN },
+ /* CAPTURE_DR */ { SHIFT_DR, EXIT1_DR },
+ /* SHIFT_DR */ { SHIFT_DR, EXIT1_DR },
+ /* EXIT1_DR */ { PAUSE_DR, UPDATE_DR },
+ /* PAUSE_DR */ { PAUSE_DR, EXIT2_DR },
+ /* EXIT2_DR */ { SHIFT_DR, UPDATE_DR },
+ /* UPDATE_DR */ { RUN_TEST_IDLE, SELECT_DR_SCAN },
+ /* SELECT_IR_SCAN */ { CAPTURE_IR, TEST_LOGIC_RESET },
+ /* CAPTURE_IR */ { SHIFT_IR, EXIT1_IR },
+ /* SHIFT_IR */ { SHIFT_IR, EXIT1_IR },
+ /* EXIT1_IR */ { PAUSE_IR, UPDATE_IR },
+ /* PAUSE_IR */ { PAUSE_IR, EXIT2_IR },
+ /* EXIT2_IR */ { SHIFT_IR, UPDATE_IR },
+ /* UPDATE_IR */ { RUN_TEST_IDLE, SELECT_DR_SCAN }
+ };
+};
+
+#endif
diff --git a/riscv/remote_bitbang.cc b/riscv/remote_bitbang.cc
index 7f22cd3..acfd216 100644
--- a/riscv/remote_bitbang.cc
+++ b/riscv/remote_bitbang.cc
@@ -11,6 +11,12 @@
#include "remote_bitbang.h"
+#if 1
+# define D(x) x
+#else
+# define D(x)
+#endif
+
/////////// Circular buffer
template <typename T>
@@ -87,7 +93,8 @@ void circular_buffer_t<T>::append(T value)
/////////// remote_bitbang_t
-remote_bitbang_t::remote_bitbang_t(uint16_t port, sim_t *sim) :
+remote_bitbang_t::remote_bitbang_t(uint16_t port, jtag_dtm_t *tap) :
+ tap(tap),
socket_fd(0),
client_fd(0),
recv_buf(64 * 1024),
@@ -212,22 +219,27 @@ void remote_bitbang_t::tick()
void remote_bitbang_t::process_input()
{
+ // TODO: get rid of the circular buffers, and just read/write here with
+ // simple local buffers.
+ // Each message is a single character, so there's never any need to keep a
+ // partially transmitted message around.
+
for (unsigned i = 0; i < recv_buf.size(); i++) {
uint8_t command = recv_buf[i];
switch (command) {
case 'B': fprintf(stderr, "*BLINK*\n"); break;
case 'b': fprintf(stderr, "_______\n"); break;
- case 'r': tap.reset(); break;
- case '0': tap.set_pins(0, 0, 0); break;
- case '1': tap.set_pins(0, 0, 1); break;
- case '2': tap.set_pins(0, 1, 0); break;
- case '3': tap.set_pins(0, 1, 1); break;
- case '4': tap.set_pins(1, 0, 0); break;
- case '5': tap.set_pins(1, 0, 1); break;
- case '6': tap.set_pins(1, 1, 0); break;
- case '7': tap.set_pins(1, 1, 1); break;
- case 'R': send_buf.append(tap.tdo() ? '1' : '0'); break;
+ case 'r': tap->reset(); break;
+ case '0': tap->set_pins(0, 0, 0); break;
+ case '1': tap->set_pins(0, 0, 1); break;
+ case '2': tap->set_pins(0, 1, 0); break;
+ case '3': tap->set_pins(0, 1, 1); break;
+ case '4': tap->set_pins(1, 0, 0); break;
+ case '5': tap->set_pins(1, 0, 1); break;
+ case '6': tap->set_pins(1, 1, 0); break;
+ case '7': tap->set_pins(1, 1, 1); break;
+ case 'R': send_buf.append(tap->tdo() ? '1' : '0'); break;
default:
fprintf(stderr, "remote_bitbang got unsupported command '%c'\n", command);
}
diff --git a/riscv/remote_bitbang.h b/riscv/remote_bitbang.h
index 5f2a3ea..c0aa7e0 100644
--- a/riscv/remote_bitbang.h
+++ b/riscv/remote_bitbang.h
@@ -3,14 +3,7 @@
#include <stdint.h>
-#define DEBUG
-#ifdef DEBUG
-# define D(x) x
-#else
-# define D(x)
-#endif // DEBUG
-
-class sim_t;
+#include "jtag_dtm.h"
template <typename T>
class circular_buffer_t
@@ -51,143 +44,18 @@ public:
void append(T value);
};
-typedef enum {
- TEST_LOGIC_RESET,
- RUN_TEST_IDLE,
- SELECT_DR_SCAN,
- CAPTURE_DR,
- SHIFT_DR,
- EXIT1_DR,
- PAUSE_DR,
- EXIT2_DR,
- UPDATE_DR,
- SELECT_IR_SCAN,
- CAPTURE_IR,
- SHIFT_IR,
- EXIT1_IR,
- PAUSE_IR,
- EXIT2_IR,
- UPDATE_IR
-} jtag_state_t;
-
-class jtag_tap_t
-{
- static const unsigned idcode_ir = 1;
- static const unsigned idcode_dr = 0xdeadbeef;
- static const unsigned dtmcontrol_ir = 0x10;
-
- public:
- jtag_tap_t() :
- state(TEST_LOGIC_RESET) {}
-
- void reset() {
- state = TEST_LOGIC_RESET;
- }
-
- void set_pins(bool tck, bool tms, bool tdi) {
- if (!_tck && tck) {
- // Positive clock edge.
-
- switch (state) {
- case SHIFT_DR:
- dr >>= 1;
- dr |= (uint64_t) _tdi << (dr_length-1);
- break;
- case SHIFT_IR:
- ir >>= 1;
- ir |= _tdi << (ir_length-1);
- break;
- default:
- break;
- }
- state = next[state][_tms];
- switch (state) {
- case TEST_LOGIC_RESET:
- ir = idcode_ir;
- break;
- case CAPTURE_DR:
- switch (ir) {
- case idcode_ir:
- dr = 0xdeadbeef;
- dr_length = 32;
- break;
- case dtmcontrol_ir:
- dr = dtmcontrol;
- dr_length = 32;
- default:
- D(fprintf(stderr, "Unsupported IR: 0x%x\n", ir));
- break;
- }
- break;
- case SHIFT_DR:
- _tdo = dr & 1;
- break;
- case UPDATE_DR:
- break;
- case CAPTURE_IR:
- break;
- case SHIFT_IR:
- _tdo = ir & 1;
- break;
- case UPDATE_IR:
- break;
- default:
- break;
- }
- }
-
- _tck = tck;
- _tms = tms;
- _tdi = tdi;
-
- D(fprintf(stderr, "state=%2d tck=%d tms=%d tdi=%d tdo=%d ir=0x%x dr=0x%lx\n",
- state, _tck, _tms, _tdi, _tdo, ir, dr));
- }
-
- bool tdo() const { return _tdo; }
-
- private:
- bool _tck, _tms, _tdi, _tdo;
- uint32_t ir;
- const unsigned ir_length = 5;
- uint64_t dr;
- unsigned dr_length;
-
- uint32_t dtmcontrol = 1;
-
- jtag_state_t state;
- const jtag_state_t next[16][2] = {
- /* TEST_LOGIC_RESET */ { RUN_TEST_IDLE, TEST_LOGIC_RESET },
- /* RUN_TEST_IDLE */ { RUN_TEST_IDLE, SELECT_DR_SCAN },
- /* SELECT_DR_SCAN */ { CAPTURE_DR, SELECT_IR_SCAN },
- /* CAPTURE_DR */ { SHIFT_DR, EXIT1_DR },
- /* SHIFT_DR */ { SHIFT_DR, EXIT1_DR },
- /* EXIT1_DR */ { PAUSE_DR, UPDATE_DR },
- /* PAUSE_DR */ { PAUSE_DR, EXIT2_DR },
- /* EXIT2_DR */ { SHIFT_DR, UPDATE_DR },
- /* UPDATE_DR */ { RUN_TEST_IDLE, SELECT_DR_SCAN },
- /* SELECT_IR_SCAN */ { CAPTURE_IR, TEST_LOGIC_RESET },
- /* CAPTURE_IR */ { SHIFT_IR, EXIT1_IR },
- /* SHIFT_IR */ { SHIFT_IR, EXIT1_IR },
- /* EXIT1_IR */ { PAUSE_IR, UPDATE_IR },
- /* PAUSE_IR */ { PAUSE_IR, EXIT2_IR },
- /* EXIT2_IR */ { SHIFT_IR, UPDATE_IR },
- /* UPDATE_IR */ { RUN_TEST_IDLE, SELECT_DR_SCAN }
- };
-};
-
class remote_bitbang_t
{
public:
// Create a new server, listening for connections from localhost on the given
// port.
- remote_bitbang_t(uint16_t port, sim_t *sim);
+ remote_bitbang_t(uint16_t port, jtag_dtm_t *tap);
// Do a bit of work.
void tick();
private:
- jtag_tap_t tap;
+ jtag_dtm_t *tap;
int socket_fd;
int client_fd;
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index 695803b..6f12b84 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -25,6 +25,7 @@ riscv_hdrs = \
mulhi.h \
debug_module.h \
remote_bitbang.h \
+ jtag_dtm.h \
riscv_precompiled_hdrs = \
insn_template.h \
@@ -47,6 +48,7 @@ riscv_srcs = \
rtc.cc \
debug_module.cc \
remote_bitbang.cc \
+ jtag_dtm.cc \
$(riscv_gen_srcs) \
riscv_test_srcs =
diff --git a/spike_main/spike.cc b/spike_main/spike.cc
index 576c01f..844d8e8 100644
--- a/spike_main/spike.cc
+++ b/spike_main/spike.cc
@@ -79,9 +79,10 @@ int main(int argc, char** argv)
auto argv1 = parser.parse(argv);
std::vector<std::string> htif_args(argv1, (const char*const*)argv + argc);
sim_t s(isa, nprocs, mem_mb, halted, htif_args);
+ std::unique_ptr<jtag_dtm_t> jtag_dtm(new jtag_dtm_t());
std::unique_ptr<remote_bitbang_t> remote_bitbang;
if (rbb_port) {
- remote_bitbang = std::unique_ptr<remote_bitbang_t>(new remote_bitbang_t(rbb_port, &s));
+ remote_bitbang.reset(new remote_bitbang_t(rbb_port, &(*jtag_dtm)));
s.set_remote_bitbang(&(*remote_bitbang));
}