From 10a2823191a96911c6f12def22703f01f392f2a5 Mon Sep 17 00:00:00 2001 From: cgsfv Date: Wed, 22 Aug 2018 13:25:27 +0200 Subject: Read memory words individually if burst read fails --- src/target/riscv/riscv-013.c | 123 +++++++++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 34ec3c6..37206ea 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -2036,53 +2036,13 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address, * Read the requested memory, taking care to execute every read exactly once, * even if cmderr=busy is encountered. */ -static int read_memory_progbuf(struct target *target, target_addr_t address, +static int read_memory_progbuf_inner(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer) { RISCV013_INFO(info); int result = ERROR_OK; - LOG_DEBUG("reading %d words of %d bytes from 0x%" TARGET_PRIxADDR, count, - size, address); - - select_dmi(target); - - /* s0 holds the next address to write to - * s1 holds the next data value to write - */ - uint64_t s0, s1; - if (register_read(target, &s0, GDB_REGNO_S0) != ERROR_OK) - return ERROR_FAIL; - if (register_read(target, &s1, GDB_REGNO_S1) != ERROR_OK) - return ERROR_FAIL; - - if (execute_fence(target) != ERROR_OK) - return ERROR_FAIL; - - /* Write the program (load, increment) */ - struct riscv_program program; - riscv_program_init(&program, target); - switch (size) { - case 1: - riscv_program_lbr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0); - break; - case 2: - riscv_program_lhr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0); - break; - case 4: - riscv_program_lwr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0); - break; - default: - LOG_ERROR("Unsupported size: %d", size); - return ERROR_FAIL; - } - riscv_program_addi(&program, GDB_REGNO_S0, GDB_REGNO_S0, size); - - if (riscv_program_ebreak(&program) != ERROR_OK) - return ERROR_FAIL; - riscv_program_write(&program); - /* Write address to S0, and execute buffer. */ result = register_write_direct(target, GDB_REGNO_S0, address); if (result != ERROR_OK) @@ -2210,7 +2170,7 @@ static int read_memory_progbuf(struct target *target, target_addr_t address, 1 << DMI_ABSTRACTAUTO_AUTOEXECDATA_OFFSET); break; default: - LOG_ERROR("error when reading memory, abstractcs=0x%08lx", (long)abstractcs); + LOG_DEBUG("error when reading memory, abstractcs=0x%08lx", (long)abstractcs); riscv013_clear_abstract_error(target); riscv_batch_free(batch); result = ERROR_FAIL; @@ -2268,13 +2228,88 @@ static int read_memory_progbuf(struct target *target, target_addr_t address, write_to_buf(buffer + receive_addr - address, value, size); log_memory_access(receive_addr, value, size, true); - riscv_set_register(target, GDB_REGNO_S0, s0); - riscv_set_register(target, GDB_REGNO_S1, s1); return ERROR_OK; error: dmi_write(target, DMI_ABSTRACTAUTO, 0); + return result; +} + +/** + * Read the requested memory, silently handling memory access errors. + */ +static int read_memory_progbuf(struct target *target, target_addr_t address, + uint32_t size, uint32_t count, uint8_t *buffer) +{ + int result = ERROR_OK; + + LOG_DEBUG("reading %d words of %d bytes from 0x%" TARGET_PRIxADDR, count, + size, address); + + select_dmi(target); + + /* s0 holds the next address to write to + * s1 holds the next data value to write + */ + uint64_t s0, s1; + if (register_read(target, &s0, GDB_REGNO_S0) != ERROR_OK) + return ERROR_FAIL; + if (register_read(target, &s1, GDB_REGNO_S1) != ERROR_OK) + return ERROR_FAIL; + + if (execute_fence(target) != ERROR_OK) + return ERROR_FAIL; + + /* Write the program (load, increment) */ + struct riscv_program program; + riscv_program_init(&program, target); + switch (size) { + case 1: + riscv_program_lbr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0); + break; + case 2: + riscv_program_lhr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0); + break; + case 4: + riscv_program_lwr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0); + break; + default: + LOG_ERROR("Unsupported size: %d", size); + return ERROR_FAIL; + } + riscv_program_addi(&program, GDB_REGNO_S0, GDB_REGNO_S0, size); + + if (riscv_program_ebreak(&program) != ERROR_OK) + return ERROR_FAIL; + riscv_program_write(&program); + + result = read_memory_progbuf_inner(target, address, size, count, buffer); + + /* The full read did not succeed, so we will try to read each word individually. */ + /* This will not be fast, but reading outside actual memory is a special case anyway. */ + /* It will make the toolchain happier, especially Eclipse Memory View as it reads ahead. */ + if (result != ERROR_OK) { + target_addr_t address_i = address; + uint32_t size_i = size; + uint32_t count_i = 1; + uint8_t* buffer_i = buffer; + + for (uint32_t i = 0; i < count; i++, address_i += size_i, buffer_i += size_i) { + result = read_memory_progbuf_inner(target, address_i, size_i, count_i, buffer_i); + + /* The read of a single word failed, so we will just return 0 for that instead */ + if (result != ERROR_OK) { + LOG_DEBUG("error reading single word of %d bytes from 0x%" TARGET_PRIxADDR, + size_i, address_i); + + uint64_t value_i = 0; + write_to_buf(buffer_i, value_i, size_i); + } + } + result = ERROR_OK; + } + riscv_set_register(target, GDB_REGNO_S0, s0); riscv_set_register(target, GDB_REGNO_S1, s1); return result; -- cgit v1.1 From c3a744149c1897adfe0b94f691e8322ce8b801e8 Mon Sep 17 00:00:00 2001 From: cgsfv Date: Thu, 23 Aug 2018 14:10:47 +0200 Subject: Use LOG_DEBUG for debug messages: Discard unexpected char --- src/server/gdb_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 58df51a..3ea3242 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -390,7 +390,7 @@ static int gdb_put_packet_inner(struct connection *connection, break; } - LOG_WARNING("Discard unexpected char %c", reply); + LOG_DEBUG("Discard unexpected char %c", reply); } #endif -- cgit v1.1 From 0a31d919e36016fb05bdf0d18f58aa5c32578b2c Mon Sep 17 00:00:00 2001 From: cgsfv Date: Mon, 17 Sep 2018 10:49:36 -0700 Subject: Corrected wrong C syntax --- src/target/riscv/riscv-013.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 37206ea..7a7245f 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -2293,7 +2293,7 @@ static int read_memory_progbuf(struct target *target, target_addr_t address, target_addr_t address_i = address; uint32_t size_i = size; uint32_t count_i = 1; - uint8_t* buffer_i = buffer; + uint8_t *buffer_i = buffer; for (uint32_t i = 0; i < count; i++, address_i += size_i, buffer_i += size_i) { result = read_memory_progbuf_inner(target, address_i, size_i, count_i, buffer_i); -- cgit v1.1