aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPalmer Dabbelt <palmer@dabbelt.com>2017-04-14 17:44:47 -0700
committerPalmer Dabbelt <palmer@dabbelt.com>2017-04-14 17:44:47 -0700
commit763e5cb44c2e8d40b147d0585e146e5ce6be6411 (patch)
tree6be7a4b5ec9621d68d5bfedf0efd071cfe5c9bf5
parent6c74c1c6f31c4a588f7f5dae6acc7eafdad93257 (diff)
downloadriscv-openocd-763e5cb44c2e8d40b147d0585e146e5ce6be6411.zip
riscv-openocd-763e5cb44c2e8d40b147d0585e146e5ce6be6411.tar.gz
riscv-openocd-763e5cb44c2e8d40b147d0585e146e5ce6be6411.tar.bz2
memoize
-rw-r--r--src/target/riscv/riscv-013.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 1860e98..c71597f 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -69,6 +69,8 @@ static void riscv013_execute_debug_buffer(struct target *target);
#define CSR_DCSR_CAUSE_STEP 4
#define CSR_DCSR_CAUSE_HALT 5
+#define RISCV013_INFO(r) riscv013_info_t *r = get_info(target)
+
/*** JTAG registers. ***/
typedef enum {
@@ -168,6 +170,9 @@ typedef struct {
unsigned int ac_busy_delay;
bool need_strict_step;
+
+ // Some memoized values
+ int progbuf_size, progbuf_addr, data_addr, data_size;
} riscv013_info_t;
static void dump_field(const struct scan_field *field)
@@ -740,6 +745,11 @@ static int init_target(struct command_context *cmd_ctx,
return ERROR_FAIL;
riscv013_info_t *info = get_info(target);
+ info->progbuf_size = -1;
+ info->progbuf_addr = -1;
+ info->data_size = -1;
+ info->data_addr = -1;
+
target->reg_cache = calloc(1, sizeof(*target->reg_cache));
target->reg_cache->name = "RISC-V registers";
target->reg_cache->num_regs = GDB_REGNO_COUNT;
@@ -1722,18 +1732,30 @@ static void riscv013_step_or_resume_current_hart(struct target *target, bool ste
size_t riscv013_progbuf_size(struct target *target)
{
- uint32_t acs = dmi_read(target, DMI_ABSTRACTCS);
- return get_field(acs, DMI_ABSTRACTCS_PROGSIZE);
+ RISCV013_INFO(info);
+ if (info->progbuf_size == -1) {
+ uint32_t acs = dmi_read(target, DMI_ABSTRACTCS);
+ info->progbuf_size = get_field(acs, DMI_ABSTRACTCS_PROGSIZE);
+ }
+ return info->progbuf_size;
}
size_t riscv013_data_size(struct target *target)
{
- uint32_t acs = dmi_read(target, DMI_HARTINFO);
- return get_field(acs, DMI_HARTINFO_DATASIZE);
+ RISCV013_INFO(info);
+ if (info->data_size == -1) {
+ uint32_t acs = dmi_read(target, DMI_HARTINFO);
+ info->data_size = get_field(acs, DMI_HARTINFO_DATASIZE);
+ }
+ return info->data_size;
}
size_t riscv013_data_addr(struct target *target)
{
- uint32_t acs = dmi_read(target, DMI_HARTINFO);
- return get_field(acs, DMI_HARTINFO_DATAACCESS) ? get_field(acs, DMI_HARTINFO_DATAADDR) : 0;
+ RISCV013_INFO(info);
+ if (info->data_addr == -1) {
+ uint32_t acs = dmi_read(target, DMI_HARTINFO);
+ info->data_addr = get_field(acs, DMI_HARTINFO_DATAACCESS) ? get_field(acs, DMI_HARTINFO_DATAADDR) : 0;
+ }
+ return info->data_addr;
}