Speed up register read.
Don't scan an extra sequence just to read the return value.__archive__
parent
27b94d36d0
commit
1fdcfa7082
|
@ -406,6 +406,7 @@ static void cache_set(struct target *target, unsigned int index, uint32_t data)
|
||||||
info->dram_cache[index].data == data) {
|
info->dram_cache[index].data == data) {
|
||||||
// This is already preset on the target.
|
// This is already preset on the target.
|
||||||
LOG_DEBUG("Cache hit at 0x%x for data 0x%x", index, data);
|
LOG_DEBUG("Cache hit at 0x%x for data 0x%x", index, data);
|
||||||
|
assert(dram_read32(target, index) == info->dram_cache[index].data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
info->dram_cache[index].data = data;
|
info->dram_cache[index].data = data;
|
||||||
|
@ -427,6 +428,30 @@ static void dump_debug_ram(struct target *target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Call this if the code you just ran writes to debug RAM entries 0 through 3. */
|
||||||
|
static void cache_invalidate(struct target *target)
|
||||||
|
{
|
||||||
|
riscv_info_t *info = (riscv_info_t *) target->arch_info;
|
||||||
|
for (unsigned int i = 0; i < DRAM_CACHE_SIZE; i++) {
|
||||||
|
info->dram_cache[i].valid = false;
|
||||||
|
info->dram_cache[i].dirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called by cache_write() after the program has run. Also call this if you're
|
||||||
|
* running programs without calling cache_write(). */
|
||||||
|
static void cache_clean(struct target *target)
|
||||||
|
{
|
||||||
|
riscv_info_t *info = (riscv_info_t *) target->arch_info;
|
||||||
|
for (unsigned int i = 0; i < DRAM_CACHE_SIZE; i++) {
|
||||||
|
if (i >= 4) {
|
||||||
|
info->dram_cache[i].valid = false;
|
||||||
|
} else {
|
||||||
|
info->dram_cache[i].dirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Write cache to the target, and optionally run the program. */
|
/** Write cache to the target, and optionally run the program. */
|
||||||
static int cache_write(struct target *target, unsigned int address, bool run)
|
static int cache_write(struct target *target, unsigned int address, bool run)
|
||||||
{
|
{
|
||||||
|
@ -553,6 +578,7 @@ static int cache_write(struct target *target, unsigned int address, bool run)
|
||||||
}
|
}
|
||||||
info->dram_cache[i].dirty = false;
|
info->dram_cache[i].dirty = false;
|
||||||
}
|
}
|
||||||
|
cache_clean(target);
|
||||||
|
|
||||||
if (wait_for_debugint_clear(target, true) != ERROR_OK) {
|
if (wait_for_debugint_clear(target, true) != ERROR_OK) {
|
||||||
LOG_ERROR("Debug interrupt didn't clear.");
|
LOG_ERROR("Debug interrupt didn't clear.");
|
||||||
|
@ -561,6 +587,8 @@ static int cache_write(struct target *target, unsigned int address, bool run)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
cache_clean(target);
|
||||||
|
|
||||||
int interrupt = buf_get_u32(in + 8*(scan-1), DBUS_DATA_START + 33, 1);
|
int interrupt = buf_get_u32(in + 8*(scan-1), DBUS_DATA_START + 33, 1);
|
||||||
if (interrupt) {
|
if (interrupt) {
|
||||||
info->interrupt_high_count++;
|
info->interrupt_high_count++;
|
||||||
|
@ -570,14 +598,16 @@ static int cache_write(struct target *target, unsigned int address, bool run)
|
||||||
dump_debug_ram(target);
|
dump_debug_ram(target);
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < DRAM_CACHE_SIZE; i++) {
|
|
||||||
if (i >= 4) {
|
|
||||||
info->dram_cache[i].valid = false;
|
|
||||||
} else {
|
} else {
|
||||||
info->dram_cache[i].dirty = false;
|
// We read a useful value in that last scan.
|
||||||
|
unsigned int read_addr = buf_get_u32(in + 8*(scan-1), DBUS_ADDRESS_START, info->addrbits);
|
||||||
|
if (read_addr != address) {
|
||||||
|
LOG_INFO("Got data from 0x%x but expected it from 0x%x",
|
||||||
|
read_addr, address);
|
||||||
|
}
|
||||||
|
info->dram_cache[read_addr].data =
|
||||||
|
buf_get_u64(in + 8*(scan-1), DBUS_DATA_START, DBUS_DATA_SIZE);
|
||||||
|
info->dram_cache[read_addr].valid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,14 +616,14 @@ static int cache_write(struct target *target, unsigned int address, bool run)
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call this if the code you just ran writes to debug RAM entries 0 through 3. */
|
uint32_t cache_get32(struct target *target, unsigned int address)
|
||||||
static void cache_invalidate(struct target *target)
|
|
||||||
{
|
{
|
||||||
riscv_info_t *info = (riscv_info_t *) target->arch_info;
|
riscv_info_t *info = (riscv_info_t *) target->arch_info;
|
||||||
for (unsigned int i = 0; i < DRAM_CACHE_SIZE; i++) {
|
if (!info->dram_cache[address].valid) {
|
||||||
info->dram_cache[i].valid = false;
|
info->dram_cache[address].data = dram_read32(target, address);
|
||||||
info->dram_cache[i].dirty = false;
|
info->dram_cache[address].valid = true;
|
||||||
}
|
}
|
||||||
|
return info->dram_cache[address].data;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -820,9 +850,9 @@ static int register_get(struct reg *reg)
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t value = dram_read32(target, 4);
|
uint32_t value = cache_get32(target, 4);
|
||||||
|
|
||||||
uint32_t exception = dram_read32(target, info->dramsize-1);
|
uint32_t exception = cache_get32(target, info->dramsize-1);
|
||||||
if (exception) {
|
if (exception) {
|
||||||
LOG_ERROR("Got exception 0x%x when reading register %d", exception,
|
LOG_ERROR("Got exception 0x%x when reading register %d", exception,
|
||||||
reg->number);
|
reg->number);
|
||||||
|
@ -1570,6 +1600,8 @@ static int riscv_write_memory(struct target *target, uint32_t address,
|
||||||
// batch.
|
// batch.
|
||||||
LOG_INFO("Retrying memory write starting from 0x%x with more delays", address + size * i);
|
LOG_INFO("Retrying memory write starting from 0x%x with more delays", address + size * i);
|
||||||
|
|
||||||
|
cache_clean(target);
|
||||||
|
|
||||||
if (write_gpr(target, T0, address + size * i) != ERROR_OK) {
|
if (write_gpr(target, T0, address + size * i) != ERROR_OK) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -1586,6 +1618,7 @@ static int riscv_write_memory(struct target *target, uint32_t address,
|
||||||
free(out);
|
free(out);
|
||||||
free(field);
|
free(field);
|
||||||
|
|
||||||
|
cache_clean(target);
|
||||||
return register_write(target, T0, t0);
|
return register_write(target, T0, t0);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
Loading…
Reference in New Issue