target/riscv: support log memory access128 for read

Change-Id: I9235150fa00c03a1d75d0b44a7500758daa56e2b
Signed-off-by: Mark Zhuang <mark.zhuang@spacemit.com>
This commit is contained in:
Mark Zhuang 2023-04-04 00:12:51 +08:00
parent 15bb3e23b8
commit aa7344225b
1 changed files with 40 additions and 31 deletions

View File

@ -2541,8 +2541,8 @@ static void log_memory_access128(target_addr_t address, uint64_t value_h,
LOG_DEBUG(fmt, value_h, value_l); LOG_DEBUG(fmt, value_h, value_l);
} }
static void log_memory_access(target_addr_t address, uint64_t value, static void log_memory_access64(target_addr_t address, uint64_t value,
unsigned size_bytes, bool is_read) unsigned int size_bytes, bool is_read)
{ {
if (debug_level < LOG_LVL_DEBUG) if (debug_level < LOG_LVL_DEBUG)
return; return;
@ -2567,23 +2567,35 @@ static void log_memory_access(target_addr_t address, uint64_t value,
} }
LOG_DEBUG(fmt, value); LOG_DEBUG(fmt, value);
} }
static void log_memory_access(target_addr_t address, uint32_t *sbvalue,
unsigned int size_bytes, bool is_read)
{
if (size_bytes == 16) {
uint64_t value_h = ((uint64_t)sbvalue[3] << 32) | sbvalue[2];
uint64_t value_l = ((uint64_t)sbvalue[1] << 32) | sbvalue[0];
log_memory_access128(address, value_h, value_l, is_read);
} else {
uint64_t value = ((uint64_t)sbvalue[1] << 32) | sbvalue[0];
log_memory_access64(address, value, size_bytes, is_read);
}
}
/* Read the relevant sbdata regs depending on size, and put the results into /* Read the relevant sbdata regs depending on size, and put the results into
* buffer. */ * buffer. */
static int read_memory_bus_word(struct target *target, target_addr_t address, static int read_memory_bus_word(struct target *target, target_addr_t address,
uint32_t size, uint8_t *buffer) uint32_t size, uint8_t *buffer)
{ {
uint32_t value;
int result; int result;
uint32_t sbvalue[4] = { 0 };
static int sbdata[4] = { DM_SBDATA0, DM_SBDATA1, DM_SBDATA2, DM_SBDATA3 }; static int sbdata[4] = { DM_SBDATA0, DM_SBDATA1, DM_SBDATA2, DM_SBDATA3 };
assert(size <= 16); assert(size <= 16);
for (int i = (size - 1) / 4; i >= 0; i--) { for (int i = (size - 1) / 4; i >= 0; i--) {
result = dmi_op(target, &value, NULL, DMI_OP_READ, sbdata[i], 0, false, true); result = dmi_op(target, &sbvalue[i], NULL, DMI_OP_READ, sbdata[i], 0, false, true);
if (result != ERROR_OK) if (result != ERROR_OK)
return result; return result;
buf_set_u32(buffer + i * 4, 0, 8 * MIN(size, 4), value); buf_set_u32(buffer + i * 4, 0, 8 * MIN(size, 4), sbvalue[i]);
log_memory_access(address + i * 4, value, MIN(size, 4), true);
} }
log_memory_access(address, sbvalue, size, true);
return ERROR_OK; return ERROR_OK;
} }
@ -2778,11 +2790,12 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
* to get it. */ * to get it. */
static int sbdata[4] = {DM_SBDATA0, DM_SBDATA1, DM_SBDATA2, DM_SBDATA3}; static int sbdata[4] = {DM_SBDATA0, DM_SBDATA1, DM_SBDATA2, DM_SBDATA3};
uint32_t sbvalue[4] = {0};
assert(size <= 16); assert(size <= 16);
target_addr_t next_read = address - 1; target_addr_t next_read = address - 1;
int next_read_j = 0;
for (uint32_t i = (next_address - address) / size; i < count - 1; i++) { for (uint32_t i = (next_address - address) / size; i < count - 1; i++) {
for (int j = (size - 1) / 4; j >= 0; j--) { for (int j = (size - 1) / 4; j >= 0; j--) {
uint32_t value;
unsigned attempt = 0; unsigned attempt = 0;
while (1) { while (1) {
if (attempt++ > 100) { if (attempt++ > 100) {
@ -2791,7 +2804,7 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
return ERROR_FAIL; return ERROR_FAIL;
} }
keep_alive(); keep_alive();
dmi_status_t status = dmi_scan(target, NULL, &value, dmi_status_t status = dmi_scan(target, NULL, &sbvalue[next_read_j],
DMI_OP_READ, sbdata[j], 0, false); DMI_OP_READ, sbdata[j], 0, false);
if (status == DMI_STATUS_BUSY) if (status == DMI_STATUS_BUSY)
increase_dmi_busy_delay(target); increase_dmi_busy_delay(target);
@ -2801,16 +2814,19 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
return ERROR_FAIL; return ERROR_FAIL;
} }
if (next_read != address - 1) { if (next_read != address - 1) {
buf_set_u32(buffer + next_read - address, 0, 8 * MIN(size, 4), value); buf_set_u32(buffer + next_read - address, 0, 8 * MIN(size, 4), sbvalue[next_read_j]);
log_memory_access(next_read, value, MIN(size, 4), true); if (next_read_j == 0) {
log_memory_access(next_read, sbvalue, size, true);
memset(sbvalue, 0, size);
}
} }
next_read = address + i * size + j * 4; next_read_j = j;
next_read = address + i * size + next_read_j * 4;
} }
} }
uint32_t sbcs_read = 0; uint32_t sbcs_read = 0;
if (count > 1) { if (count > 1) {
uint32_t value;
unsigned attempt = 0; unsigned attempt = 0;
while (1) { while (1) {
if (attempt++ > 100) { if (attempt++ > 100) {
@ -2818,7 +2834,7 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
next_read); next_read);
return ERROR_FAIL; return ERROR_FAIL;
} }
dmi_status_t status = dmi_scan(target, NULL, &value, DMI_OP_NOP, 0, 0, false); dmi_status_t status = dmi_scan(target, NULL, &sbvalue[0], DMI_OP_NOP, 0, 0, false);
if (status == DMI_STATUS_BUSY) if (status == DMI_STATUS_BUSY)
increase_dmi_busy_delay(target); increase_dmi_busy_delay(target);
else if (status == DMI_STATUS_SUCCESS) else if (status == DMI_STATUS_SUCCESS)
@ -2826,8 +2842,8 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
else else
return ERROR_FAIL; return ERROR_FAIL;
} }
buf_set_u32(buffer + next_read - address, 0, 8 * MIN(size, 4), value); buf_set_u32(buffer + next_read - address, 0, 8 * MIN(size, 4), sbvalue[0]);
log_memory_access(next_read, value, MIN(size, 4), true); log_memory_access(next_read, sbvalue, size, true);
/* "Writes to sbcs while sbbusy is high result in undefined behavior. /* "Writes to sbcs while sbbusy is high result in undefined behavior.
* A debugger must not write to sbcs until it reads sbbusy as 0." */ * A debugger must not write to sbcs until it reads sbbusy as 0." */
@ -3196,7 +3212,7 @@ static int read_memory_progbuf_inner(struct target *target, target_addr_t addres
if (register_read_direct(target, &value, GDB_REGNO_S1) != ERROR_OK) if (register_read_direct(target, &value, GDB_REGNO_S1) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
buf_set_u64(buffer, 0, 8 * size, value); buf_set_u64(buffer, 0, 8 * size, value);
log_memory_access(address, value, size, true); log_memory_access64(address, value, size, true);
return ERROR_OK; return ERROR_OK;
} }
@ -3298,7 +3314,7 @@ static int read_memory_progbuf_inner(struct target *target, target_addr_t addres
uint64_t value64 = (((uint64_t)dmi_data1) << 32) | dmi_data0; uint64_t value64 = (((uint64_t)dmi_data1) << 32) | dmi_data0;
buf_set_u64(buffer + (next_index - 2) * size, 0, 8 * size, value64); buf_set_u64(buffer + (next_index - 2) * size, 0, 8 * size, value64);
log_memory_access(address + (next_index - 2) * size, value64, size, true); log_memory_access64(address + (next_index - 2) * size, value64, size, true);
/* Restore the command, and execute it. /* Restore the command, and execute it.
* Now DM_DATA0 contains the next value just as it would if no * Now DM_DATA0 contains the next value just as it would if no
@ -3364,7 +3380,7 @@ static int read_memory_progbuf_inner(struct target *target, target_addr_t addres
} }
riscv_addr_t offset = j * size; riscv_addr_t offset = j * size;
buf_set_u64(buffer + offset, 0, 8 * size, value); buf_set_u64(buffer + offset, 0, 8 * size, value);
log_memory_access(address + j * increment, value, size, true); log_memory_access64(address + j * increment, value, size, true);
} }
index = next_index; index = next_index;
@ -3383,7 +3399,7 @@ static int read_memory_progbuf_inner(struct target *target, target_addr_t addres
return ERROR_FAIL; return ERROR_FAIL;
uint64_t value64 = (((uint64_t)dmi_data1) << 32) | dmi_data0; uint64_t value64 = (((uint64_t)dmi_data1) << 32) | dmi_data0;
buf_set_u64(buffer + size * (count - 2), 0, 8 * size, value64); buf_set_u64(buffer + size * (count - 2), 0, 8 * size, value64);
log_memory_access(address + size * (count - 2), value64, size, true); log_memory_access64(address + size * (count - 2), value64, size, true);
} }
/* Read the last word. */ /* Read the last word. */
@ -3391,8 +3407,8 @@ static int read_memory_progbuf_inner(struct target *target, target_addr_t addres
result = register_read_direct(target, &value, GDB_REGNO_S1); result = register_read_direct(target, &value, GDB_REGNO_S1);
if (result != ERROR_OK) if (result != ERROR_OK)
goto error; goto error;
buf_set_u64(buffer + size * (count-1), 0, 8 * size, value); buf_set_u64(buffer + size * (count - 1), 0, 8 * size, value);
log_memory_access(address + size * (count-1), value, size, true); log_memory_access64(address + size * (count - 1), value, size, true);
return ERROR_OK; return ERROR_OK;
@ -3460,7 +3476,7 @@ static int read_memory_progbuf_one(struct target *target, target_addr_t address,
if (register_read_direct(target, &value, GDB_REGNO_S0) != ERROR_OK) if (register_read_direct(target, &value, GDB_REGNO_S0) != ERROR_OK)
goto restore_mstatus; goto restore_mstatus;
buf_set_u64(buffer, 0, 8 * size, value); buf_set_u64(buffer, 0, 8 * size, value);
log_memory_access(address, value, size, true); log_memory_access64(address, value, size, true);
result = ERROR_OK; result = ERROR_OK;
restore_mstatus: restore_mstatus:
@ -3769,14 +3785,7 @@ static int write_memory_bus_v1(struct target *target, target_addr_t address,
riscv_batch_add_dmi_write(batch, DM_SBDATA0, sbvalue[0], false); riscv_batch_add_dmi_write(batch, DM_SBDATA0, sbvalue[0], false);
if (size == 16) { log_memory_access(address + i * size, sbvalue, size, false);
uint64_t value_h = (((uint64_t) sbvalue[3]) << 32) | sbvalue[2];
uint64_t value_l = (((uint64_t) sbvalue[1]) << 32) | sbvalue[0];
log_memory_access128(address + i * size, value_h, value_l, false);
} else {
uint64_t value = (((uint64_t) sbvalue[1]) << 32) | sbvalue[0];
log_memory_access(address + i * size, value, size, false);
}
next_address += size; next_address += size;
} }
@ -3943,7 +3952,7 @@ static int write_memory_progbuf(struct target *target, target_addr_t address,
uint64_t value = buf_get_u64(t_buffer, 0, 8 * size); uint64_t value = buf_get_u64(t_buffer, 0, 8 * size);
log_memory_access(cur_addr, value, size, false); log_memory_access64(cur_addr, value, size, false);
cur_addr += size; cur_addr += size;
if (setup_needed) { if (setup_needed) {