diff options
author | Gianluca Guida <gianluca@rivosinc.com> | 2023-05-25 13:27:45 +0100 |
---|---|---|
committer | Gianluca Guida <gianluca@rivosinc.com> | 2023-06-19 19:16:15 +0100 |
commit | 4ac7e03dfb7a45d2732fadfe29e1af30ef25bcac (patch) | |
tree | 01d2db9dbe050ec9c0a077d511784a6f95310bfe | |
parent | 07e7626e5692ae6bb5773ddb5493ba838debca86 (diff) | |
download | riscv-isa-sim-4ac7e03dfb7a45d2732fadfe29e1af30ef25bcac.zip riscv-isa-sim-4ac7e03dfb7a45d2732fadfe29e1af30ef25bcac.tar.gz riscv-isa-sim-4ac7e03dfb7a45d2732fadfe29e1af30ef25bcac.tar.bz2 |
mmu: support load/store longer than 64-bits.
-rw-r--r-- | riscv/mmu.cc | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 358ccd3..3f90060 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -242,6 +242,11 @@ void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes, xlate_flags_t load_slow_path_intrapage(len - len_page0, bytes + len_page0, access_info.split_misaligned_access(len_page0)); } + while (len > sizeof(reg_t)) { + check_triggers(triggers::OPERATION_LOAD, addr, access_info.effective_virt, reg_from_bytes(sizeof(reg_t), bytes)); + len -= sizeof(reg_t); + bytes += sizeof(reg_t); + } check_triggers(triggers::OPERATION_LOAD, addr, access_info.effective_virt, reg_from_bytes(len, bytes)); } @@ -275,8 +280,16 @@ void mmu_t::store_slow_path_intrapage(reg_t len, const uint8_t* bytes, mem_acces void mmu_t::store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes, xlate_flags_t xlate_flags, bool actually_store, bool UNUSED require_alignment) { auto access_info = generate_access_info(addr, STORE, xlate_flags); - if (actually_store) - check_triggers(triggers::OPERATION_STORE, addr, access_info.effective_virt, reg_from_bytes(len, bytes)); + if (actually_store) { + reg_t trig_len = len; + const uint8_t* trig_bytes = bytes; + while (trig_len > sizeof(reg_t)) { + check_triggers(triggers::OPERATION_STORE, addr, access_info.effective_virt, reg_from_bytes(sizeof(reg_t), trig_bytes)); + trig_len -= sizeof(reg_t); + trig_bytes += sizeof(reg_t); + } + check_triggers(triggers::OPERATION_STORE, addr, access_info.effective_virt, reg_from_bytes(trig_len, trig_bytes)); + } if (addr & (len - 1)) { bool gva = access_info.effective_virt; |