aboutsummaryrefslogtreecommitdiff
path: root/riscv/mmu.h
diff options
context:
space:
mode:
authorRyan Buchner <ryan.buchner@arilinc.com>2022-04-12 13:06:10 -0700
committerRyan Buchner <ryan.buchner@arilinc.com>2022-04-13 09:42:57 -0700
commit147ed1bc807360c4c90784f975c24693cdd291d4 (patch)
treec524688b2a1332d51b7057bf83ede0577c48fcec /riscv/mmu.h
parentb1e7493a652b969c3aed96628a347f683dd1af16 (diff)
downloadspike-147ed1bc807360c4c90784f975c24693cdd291d4.zip
spike-147ed1bc807360c4c90784f975c24693cdd291d4.tar.gz
spike-147ed1bc807360c4c90784f975c24693cdd291d4.tar.bz2
Skip storing in store_func if actually_store is false, add a fake store at start of AMO.
This includes skipping store in store_slow_path. Is okay to skip the mmio_store part too, since the access_fault for mmio_failure will be caught on the actual store. The ordering for the mmio_access fault is irrelevant since it will occur after the TW faults, and load faults are converted to store faults. Will catch any faults from the access but won't perform a store. Since store permissions can only be granted if read permissions exist, any store faults will occur before or at the same time as a load fault. Thus this store permissions check is sufficient for properly catching the faults in an Amo access TW.
Diffstat (limited to 'riscv/mmu.h')
-rw-r--r--riscv/mmu.h7
1 files changed, 6 insertions, 1 deletions
diff --git a/riscv/mmu.h b/riscv/mmu.h
index deacbc4..fc6f950 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -153,10 +153,13 @@ public:
reg_t vpn = addr >> PGSHIFT; \
size_t size = sizeof(type##_t); \
if ((xlate_flags) == 0 && likely(tlb_store_tag[vpn % TLB_ENTRIES] == vpn)) { \
+ if (actually_store) { \
if (proc) WRITE_MEM(addr, val, size); \
*(target_endian<type##_t>*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr) = to_target(val); \
+ } \
} \
else if ((xlate_flags) == 0 && unlikely(tlb_store_tag[vpn % TLB_ENTRIES] == (vpn | TLB_CHECK_TRIGGERS))) { \
+ if (actually_store) { \
if (!matched_trigger) { \
matched_trigger = trigger_exception(triggers::OPERATION_STORE, addr, val); \
if (matched_trigger) \
@@ -164,11 +167,12 @@ public:
} \
if (proc) WRITE_MEM(addr, val, size); \
*(target_endian<type##_t>*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr) = to_target(val); \
+ } \
} \
else { \
target_endian<type##_t> target_val = to_target(val); \
store_slow_path(addr, sizeof(type##_t), (const uint8_t*)&target_val, (xlate_flags), actually_store); \
- if (proc) WRITE_MEM(addr, val, size); \
+ if (actually_store && proc) WRITE_MEM(addr, val, size); \
} \
}
@@ -192,6 +196,7 @@ public:
template<typename op> \
type##_t amo_##type(reg_t addr, op f) { \
convert_load_traps_to_store_traps({ \
+ store_##type(addr, 0, false); \
auto lhs = load_##type(addr, true); \
store_##type(addr, f(lhs)); \
return lhs; \