aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2016-06-09 09:49:11 -0700
committerTim Newsome <tim@sifive.com>2016-09-23 14:16:23 -0700
commit04cfc35147296385a50fbcacd47d7fed6b120afe (patch)
treeff8fed6a654438fd3c3a4502ea1a6694b75e0f51
parentdce4a992a3ffa17a0b268737acdacc31e8bebf58 (diff)
downloadriscv-openocd-04cfc35147296385a50fbcacd47d7fed6b120afe.zip
riscv-openocd-04cfc35147296385a50fbcacd47d7fed6b120afe.tar.gz
riscv-openocd-04cfc35147296385a50fbcacd47d7fed6b120afe.tar.bz2
Use the dram cache to save some scans.
-rw-r--r--src/jtag/core.c53
-rw-r--r--src/target/riscv/riscv.c27
2 files changed, 49 insertions, 31 deletions
diff --git a/src/jtag/core.c b/src/jtag/core.c
index 70ac3aa..2a07129 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -838,10 +838,13 @@ int default_interface_jtag_execute_queue(void)
int result = jtag->execute_queue();
+ // TODO: I like these better than some of the other JTAG debug statements,
+ // but having both is silly.
struct jtag_command *cmd = jtag_command_queue;
while (debug_level >= LOG_LVL_DEBUG && cmd) {
switch (cmd->type) {
case JTAG_SCAN:
+#if 0
LOG_DEBUG("JTAG %s SCAN to %s",
cmd->cmd.scan->ir_scan ? "IR" : "DR",
tap_state_name(cmd->cmd.scan->end_state));
@@ -868,37 +871,44 @@ int default_interface_jtag_execute_queue(void)
free(str);
}
}
- uint8_t *buf = NULL;
- int scan_bits = jtag_build_buffer(cmd->cmd.scan, &buf);
- char *str_out = buf_to_str(buf, scan_bits, 16);
- free(buf);
- LOG_DEBUG("vvv jtag_scan(%d, %d, %d'h%s, %d); // %s",
- cmd->cmd.scan->ir_scan,
- scan_bits,
- scan_bits, str_out,
- cmd->cmd.scan->end_state, tap_state_name(cmd->cmd.scan->end_state));
- free(str_out);
-
- struct scan_field *last_field = cmd->cmd.scan->fields + cmd->cmd.scan->num_fields - 1;
- if (last_field->in_value) {
- char *str_in = buf_to_str(last_field->in_value, last_field->num_bits, 16);
- LOG_DEBUG("vvv jtag_check_tdo(%d, %d'h%s);",
- last_field->num_bits,
- last_field->num_bits, str_in);
- free(str_in);
+#endif
+ {
+ uint8_t *buf = NULL;
+ int scan_bits = jtag_build_buffer(cmd->cmd.scan, &buf);
+ char *str_out = buf_to_str(buf, scan_bits, 16);
+ free(buf);
+ LOG_DEBUG("vvv jtag_scan(%d, %d, %d'h%s, %d); // %s",
+ cmd->cmd.scan->ir_scan,
+ scan_bits,
+ scan_bits, str_out,
+ cmd->cmd.scan->end_state, tap_state_name(cmd->cmd.scan->end_state));
+ free(str_out);
+
+ struct scan_field *last_field = cmd->cmd.scan->fields + cmd->cmd.scan->num_fields - 1;
+ if (last_field->in_value) {
+ char *str_in = buf_to_str(last_field->in_value, last_field->num_bits, 16);
+ LOG_DEBUG("vvv jtag_check_tdo(%d, %d'h%s);",
+ last_field->num_bits,
+ last_field->num_bits, str_in);
+ free(str_in);
+ }
}
break;
case JTAG_TLR_RESET:
+#if 0
LOG_DEBUG("JTAG TLR RESET to %s",
tap_state_name(cmd->cmd.statemove->end_state));
+#endif
LOG_DEBUG("vvv jtag_tlr_reset(%d); // %s",
cmd->cmd.statemove->end_state,
tap_state_name(cmd->cmd.statemove->end_state));
break;
case JTAG_RUNTEST:
+#if 0
LOG_DEBUG("JTAG RUNTEST %d cycles to %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(cmd->cmd.runtest->end_state));
+#endif
LOG_DEBUG("vvv jtag_runtest(%d, %d); // %s",
cmd->cmd.runtest->num_cycles,
cmd->cmd.runtest->end_state,
@@ -906,35 +916,32 @@ int default_interface_jtag_execute_queue(void)
break;
case JTAG_RESET:
{
+#if 0
const char *reset_str[3] = {
"leave", "deassert", "assert"
};
LOG_DEBUG("JTAG RESET %s TRST, %s SRST",
reset_str[cmd->cmd.reset->trst + 1],
reset_str[cmd->cmd.reset->srst + 1]);
+#endif
LOG_DEBUG("vvv jtag_reset(%d, %d);",
cmd->cmd.reset->trst, cmd->cmd.reset->srst);
}
break;
case JTAG_PATHMOVE:
LOG_DEBUG("JTAG PATHMOVE (TODO)");
- abort();
break;
case JTAG_SLEEP:
LOG_DEBUG("JTAG SLEEP (TODO)");
- abort();
break;
case JTAG_STABLECLOCKS:
LOG_DEBUG("JTAG STABLECLOCKS (TODO)");
- abort();
break;
case JTAG_TMS:
LOG_DEBUG("JTAG STABLECLOCKS (TODO)");
- abort();
break;
default:
LOG_ERROR("Unknown JTAG command: %d", cmd->type);
- abort();
break;
}
cmd = cmd->next;
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 6312108..ed71f9e 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -230,6 +230,7 @@ static dbus_status_t dbus_scan(struct target *target, uint64_t *data_in,
static const char *op_string[] = {"nop", "r", "w", "cw"};
static const char *status_string[] = {"+", "nw", "F", "b"};
+ /*
LOG_DEBUG("vvv $display(\"hardware: dbus scan %db %s %01x:%08x @%02x -> %s %01x:%08x @%02x\");",
field.num_bits,
op_string[buf_get_u32(out, 0, 2)],
@@ -238,7 +239,7 @@ static dbus_status_t dbus_scan(struct target *target, uint64_t *data_in,
status_string[buf_get_u32(in, 0, 2)],
buf_get_u32(in, 34, 2), buf_get_u32(in, 2, 32),
buf_get_u32(in, 36, info->addrbits));
- /*
+ */
LOG_DEBUG("dbus scan %db %s %01x:%08x @%02x -> %s %01x:%08x @%02x",
field.num_bits,
op_string[buf_get_u32(out, 0, 2)],
@@ -247,7 +248,6 @@ static dbus_status_t dbus_scan(struct target *target, uint64_t *data_in,
status_string[buf_get_u32(in, 0, 2)],
buf_get_u32(in, 34, 2), buf_get_u32(in, 2, 32),
buf_get_u32(in, 36, info->addrbits));
- */
//debug_scan(target);
@@ -313,21 +313,31 @@ static uint32_t dtminfo_read(struct target *target)
static uint32_t dram_read32(struct target *target, unsigned int index)
{
+ riscv_info_t *info = (riscv_info_t *) target->arch_info;
// TODO: check cache to see if this even needs doing.
uint16_t address = dram_address(index);
- return dbus_read(target, address, address);
+ uint32_t value = dbus_read(target, address, address);
+ info->dram_valid |= (1<<index);
+ info->dram[index] = value;
+ return value;
}
static void dram_write32(struct target *target, unsigned int index, uint32_t value,
bool set_interrupt)
{
riscv_info_t *info = (riscv_info_t *) target->arch_info;
- // TODO: check cache to see if this even needs doing.
+
+ if (info->dram_valid & (1<<index) && info->dram[index] == value) {
+ LOG_DEBUG("DRAM cache hit: 0x%x @%d", value, index);
+ return;
+ }
+
uint64_t dbus_value = DMCONTROL_HALTNOT | value;
if (set_interrupt)
dbus_value |= DMCONTROL_INTERRUPT;
dbus_write(target, dram_address(index), dbus_value);
info->dram_valid |= (1<<index);
+ info->dram[index] = value;
}
#if 1
@@ -479,9 +489,13 @@ static void update_reg_list(struct target *target)
static int register_get(struct reg *reg)
{
struct target *target = (struct target *) reg->arch_info;
+ riscv_info_t *info = (riscv_info_t *) target->arch_info;
// TODO: S0 and S1
- if (reg->number <= REG_XPR31) {
+ if (reg->number == ZERO) {
+ buf_set_u64(reg->value, 0, info->xlen, 0);
+ return ERROR_OK;
+ } else if (reg->number <= REG_XPR31) {
dram_write32(target, 0, sw(reg->number - REG_XPR0, ZERO, DEBUG_RAM_START), false);
dram_write_jump(target, 1, true);
} else if (reg->number == REG_PC) {
@@ -1128,9 +1142,6 @@ static int riscv_write_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
- // TODO: save/restore T0
-
- // Set up the address.
// Write program.
dram_write32(target, 0, lw(S1, ZERO, DEBUG_RAM_START + 16), false);