diff options
-rw-r--r-- | src/jtag/drivers/mpsse.c | 7 | ||||
-rw-r--r-- | src/rtos/riscv_debug.c | 8 | ||||
-rw-r--r-- | src/server/gdb_server.c | 4 | ||||
-rw-r--r-- | src/target/riscv/batch.c | 14 | ||||
-rw-r--r-- | src/target/riscv/riscv-013.c | 63 | ||||
-rw-r--r-- | src/target/riscv/riscv.c | 50 | ||||
-rw-r--r-- | src/target/startup.tcl | 1 |
7 files changed, 102 insertions, 45 deletions
diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c index 06d008b..6c70be6 100644 --- a/src/jtag/drivers/mpsse.c +++ b/src/jtag/drivers/mpsse.c @@ -22,6 +22,7 @@ #include "mpsse.h" #include "helper/log.h" +#include "helper/time_support.h" #include <libusb.h> /* Compatibility define for older libusb-1.0 */ @@ -892,6 +893,7 @@ int mpsse_flush(struct mpsse_ctx *ctx) } /* Polling loop, more or less taken from libftdi */ + int64_t start = timeval_ms(); while (!write_result.done || !read_result.done) { struct timeval timeout_usb; @@ -914,6 +916,11 @@ int mpsse_flush(struct mpsse_ctx *ctx) break; } } + + if (timeval_ms() - start > 2000) { + LOG_ERROR("Timed out handling USB events in mpsse_flush()."); + break; + } } error_check: diff --git a/src/rtos/riscv_debug.c b/src/rtos/riscv_debug.c index 6703008..dade798 100644 --- a/src/rtos/riscv_debug.c +++ b/src/rtos/riscv_debug.c @@ -124,7 +124,12 @@ static int riscv_gdb_thread_packet(struct connection *connection, const char *pa return ERROR_OK; } - if (strcmp(packet, "qC") == 0) { + if (strncmp(packet, "qTStatus", 8) == 0) { + gdb_put_packet(connection, "T0", strlen("T0")); + return ERROR_OK; + } + + if (strncmp(packet, "qC", 2) == 0) { char rep_str[32]; snprintf(rep_str, 32, "QC%" PRIx64, rtos->current_threadid); gdb_put_packet(connection, rep_str, strlen(rep_str)); @@ -250,6 +255,7 @@ static int riscv_gdb_v_packet(struct connection *connection, const char *packet, if (strcmp(packet_stttrr, "vCont;c") == 0) { target_call_event_callbacks(target, TARGET_EVENT_GDB_START); target_call_event_callbacks(target, TARGET_EVENT_RESUME_START); + riscv_set_all_rtos_harts(target); riscv_openocd_resume(target, 1, 0, 0, 0); target->state = TARGET_RUNNING; gdb_set_frontend_state_running(connection); diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 3ea3242..918f99b 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -781,6 +781,10 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio gdb_connection->ctrl_c = 0; } + char sig_reply_str[46]; + memset(sig_reply_str, '\0', 46); + strncpy(sig_reply_str, sig_reply, 46); + LOG_DEBUG("signal reply: %s", sig_reply_str); gdb_put_packet(connection, sig_reply, sig_reply_len); gdb_connection->frontend_state = TARGET_HALTED; } diff --git a/src/target/riscv/batch.c b/src/target/riscv/batch.c index 9327cb3..6b3bede 100644 --- a/src/target/riscv/batch.c +++ b/src/target/riscv/batch.c @@ -51,7 +51,7 @@ int riscv_batch_run(struct riscv_batch *batch) keep_alive(); - LOG_DEBUG("running a batch of %ld scans", (long)batch->used_scans); + LOG_DEBUG_IO("running a batch of %ld scans", (long)batch->used_scans); riscv_batch_add_nop(batch); for (size_t i = 0; i < batch->used_scans; ++i) { @@ -60,7 +60,7 @@ int riscv_batch_run(struct riscv_batch *batch) jtag_add_runtest(batch->idle_count, TAP_IDLE); } - LOG_DEBUG("executing queue"); + LOG_DEBUG_IO("executing queue"); if (jtag_execute_queue() != ERROR_OK) { LOG_ERROR("Unable to execute JTAG queue"); return ERROR_FAIL; @@ -102,7 +102,7 @@ size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, unsigned address) riscv_batch_add_nop(batch); batch->read_keys[batch->read_keys_used] = batch->used_scans - 1; - LOG_DEBUG("read key %u for batch 0x%p is %u (0x%p)", + LOG_DEBUG_IO("read key %u for batch 0x%p is %u (0x%p)", (unsigned) batch->read_keys_used, batch, (unsigned) (batch->used_scans - 1), batch->data_in + sizeof(uint64_t) * (batch->used_scans + 1)); return batch->read_keys_used++; @@ -135,7 +135,7 @@ void riscv_batch_add_nop(struct riscv_batch *batch) riscv_fill_dmi_nop_u64(batch->target, (char *)field->in_value); batch->last_scan = RISCV_SCAN_TYPE_NOP; batch->used_scans++; - LOG_DEBUG(" added NOP with in_value=0x%p", field->in_value); + LOG_DEBUG_IO(" added NOP with in_value=0x%p", field->in_value); } void dump_field(const struct scan_field *field) @@ -143,7 +143,7 @@ void dump_field(const struct scan_field *field) static const char * const op_string[] = {"-", "r", "w", "?"}; static const char * const status_string[] = {"+", "?", "F", "b"}; - if (debug_level < LOG_LVL_DEBUG) + if (debug_level < LOG_LVL_DEBUG_IO) return; assert(field->out_value != NULL); @@ -158,14 +158,14 @@ void dump_field(const struct scan_field *field) unsigned int in_data = get_field(in, DTM_DMI_DATA); unsigned int in_address = in >> DTM_DMI_ADDRESS_OFFSET; - log_printf_lf(LOG_LVL_DEBUG, + log_printf_lf(LOG_LVL_DEBUG_IO, __FILE__, __LINE__, __PRETTY_FUNCTION__, "%db %s %08x @%02x -> %s %08x @%02x", field->num_bits, op_string[out_op], out_data, out_address, status_string[in_op], in_data, in_address); } else { - log_printf_lf(LOG_LVL_DEBUG, + log_printf_lf(LOG_LVL_DEBUG_IO, __FILE__, __LINE__, __PRETTY_FUNCTION__, "%db %s %08x @%02x -> ?", field->num_bits, op_string[out_op], out_data, out_address); } diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 7a7245f..350d333 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -458,14 +458,18 @@ static dmi_status_t dmi_scan(struct target *target, uint32_t *address_in, bool exec) { riscv013_info_t *info = get_info(target); - uint8_t in[8] = {0}; - uint8_t out[8]; + unsigned num_bits = info->abits + DTM_DMI_OP_LENGTH + DTM_DMI_DATA_LENGTH; + size_t num_bytes = (num_bits + 7) / 8; + uint8_t in[num_bytes]; + uint8_t out[num_bytes]; struct scan_field field = { - .num_bits = info->abits + DTM_DMI_OP_LENGTH + DTM_DMI_DATA_LENGTH, + .num_bits = num_bits, .out_value = out, .in_value = in }; + memset(in, 0, num_bytes); + assert(info->abits != 0); buf_set_u32(out, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH, op); @@ -1767,13 +1771,38 @@ static void write_to_buf(uint8_t *buffer, uint64_t value, unsigned size) static int execute_fence(struct target *target) { - struct riscv_program program; - riscv_program_init(&program, target); - riscv_program_fence(&program); - int result = riscv_program_exec(&program, target); - if (result != ERROR_OK) - LOG_ERROR("Unable to execute fence"); - return result; + int old_hartid = riscv_current_hartid(target); + + /* FIXME: For non-coherent systems we need to flush the caches right + * here, but there's no ISA-defined way of doing that. */ + { + struct riscv_program program; + riscv_program_init(&program, target); + riscv_program_fence_i(&program); + riscv_program_fence(&program); + int result = riscv_program_exec(&program, target); + if (result != ERROR_OK) + LOG_DEBUG("Unable to execute pre-fence"); + } + + for (int i = 0; i < riscv_count_harts(target); ++i) { + if (!riscv_hart_enabled(target, i)) + continue; + + riscv_set_current_hartid(target, i); + + struct riscv_program program; + riscv_program_init(&program, target); + riscv_program_fence_i(&program); + riscv_program_fence(&program); + int result = riscv_program_exec(&program, target); + if (result != ERROR_OK) + LOG_DEBUG("Unable to execute fence on hart %d", i); + } + + riscv_set_current_hartid(target, old_hartid); + + return ERROR_OK; } static void log_memory_access(target_addr_t address, uint64_t value, @@ -3336,19 +3365,7 @@ int riscv013_dmi_write_u64_bits(struct target *target) static int maybe_execute_fence_i(struct target *target) { - RISCV013_INFO(info); - RISCV_INFO(r); - if (info->progbufsize + r->impebreak >= 2) { - struct riscv_program program; - riscv_program_init(&program, target); - if (riscv_program_fence_i(&program) != ERROR_OK) - return ERROR_FAIL; - if (riscv_program_exec(&program, target) != ERROR_OK) { - LOG_ERROR("Failed to execute fence.i"); - return ERROR_FAIL; - } - } - return ERROR_OK; + return execute_fence(target); } /* Helper Functions. */ diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 0ba2e15..30efc8b 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -266,6 +266,8 @@ static int riscv_init_target(struct command_context *cmd_ctx, riscv_semihosting_init(target); + target->debug_reason = DBG_REASON_DBGRQ; + return ERROR_OK; } @@ -280,12 +282,17 @@ static void riscv_deinit_target(struct target *target) free(info); } /* Free the shared structure use for most registers. */ - free(target->reg_cache->reg_list[0].arch_info); - /* Free the ones we allocated separately. */ - for (unsigned i = GDB_REGNO_COUNT; i < target->reg_cache->num_regs; i++) - free(target->reg_cache->reg_list[i].arch_info); - free(target->reg_cache->reg_list); - free(target->reg_cache); + if (target->reg_cache) { + if (target->reg_cache->reg_list) { + if (target->reg_cache->reg_list[0].arch_info) + free(target->reg_cache->reg_list[0].arch_info); + /* Free the ones we allocated separately. */ + for (unsigned i = GDB_REGNO_COUNT; i < target->reg_cache->num_regs; i++) + free(target->reg_cache->reg_list[i].arch_info); + free(target->reg_cache->reg_list); + } + free(target->reg_cache); + } target->arch_info = NULL; } @@ -855,9 +862,11 @@ static int old_or_new_riscv_resume( static int riscv_select_current_hart(struct target *target) { RISCV_INFO(r); - if (r->rtos_hartid != -1 && riscv_rtos_enabled(target)) + if (riscv_rtos_enabled(target)) { + if (r->rtos_hartid == -1) + r->rtos_hartid = target->rtos->current_threadid - 1; return riscv_set_current_hartid(target, r->rtos_hartid); - else + } else return riscv_set_current_hartid(target, target->coreid); } @@ -1195,8 +1204,12 @@ int riscv_openocd_halt(struct target *target) register_cache_invalidate(target->reg_cache); if (riscv_rtos_enabled(target)) { - target->rtos->current_threadid = r->rtos_hartid + 1; - target->rtos->current_thread = r->rtos_hartid + 1; + if (r->rtos_hartid != -1) { + LOG_DEBUG("halt requested on RTOS hartid %d", r->rtos_hartid); + target->rtos->current_threadid = r->rtos_hartid + 1; + target->rtos->current_thread = r->rtos_hartid + 1; + } else + LOG_DEBUG("halt requested, but no known RTOS hartid"); } target->state = TARGET_HALTED; @@ -1816,6 +1829,8 @@ int riscv_halt_all_harts(struct target *target) riscv_halt_one_hart(target, i); } + riscv_invalidate_register_cache(target); + return ERROR_OK; } @@ -1868,7 +1883,7 @@ int riscv_step_rtos_hart(struct target *target) if (riscv_rtos_enabled(target)) { hartid = r->rtos_hartid; if (hartid == -1) { - LOG_USER("GDB has asked me to step \"any\" thread, so I'm stepping hart 0."); + LOG_DEBUG("GDB has asked me to step \"any\" thread, so I'm stepping hart 0."); hartid = 0; } } @@ -1941,14 +1956,15 @@ int riscv_set_current_hartid(struct target *target, int hartid) if (!target_was_examined(target)) return ERROR_OK; +#if 0 /* Avoid invalidating the register cache all the time. */ if (r->registers_initialized && (!riscv_rtos_enabled(target) || (previous_hartid == hartid)) - && target->reg_cache->reg_list[GDB_REGNO_ZERO].size == (unsigned)riscv_xlen(target) - && (!riscv_rtos_enabled(target) || (r->rtos_hartid != -1))) { + && target->reg_cache->reg_list[GDB_REGNO_ZERO].size == (unsigned)riscv_xlen(target) { return ERROR_OK; } else LOG_DEBUG("Initializing registers: xlen=%d", riscv_xlen(target)); +#endif riscv_invalidate_register_cache(target); return ERROR_OK; @@ -2030,7 +2046,15 @@ int riscv_get_register_on_hart(struct target *target, riscv_reg_t *value, int hartid, enum gdb_regno regid) { RISCV_INFO(r); + + if (hartid != riscv_current_hartid(target)) + riscv_invalidate_register_cache(target); + int result = r->get_register(target, value, hartid, regid); + + if (hartid != riscv_current_hartid(target)) + riscv_invalidate_register_cache(target); + LOG_DEBUG("[%d] %s: %" PRIx64, hartid, gdb_regno_name(regid), *value); return result; } diff --git a/src/target/startup.tcl b/src/target/startup.tcl index cf844e1..9bbc6e3 100644 --- a/src/target/startup.tcl +++ b/src/target/startup.tcl @@ -203,7 +203,6 @@ proc init_target_events {} { foreach t $targets { set_default_target_event $t gdb-flash-erase-start "reset init" set_default_target_event $t gdb-flash-write-end "reset halt" - set_default_target_event $t gdb-attach "halt" } } |