Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt access on every byte of an unaligned access #23

Open
wants to merge 1 commit into
base: ibex_cosim
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions riscv/mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,25 @@ class mmu_t
{
#ifdef RISCV_ENABLE_MISALIGNED
reg_t res = 0;
for (size_t i = 0; i < size; i++)
res += (reg_t)load_uint8(addr + (target_big_endian? size-1-i : i)) << (i * 8);
bool caught_fault = false;
trap_load_access_fault fault(false, 0, 0, 0);
for (size_t i = 0; i < size; i++) {
try {
res += (reg_t)load_uint8(addr + (target_big_endian? size-1-i : i)) << (i * 8);
} catch (trap_load_access_fault& f) {
if (!caught_fault) {
// Catch first fault seen on unaligned access and proceed with other bytes of the access.
fault = f;
caught_fault = true;
}
}
}

if (caught_fault) {
// Throw a fault if we saw onw
throw fault;
}

return res;
#else
bool gva = ((proc) ? proc->state.v : false) || (RISCV_XLATE_VIRT & xlate_flags);
Expand All @@ -68,8 +85,24 @@ class mmu_t
inline void misaligned_store(reg_t addr, reg_t data, size_t size, uint32_t xlate_flags, bool actually_store=true)
{
#ifdef RISCV_ENABLE_MISALIGNED
for (size_t i = 0; i < size; i++)
store_uint8(addr + (target_big_endian? size-1-i : i), data >> (i * 8), actually_store);
bool caught_fault = false;
trap_store_access_fault fault(false, 0, 0, 0);
for (size_t i = 0; i < size; i++) {
try {
store_uint8(addr + (target_big_endian? size-1-i : i), data >> (i * 8), actually_store);
} catch (trap_store_access_fault& f) {
if (!caught_fault) {
// Catch first fault seen on unaligned access and proceed with other bytes of the access.
fault = f;
caught_fault = true;
}
}
}

if (caught_fault) {
// Throw a fault if we saw onw
throw fault;
}
#else
bool gva = ((proc) ? proc->state.v : false) || (RISCV_XLATE_VIRT & xlate_flags);
throw trap_store_address_misaligned(gva, addr, 0, 0);
Expand Down