From 4917ba5ef380dd862fc185537fe638e419b4b3cb Mon Sep 17 00:00:00 2001 From: Parshintsev Anatoly Date: Sat, 3 Aug 2024 13:56:52 +0300 Subject: [PATCH] target/riscv: sys bus v1 fix for sizes greater than 4 read_memory_bus_v1 incorrectly copied data to ouput buffer Signed-off-by: Parshintsev Anatoly --- src/target/riscv/riscv-013.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index ae36a063d..8322f4c0d 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -16,6 +16,7 @@ #include "target/target.h" #include "target/algorithm.h" #include "target/target_type.h" +#include #include #include "jtag/jtag.h" #include "target/register.h" @@ -3349,6 +3350,9 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address, return ERROR_NOT_IMPLEMENTED; } + assert(size <= 16); + assert(IS_PWR_OF_2(size)); + dm013_info_t *dm = get_dm(target); if (!dm) return ERROR_FAIL; @@ -3384,7 +3388,6 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address, * be unnecessary. */ uint32_t sbvalue[4] = {0}; - assert(size <= 16); for (uint32_t i = (next_address - address) / size; i < count - 1; i++) { const uint32_t size_in_words = DIV_ROUND_UP(size, 4); struct riscv_batch *batch = riscv_batch_alloc(target, size_in_words); @@ -3405,9 +3408,12 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address, const size_t last_key = batch->read_keys_used - 1; for (size_t k = 0; k <= last_key; ++k) { - sbvalue[k] = riscv_batch_get_dmi_read_data(batch, - last_key - k); - buf_set_u32(buffer + i * size + k * 4, 0, 8 * size, sbvalue[k]); + sbvalue[k] = riscv_batch_get_dmi_read_data(batch, last_key - k); + /* This can be written as: n_bits = MIN(32, 8 * size), but I think + * we'd better to be explicit on how n_bits is calculated */ + const size_t n_bits = (k != last_key) ? 32 : (8 * size - k * 4 * 8); + assert(n_bits <= 32); + buf_set_u32(buffer + i * size + k * 4, 0, n_bits, sbvalue[k]); } riscv_batch_free(batch); const target_addr_t read_addr = address + i * increment;