diff options
author | Tim Newsome <tim@sifive.com> | 2016-06-09 09:49:11 -0700 |
---|---|---|
committer | Tim Newsome <tim@sifive.com> | 2016-09-23 14:16:23 -0700 |
commit | 04cfc35147296385a50fbcacd47d7fed6b120afe (patch) | |
tree | ff8fed6a654438fd3c3a4502ea1a6694b75e0f51 /src | |
parent | dce4a992a3ffa17a0b268737acdacc31e8bebf58 (diff) | |
download | riscv-openocd-04cfc35147296385a50fbcacd47d7fed6b120afe.zip riscv-openocd-04cfc35147296385a50fbcacd47d7fed6b120afe.tar.gz riscv-openocd-04cfc35147296385a50fbcacd47d7fed6b120afe.tar.bz2 |
Use the dram cache to save some scans.
Diffstat (limited to 'src')
-rw-r--r-- | src/jtag/core.c | 53 | ||||
-rw-r--r-- | src/target/riscv/riscv.c | 27 |
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); |