Browse Source

OpenOCD can now scan out the hacked IDCODE.

pull/94/head
Tim Newsome 10 years ago
parent
commit
f6a7fe2c4e
  1. 39
      riscv/remote_bitbang.cc
  2. 116
      riscv/remote_bitbang.h

39
riscv/remote_bitbang.cc

@ -11,13 +11,6 @@
#include "remote_bitbang.h"
#define DEBUG
#ifdef DEBUG
# define D(x) x
#else
# define D(x)
#endif // DEBUG
/////////// Circular buffer
template <typename T>
@ -86,6 +79,12 @@ void circular_buffer_t<T>::append(const T *src, unsigned int count)
}
}
template <typename T>
void circular_buffer_t<T>::append(T value)
{
append(&value, 1);
}
/////////// remote_bitbang_t
remote_bitbang_t::remote_bitbang_t(uint16_t port, sim_t *sim) :
@ -204,8 +203,34 @@ void remote_bitbang_t::tick()
{
if (client_fd > 0) {
this->read();
process_input();
this->write();
} else {
this->accept();
}
}
void remote_bitbang_t::process_input()
{
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;
default:
fprintf(stderr, "remote_bitbang got unsupported command '%c'\n", command);
}
}
recv_buf.reset();
}

116
riscv/remote_bitbang.h

@ -3,6 +3,13 @@
#include <stdint.h>
#define DEBUG
#ifdef DEBUG
# define D(x) x
#else
# define D(x)
#endif // DEBUG
class sim_t;
template <typename T>
@ -41,6 +48,110 @@ public:
T operator[](unsigned int i) const { return data[(start + i) % capacity]; }
void append(const T *src, unsigned int count);
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
{
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.
D(fprintf(stderr, "Next state: %d\n", state));
state = next[state][_tms];
switch (state) {
case TEST_LOGIC_RESET:
ir = 1;
break;
case CAPTURE_DR:
dr = 0xdeadbeef;
dr_length = 32;
break;
case SHIFT_DR:
_tdo = dr & 1;
dr >>= 1;
dr |= (uint64_t) _tdi << (dr_length-1);
break;
case UPDATE_DR:
break;
case CAPTURE_IR:
break;
case SHIFT_IR:
_tdo = ir & 1;
ir >>= 1;
ir = ir | (_tdi << (ir_length-1));
break;
case UPDATE_IR:
break;
default:
break;
}
}
_tck = tck;
_tms = tms;
_tdi = tdi;
D(fprintf(stderr, "tck=%d tms=%d tdi=%d tdo=%d ir=0x%x dr=0x%lx\n",
_tck, _tms, _tdi, _tdo, ir, dr));
}
bool tdo() const { return _tdo; }
private:
bool _tck, _tms, _tdi, _tdo;
uint32_t ir;
unsigned ir_length;
uint64_t dr;
unsigned dr_length;
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
@ -54,6 +165,8 @@ public:
void tick();
private:
jtag_tap_t tap;
int socket_fd;
int client_fd;
circular_buffer_t<uint8_t> recv_buf;
@ -65,6 +178,9 @@ private:
void read();
// Write as much of send_buf as possible.
void write();
// Process the input buffer.
void process_input();
};
#endif

Loading…
Cancel
Save