From d1b2b5aaf81de6d82fc5b4db4ddc0d1361e6320e Mon Sep 17 00:00:00 2001 From: Rafael Silva Date: Thu, 19 Dec 2024 14:12:57 +0000 Subject: [PATCH] riscv32: fix RV32E register count and respective size RV32E base ISA devices have 16 GPRs while RV32I base ISA devices have 32, this is correctly reported to gdb in the target description xml, but when reading or writing all registers 32 registers were considered to be present --- src/target/riscv32.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/target/riscv32.c b/src/target/riscv32.c index 51c1a2e3b2e..a39ff5ce5b1 100644 --- a/src/target/riscv32.c +++ b/src/target/riscv32.c @@ -40,11 +40,6 @@ #include "gdb_packet.h" #include "adiv5.h" -typedef struct riscv32_regs { - uint32_t gprs[32]; - uint32_t pc; -} riscv32_regs_s; - /* This defines a match trigger that's for an address or data location */ #define RV32_MATCH_ADDR_DATA_TRIGGER 0x20000000U /* A dmode of 1 restricts the writability of the trigger to debug mode only */ @@ -80,8 +75,11 @@ static int riscv32_breakwatch_clear(target_s *target, breakwatch_s *breakwatch); bool riscv32_probe(target_s *const target) { + /* 'E' base ISA has 16 GPRs + PC, 'I' base ISA has 32 GPRs + PC */ + riscv_hart_s *const hart = riscv_hart_struct(target); + target->regs_size = ((hart->extensions & RV_ISA_EXT_EMBEDDED ? 16U : 32U) + 1U) * sizeof(uint32_t); + /* Finish setting up the target structure with generic rv32 functions */ - target->regs_size = sizeof(riscv32_regs_s); /* Provide the length of a suitable registers structure */ target->regs_read = riscv32_regs_read; target->regs_write = riscv32_regs_write; target->reg_write = riscv32_reg_write; @@ -119,30 +117,30 @@ static void riscv32_regs_read(target_s *const target, void *const data) { /* Grab the hart structure and figure out how many registers need reading out */ riscv_hart_s *const hart = riscv_hart_struct(target); - riscv32_regs_s *const regs = (riscv32_regs_s *)data; + uint32_t *const regs = (uint32_t *)data; const size_t gprs_count = hart->extensions & RV_ISA_EXT_EMBEDDED ? 16U : 32U; /* Loop through reading out the GPRs */ for (size_t gpr = 0; gpr < gprs_count; ++gpr) { // TODO: handle when this fails.. - riscv_csr_read(hart, RV_GPR_BASE + gpr, ®s->gprs[gpr]); + riscv_csr_read(hart, RV_GPR_BASE + gpr, ®s[gpr]); } /* Special access to grab the program counter that would be executed on resuming the hart */ - riscv_csr_read(hart, RV_DPC, ®s->pc); + riscv_csr_read(hart, RV_DPC, ®s[gprs_count]); } static void riscv32_regs_write(target_s *const target, const void *const data) { /* Grab the hart structure and figure out how many registers need reading out */ riscv_hart_s *const hart = riscv_hart_struct(target); - const riscv32_regs_s *const regs = (const riscv32_regs_s *)data; + const uint32_t *const regs = (const uint32_t *)data; const size_t gprs_count = hart->extensions & RV_ISA_EXT_EMBEDDED ? 16U : 32U; /* Loop through writing out the GPRs, except for the first which is always 0 */ for (size_t gpr = 1; gpr < gprs_count; ++gpr) { // TODO: handle when this fails.. - riscv_csr_write(hart, RV_GPR_BASE + gpr, ®s->gprs[gpr]); + riscv_csr_write(hart, RV_GPR_BASE + gpr, ®s[gpr]); } /* Special access to poke in the program counter that will be executed on resuming the hart */ - riscv_csr_write(hart, RV_DPC, ®s->pc); + riscv_csr_write(hart, RV_DPC, ®s[gprs_count]); } static inline size_t riscv32_bool_to_4(const bool ret)