Skip to content

Commit 4a1bd80

Browse files
committed
target/riscv: fix cross-page misaligned access when mmu not enabled
When mmu is disabled, simply call the physical read/write function
1 parent 593b377 commit 4a1bd80

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

src/target/riscv/riscv.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3061,23 +3061,17 @@ static int riscv_virt2phys(struct target *target, target_addr_t virtual, target_
30613061
virtual, physical);
30623062
}
30633063

3064-
static int check_access_request(struct target *target, target_addr_t address,
3064+
static int check_virt_memory_access(struct target *target, target_addr_t address,
30653065
uint32_t size, uint32_t count, bool is_write)
30663066
{
30673067
const bool is_misaligned = address % size != 0;
30683068
// TODO: This assumes that size of each page is 4 KiB, which is not necessarily the case.
30693069
const bool crosses_page_boundary = RISCV_PGBASE(address + size * count - 1) != RISCV_PGBASE(address);
30703070
if (is_misaligned && crosses_page_boundary) {
3071-
int mmu_enabled;
3072-
int result = riscv_mmu(target, &mmu_enabled);
3073-
if (result != ERROR_OK)
3074-
return result;
3075-
if (mmu_enabled) {
3076-
LOG_TARGET_ERROR(target, "Mis-aligned memory %s (address=0x%" TARGET_PRIxADDR ", size=%d, count=%d)"
3077-
" would access an element across page boundary. This is not supported.",
3078-
is_write ? "write" : "read", address, size, count);
3079-
return ERROR_FAIL;
3080-
}
3071+
LOG_TARGET_ERROR(target, "Mis-aligned memory %s (address=0x%" TARGET_PRIxADDR ", size=%d, count=%d)"
3072+
" would access an element across page boundary. This is not supported.",
3073+
is_write ? "write" : "read", address, size, count);
3074+
return ERROR_FAIL;
30813075
}
30823076
return ERROR_OK;
30833077
}
@@ -3097,11 +3091,20 @@ static int riscv_read_memory(struct target *target, target_addr_t address,
30973091
return ERROR_OK;
30983092
}
30993093

3100-
int result = check_access_request(target, address, size, count, false);
3094+
int mmu_enabled;
3095+
int result = riscv_mmu(target, &mmu_enabled);
31013096
if (result != ERROR_OK)
31023097
return result;
31033098

31043099
RISCV_INFO(r);
3100+
3101+
if (!mmu_enabled)
3102+
return r->read_memory(target, address, size, count, buffer, size);
3103+
3104+
result = check_virt_memory_access(target, address, size, count, false);
3105+
if (result != ERROR_OK)
3106+
return result;
3107+
31053108
uint32_t current_count = 0;
31063109
while (current_count < count) {
31073110
target_addr_t physical_addr;
@@ -3142,14 +3145,22 @@ static int riscv_write_memory(struct target *target, target_addr_t address,
31423145
return ERROR_OK;
31433146
}
31443147

3145-
int result = check_access_request(target, address, size, count, true);
3148+
int mmu_enabled;
3149+
int result = riscv_mmu(target, &mmu_enabled);
31463150
if (result != ERROR_OK)
31473151
return result;
31483152

31493153
struct target_type *tt = get_target_type(target);
31503154
if (!tt)
31513155
return ERROR_FAIL;
31523156

3157+
if (!mmu_enabled)
3158+
return tt->write_memory(target, address, size, count, buffer);
3159+
3160+
result = check_virt_memory_access(target, address, size, count, true);
3161+
if (result != ERROR_OK)
3162+
return result;
3163+
31533164
uint32_t current_count = 0;
31543165
while (current_count < count) {
31553166
target_addr_t physical_addr;

0 commit comments

Comments
 (0)