From eb7232c842cd91c0a3033723d2aa3ae79b13e9eb Mon Sep 17 00:00:00 2001 From: Evgeniy Naydanov Date: Tue, 28 Oct 2025 17:16:55 +0300 Subject: [PATCH] target/riscv: fix progbuf memory writes in case last write is busy Restarting the program buffer memory write pipeline when the write of the last element resulted in the busy response triggers an extra memory wrtite, that is cought by an assertion: ``` src/target/riscv/riscv-013.c:5048: write_memory_progbuf_inner: Assertion `next_addr_on_target - args.address <= (target_addr_t)args.size * args.count' failed. ``` Change-Id: I0f27145cad24686cf539aebfea7f6578b7cd78ab Signed-off-by: Evgeniy Naydanov --- src/target/riscv/riscv-013.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index f2fb22f98..7975bd1b7 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -4873,7 +4873,8 @@ static int write_memory_progbuf_teardown(struct target *target) * failed write. */ static int write_memory_progbuf_handle_busy(struct target *target, - target_addr_t *address_p, uint32_t size, const uint8_t *buffer) + target_addr_t *address_p, target_addr_t end_address, uint32_t size, + const uint8_t *buffer) { int res = riscv013_clear_abstract_error(target); if (res != ERROR_OK) @@ -4889,8 +4890,12 @@ static int write_memory_progbuf_handle_busy(struct target *target, if (register_read_direct(target, &address_on_target, GDB_REGNO_S0) != ERROR_OK) return ERROR_FAIL; const uint8_t * const curr_buff = buffer + (address_on_target - *address_p); - LOG_TARGET_DEBUG(target, "Restarting from 0x%" TARGET_PRIxADDR, *address_p); *address_p = address_on_target; + if (*address_p == end_address) { + LOG_TARGET_DEBUG(target, "Got busy while reading after reading the last element"); + return ERROR_OK; + } + LOG_TARGET_DEBUG(target, "Restarting from 0x%" TARGET_PRIxADDR, *address_p); /* This restores the pipeline and ensures one item gets reliably written */ return write_memory_progbuf_startup(target, address_p, curr_buff, size); } @@ -4968,7 +4973,8 @@ static int write_memory_progbuf_run_batch(struct target *target, struct riscv_ba /* TODO: If dmi busy is encountered, the address of the last * successful write can be deduced by analysing the batch. */ - return write_memory_progbuf_handle_busy(target, address_p, size, buffer); + return write_memory_progbuf_handle_busy(target, address_p, end_address, + size, buffer); } LOG_TARGET_ERROR(target, "Error when writing memory, abstractcs=0x%" PRIx32, abstractcs);