From 02ece46105ec7d5fe7144adec071ac75706234fe Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Thu, 10 Jan 2019 12:32:03 -0800 Subject: [PATCH] Clean up register caching a little. Change-Id: Id039aedac44d9c206ac4bd30eb3ef754e190c3fe --- src/target/riscv/riscv-013.c | 14 -------------- src/target/riscv/riscv.c | 34 +++++++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 75224e925..0d74d5cae 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -1127,7 +1127,6 @@ static int register_write_direct(struct target *target, unsigned number, if (result == ERROR_OK && target->reg_cache) { struct reg *reg = &target->reg_cache->reg_list[number]; buf_set_u64(reg->value, 0, reg->size, value); - reg->valid = true; } if (result == ERROR_OK || info->progbufsize + r->impebreak < 2 || !riscv_is_halted(target)) @@ -1186,7 +1185,6 @@ static int register_write_direct(struct target *target, unsigned number, if (exec_out == ERROR_OK && target->reg_cache) { struct reg *reg = &target->reg_cache->reg_list[number]; buf_set_u64(reg->value, 0, reg->size, value); - reg->valid = true; } if (use_scratch) @@ -1206,24 +1204,12 @@ static int register_read(struct target *target, uint64_t *value, uint32_t number *value = 0; return ERROR_OK; } - if (target->reg_cache && - (number <= GDB_REGNO_XPR31 || - (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31))) { - /* Only check the cache for registers that we know won't spontaneously - * change. */ - struct reg *reg = &target->reg_cache->reg_list[number]; - if (reg && reg->valid) { - *value = buf_get_u64(reg->value, 0, reg->size); - return ERROR_OK; - } - } int result = register_read_direct(target, value, number); if (result != ERROR_OK) return ERROR_FAIL; if (target->reg_cache) { struct reg *reg = &target->reg_cache->reg_list[number]; buf_set_u64(reg->value, 0, reg->size, *value); - reg->valid = true; } return ERROR_OK; } diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index d786d56be..65e019938 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -1992,10 +1992,10 @@ int riscv_set_current_hartid(struct target *target, int hartid) /* This might get called during init, in which case we shouldn't be * setting up the register cache. */ - if (!target_was_examined(target)) - return ERROR_OK; + //if (target_was_examined(target) && hartid != previous_hartid) + if (target_was_examined(target) && riscv_rtos_enabled(target)) + riscv_invalidate_register_cache(target); - riscv_invalidate_register_cache(target); return ERROR_OK; } @@ -2003,6 +2003,8 @@ void riscv_invalidate_register_cache(struct target *target) { RISCV_INFO(r); + LOG_DEBUG(">>>"); + register_cache_invalidate(target->reg_cache); for (size_t i = 0; i < target->reg_cache->num_regs; ++i) { struct reg *reg = &target->reg_cache->reg_list[i]; @@ -2079,6 +2081,12 @@ int riscv_get_register_on_hart(struct target *target, riscv_reg_t *value, if (hartid != riscv_current_hartid(target)) riscv_invalidate_register_cache(target); + struct reg *reg = &target->reg_cache->reg_list[regid]; + if (reg && reg->valid) { + *value = buf_get_u64(reg->value, 0, reg->size); + return ERROR_OK; + } + int result = r->get_register(target, value, hartid, regid); if (hartid != riscv_current_hartid(target)) @@ -2292,6 +2300,15 @@ static int register_get(struct reg *reg) if (result != ERROR_OK) return result; buf_set_u64(reg->value, 0, reg->size, value); + /* CSRs (and possibly other extension) registers may change value at any + * time. */ + if (reg->number <= GDB_REGNO_XPR31 || + (reg->number >= GDB_REGNO_FPR0 && reg->number <= GDB_REGNO_FPR31) || + reg->number == GDB_REGNO_PC) + reg->valid = true; + LOG_DEBUG("[%d,%d] read 0x%" PRIx64 " from %s (valid=%d)", + target->coreid, riscv_current_hartid(target), value, reg->name, + reg->valid); return ERROR_OK; } @@ -2302,9 +2319,16 @@ static int register_set(struct reg *reg, uint8_t *buf) uint64_t value = buf_get_u64(buf, 0, reg->size); - LOG_DEBUG("write 0x%" PRIx64 " to %s", value, reg->name); + LOG_DEBUG("[%d,%d] write 0x%" PRIx64 " to %s (valid=%d)", + target->coreid, riscv_current_hartid(target), value, reg->name, + reg->valid); struct reg *r = &target->reg_cache->reg_list[reg->number]; - r->valid = true; + /* CSRs (and possibly other extension) registers may change value at any + * time. */ + if (reg->number <= GDB_REGNO_XPR31 || + (reg->number >= GDB_REGNO_FPR0 && reg->number <= GDB_REGNO_FPR31) || + reg->number == GDB_REGNO_PC) + r->valid = true; memcpy(r->value, buf, (r->size + 7) / 8); riscv_set_register(target, reg->number, value);