From c2642acebe8f31192329abf6c7b013965683c98d Mon Sep 17 00:00:00 2001 From: cgsfv Date: Wed, 22 Aug 2018 13:25:27 +0200 Subject: [PATCH 1/3] Read memory words individually if burst read fails --- src/target/riscv/riscv-013.c | 123 ++++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 44 deletions(-) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 9f4af6723..78f1f5926 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -2021,53 +2021,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) @@ -2195,7 +2155,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; @@ -2253,13 +2213,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; From 71a18e3da3fb87081311e430895b414126418f1b Mon Sep 17 00:00:00 2001 From: cgsfv Date: Thu, 23 Aug 2018 14:10:47 +0200 Subject: [PATCH 2/3] Use LOG_DEBUG for debug messages: Discard unexpected char --- src/server/gdb_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index eb4eea959..b77a2396a 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 From 3ed62ebf0da269c8966142e7563e004a5fe1c900 Mon Sep 17 00:00:00 2001 From: cgsfv Date: Mon, 17 Sep 2018 10:49:36 -0700 Subject: [PATCH 3/3] Corrected wrong C syntax --- src/target/riscv/riscv-013.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 78f1f5926..ba58056fc 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -2278,7 +2278,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);