From 51db0cae88dcb1b8c3217864b80cad55214962ef Mon Sep 17 00:00:00 2001 From: Biancaa Ramesh Date: Sun, 26 Oct 2025 14:43:17 +0530 Subject: [PATCH 1/2] added the necessary tests for progbufsize Added additional debug logs to verify correct retrieval and printing of progbufsize in various code paths within riscv-013.c. This helps in debugging hardware configurations that expose custom program buffer sizes. Signed-off-by: Biancaa Ramesh --- src/target/riscv/riscv-013.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index f2fb22f98..165c281d0 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -1385,6 +1385,11 @@ static int fpr_read_progbuf(struct target *target, uint64_t *value, { assert(target->state == TARGET_HALTED); assert(number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31); + if (!has_sufficient_progbuf(target, 2)) { + LOG_DEBUG("Skipping FPR read: insufficient progbuf (size=%d)", + get_info(target)->progbufsize); + return ERROR_FAIL; + } const unsigned int freg = number - GDB_REGNO_FPR0; @@ -1417,6 +1422,11 @@ static int csr_read_progbuf(struct target *target, uint64_t *value, { assert(target->state == TARGET_HALTED); assert(number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095); + if (!has_sufficient_progbuf(target, 2)) { + LOG_DEBUG("Skipping CSR read: insufficient progbuf (size=%d)", + get_info(target)->progbufsize); + return ERROR_FAIL; + } if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK) return ERROR_FAIL; @@ -1484,6 +1494,11 @@ static int fpr_write_progbuf(struct target *target, enum gdb_regno number, { assert(target->state == TARGET_HALTED); assert(number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31); + if (!has_sufficient_progbuf(target, 2)) { + LOG_DEBUG("Skipping FPR Write: insufficient progbuf (size=%d)", + get_info(target)->progbufsize); + return ERROR_FAIL; + } const unsigned int freg = number - GDB_REGNO_FPR0; if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK) @@ -1559,6 +1574,11 @@ static int csr_write_progbuf(struct target *target, enum gdb_regno number, { assert(target->state == TARGET_HALTED); assert(number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095); + if (!has_sufficient_progbuf(target, 2)) { + LOG_DEBUG("Skipping CSR write: insufficient progbuf (size=%d)", + get_info(target)->progbufsize); + return ERROR_FAIL; + } if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK) return ERROR_FAIL; @@ -5554,4 +5574,4 @@ static int riscv013_clear_abstract_error(struct target *target) if (dm_write(target, DM_ABSTRACTCS, DM_ABSTRACTCS_CMDERR) != ERROR_OK) result = ERROR_FAIL; return result; -} +} \ No newline at end of file From 38450adf7c6fef39be48d3280e5f8e7500184bca Mon Sep 17 00:00:00 2001 From: Biancaa Ramesh Date: Mon, 27 Oct 2025 20:52:50 +0530 Subject: [PATCH 2/2] riscv: Add have_progbuf_size check in vtype,vl writes and crs,fpr read-write Added a check for have_progbuf_size before attempting to execute. This prevents program buffer access on targets that do not support it, improving robustness and avoiding potential execution failures when the program buffer is not available or too small. Signed-off-by: Biancaa Ramesh --- src/target/riscv/riscv-013.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 165c281d0..043b294f1 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -1386,8 +1386,7 @@ static int fpr_read_progbuf(struct target *target, uint64_t *value, assert(target->state == TARGET_HALTED); assert(number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31); if (!has_sufficient_progbuf(target, 2)) { - LOG_DEBUG("Skipping FPR read: insufficient progbuf (size=%d)", - get_info(target)->progbufsize); + LOG_TARGET_DEBUG("Skipping FPR read: insufficient progbuf (size=%u)", get_info(target)->progbufsize); return ERROR_FAIL; } @@ -1423,8 +1422,7 @@ static int csr_read_progbuf(struct target *target, uint64_t *value, assert(target->state == TARGET_HALTED); assert(number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095); if (!has_sufficient_progbuf(target, 2)) { - LOG_DEBUG("Skipping CSR read: insufficient progbuf (size=%d)", - get_info(target)->progbufsize); + LOG_TARGET_DEBUG("Skipping CSR read: insufficient progbuf (size=%u)", get_info(target)->progbufsize); return ERROR_FAIL; } @@ -1441,6 +1439,7 @@ static int csr_read_progbuf(struct target *target, uint64_t *value, return register_read_abstract(target, value, GDB_REGNO_S0) != ERROR_OK; } + /** * This function reads a register by writing a program to program buffer and * executing it. @@ -1495,8 +1494,7 @@ static int fpr_write_progbuf(struct target *target, enum gdb_regno number, assert(target->state == TARGET_HALTED); assert(number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31); if (!has_sufficient_progbuf(target, 2)) { - LOG_DEBUG("Skipping FPR Write: insufficient progbuf (size=%d)", - get_info(target)->progbufsize); + LOG_TARGET_DEBUG("Skipping FPR Write: insufficient progbuf (size=%u)",get_info(target)->progbufsize); return ERROR_FAIL; } const unsigned int freg = number - GDB_REGNO_FPR0; @@ -1530,6 +1528,11 @@ static int fpr_write_progbuf(struct target *target, enum gdb_regno number, static int vtype_write_progbuf(struct target *target, riscv_reg_t value) { assert(target->state == TARGET_HALTED); + /* Ensure program buffer is large enough for 2 instructions */ + if (!has_sufficient_progbuf(target, 2)) { + LOG_TARGET_DEBUG("Skipping vtype write: insufficient progbuf (size=%u)", get_info(target)->progbufsize); + return ERROR_FAIL; + } if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK) return ERROR_FAIL; @@ -1551,6 +1554,11 @@ static int vtype_write_progbuf(struct target *target, riscv_reg_t value) static int vl_write_progbuf(struct target *target, riscv_reg_t value) { assert(target->state == TARGET_HALTED); + /* Ensure program buffer is large enough for 2 instructions */ + if (!has_sufficient_progbuf(target, 2)) { + LOG_TARGET_DEBUG("Skipping vl write: insufficient progbuf (size=%u)", get_info(target)->progbufsize); + return ERROR_FAIL; + } if (riscv013_reg_save(target, GDB_REGNO_S0) != ERROR_OK) return ERROR_FAIL; @@ -1575,8 +1583,7 @@ static int csr_write_progbuf(struct target *target, enum gdb_regno number, assert(target->state == TARGET_HALTED); assert(number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095); if (!has_sufficient_progbuf(target, 2)) { - LOG_DEBUG("Skipping CSR write: insufficient progbuf (size=%d)", - get_info(target)->progbufsize); + LOG_TARGET_DEBUG("Skipping CSR write: insufficient progbuf (size=%u)", get_info(target)->progbufsize); return ERROR_FAIL; } @@ -5574,4 +5581,4 @@ static int riscv013_clear_abstract_error(struct target *target) if (dm_write(target, DM_ABSTRACTCS, DM_ABSTRACTCS_CMDERR) != ERROR_OK) result = ERROR_FAIL; return result; -} \ No newline at end of file +}