[NFC] target/riscv: refactor riscv_read_memory,riscv_write_memory
Reduce duplicate code
This commit is contained in:
parent
4a1bd80842
commit
92d7a5798d
|
@ -3083,11 +3083,25 @@ static int riscv_read_phys_memory(struct target *target, target_addr_t phys_addr
|
|||
return r->read_memory(target, phys_address, size, count, buffer, size);
|
||||
}
|
||||
|
||||
static int riscv_read_memory(struct target *target, target_addr_t address,
|
||||
uint32_t size, uint32_t count, uint8_t *buffer)
|
||||
static int riscv_write_phys_memory(struct target *target, target_addr_t phys_address,
|
||||
uint32_t size, uint32_t count, const uint8_t *buffer)
|
||||
{
|
||||
struct target_type *tt = get_target_type(target);
|
||||
if (!tt)
|
||||
return ERROR_FAIL;
|
||||
return tt->write_memory(target, phys_address, size, count, buffer);
|
||||
}
|
||||
|
||||
static int riscv_rw_memory(struct target *target, target_addr_t address, uint32_t size,
|
||||
uint32_t count, uint8_t *read_buffer, const uint8_t *write_buffer)
|
||||
{
|
||||
/* Exactly one of the buffers must be set, the other must be NULL */
|
||||
assert(!!read_buffer != !!write_buffer);
|
||||
|
||||
const bool is_write = write_buffer ? true : false;
|
||||
if (count == 0) {
|
||||
LOG_TARGET_WARNING(target, "0-length read from 0x%" TARGET_PRIxADDR, address);
|
||||
LOG_TARGET_WARNING(target, "0-length %s 0x%" TARGET_PRIxADDR,
|
||||
is_write ? "write to" : "read from", address);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
@ -3097,11 +3111,18 @@ static int riscv_read_memory(struct target *target, target_addr_t address,
|
|||
return result;
|
||||
|
||||
RISCV_INFO(r);
|
||||
struct target_type *tt = get_target_type(target);
|
||||
if (!tt)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (!mmu_enabled)
|
||||
return r->read_memory(target, address, size, count, buffer, size);
|
||||
if (!mmu_enabled) {
|
||||
if (is_write)
|
||||
return tt->write_memory(target, address, size, count, write_buffer);
|
||||
else
|
||||
return r->read_memory(target, address, size, count, read_buffer, size);
|
||||
}
|
||||
|
||||
result = check_virt_memory_access(target, address, size, count, false);
|
||||
result = check_virt_memory_access(target, address, size, count, is_write);
|
||||
if (result != ERROR_OK)
|
||||
return result;
|
||||
|
||||
|
@ -3118,7 +3139,10 @@ static int riscv_read_memory(struct target *target, target_addr_t address,
|
|||
* which is 4 KiB. The algorithm can be improved to detect the real page size, and allow to use larger
|
||||
* memory transfers and avoid extra unnecessary virt2phys address translations. */
|
||||
uint32_t chunk_count = MIN(count - current_count, (RISCV_PGSIZE - RISCV_PGOFFSET(address)) / size);
|
||||
result = r->read_memory(target, physical_addr, size, chunk_count, buffer + current_count * size, size);
|
||||
if (is_write)
|
||||
result = tt->write_memory(target, physical_addr, size, chunk_count, write_buffer + current_count * size);
|
||||
else
|
||||
result = r->read_memory(target, physical_addr, size, chunk_count, read_buffer + current_count * size, size);
|
||||
if (result != ERROR_OK)
|
||||
return result;
|
||||
|
||||
|
@ -3128,57 +3152,16 @@ static int riscv_read_memory(struct target *target, target_addr_t address,
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int riscv_write_phys_memory(struct target *target, target_addr_t phys_address,
|
||||
uint32_t size, uint32_t count, const uint8_t *buffer)
|
||||
static int riscv_read_memory(struct target *target, target_addr_t address,
|
||||
uint32_t size, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
struct target_type *tt = get_target_type(target);
|
||||
if (!tt)
|
||||
return ERROR_FAIL;
|
||||
return tt->write_memory(target, phys_address, size, count, buffer);
|
||||
return riscv_rw_memory(target, address, size, count, buffer, NULL);
|
||||
}
|
||||
|
||||
static int riscv_write_memory(struct target *target, target_addr_t address,
|
||||
uint32_t size, uint32_t count, const uint8_t *buffer)
|
||||
{
|
||||
if (count == 0) {
|
||||
LOG_TARGET_WARNING(target, "0-length write to 0x%" TARGET_PRIxADDR, address);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int mmu_enabled;
|
||||
int result = riscv_mmu(target, &mmu_enabled);
|
||||
if (result != ERROR_OK)
|
||||
return result;
|
||||
|
||||
struct target_type *tt = get_target_type(target);
|
||||
if (!tt)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (!mmu_enabled)
|
||||
return tt->write_memory(target, address, size, count, buffer);
|
||||
|
||||
result = check_virt_memory_access(target, address, size, count, true);
|
||||
if (result != ERROR_OK)
|
||||
return result;
|
||||
|
||||
uint32_t current_count = 0;
|
||||
while (current_count < count) {
|
||||
target_addr_t physical_addr;
|
||||
result = target->type->virt2phys(target, address, &physical_addr);
|
||||
if (result != ERROR_OK) {
|
||||
LOG_TARGET_ERROR(target, "Address translation failed.");
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t chunk_count = MIN(count - current_count, (RISCV_PGSIZE - RISCV_PGOFFSET(address)) / size);
|
||||
result = tt->write_memory(target, physical_addr, size, chunk_count, buffer + current_count * size);
|
||||
if (result != ERROR_OK)
|
||||
return result;
|
||||
|
||||
current_count += chunk_count;
|
||||
address += chunk_count * size;
|
||||
}
|
||||
return ERROR_OK;
|
||||
return riscv_rw_memory(target, address, size, count, NULL, buffer);
|
||||
}
|
||||
|
||||
static const char *riscv_get_gdb_arch(const struct target *target)
|
||||
|
|
Loading…
Reference in New Issue