aboutsummaryrefslogtreecommitdiff
path: root/riscv/mmu.h
diff options
context:
space:
mode:
authorJohn Ingalls <43973001+johningalls-sifive@users.noreply.github.com>2019-12-16 15:55:39 -0800
committerAndrew Waterman <andrew@sifive.com>2019-12-16 15:55:39 -0800
commit363c76a8947a476d13f270dacff00430ca7c460c (patch)
tree28a18e7a01497058d51de6e9c718006c09607c7d /riscv/mmu.h
parente3cc8b69d101921a836ca76f67b6bb032ecc3d11 (diff)
downloadriscv-isa-sim-363c76a8947a476d13f270dacff00430ca7c460c.zip
riscv-isa-sim-363c76a8947a476d13f270dacff00430ca7c460c.tar.gz
riscv-isa-sim-363c76a8947a476d13f270dacff00430ca7c460c.tar.bz2
extend the commit and memory writes log feature with memory reads (#370)
Diffstat (limited to 'riscv/mmu.h')
-rw-r--r--riscv/mmu.h27
1 files changed, 21 insertions, 6 deletions
diff --git a/riscv/mmu.h b/riscv/mmu.h
index ebacc96..c089ea1 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -80,14 +80,26 @@ public:
#endif
}
+#ifndef RISCV_ENABLE_COMMITLOG
+# define READ_MEM(addr, size) ({})
+#else
+# define READ_MEM(addr, size) ({ \
+ proc->state.log_mem_read.addr = addr; \
+ proc->state.log_mem_read.size = size; \
+ })
+#endif
+
// template for functions that load an aligned value from memory
#define load_func(type) \
inline type##_t load_##type(reg_t addr) { \
if (unlikely(addr & (sizeof(type##_t)-1))) \
return misaligned_load(addr, sizeof(type##_t)); \
reg_t vpn = addr >> PGSHIFT; \
- if (likely(tlb_load_tag[vpn % TLB_ENTRIES] == vpn)) \
+ size_t size = sizeof(type##_t); \
+ if (likely(tlb_load_tag[vpn % TLB_ENTRIES] == vpn)) { \
+ if (proc) READ_MEM(addr, size); \
return from_le(*(type##_t*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr)); \
+ } \
if (unlikely(tlb_load_tag[vpn % TLB_ENTRIES] == (vpn | TLB_CHECK_TRIGGERS))) { \
type##_t data = from_le(*(type##_t*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr)); \
if (!matched_trigger) { \
@@ -95,10 +107,12 @@ public:
if (matched_trigger) \
throw *matched_trigger; \
} \
+ if (proc) READ_MEM(addr, size); \
return data; \
} \
type##_t res; \
load_slow_path(addr, sizeof(type##_t), (uint8_t*)&res); \
+ if (proc) READ_MEM(addr, size); \
return from_le(res); \
}
@@ -130,24 +144,25 @@ public:
if (unlikely(addr & (sizeof(type##_t)-1))) \
return misaligned_store(addr, val, sizeof(type##_t)); \
reg_t vpn = addr >> PGSHIFT; \
- if (likely(tlb_store_tag[vpn % TLB_ENTRIES] == vpn)) \
+ size_t size = sizeof(type##_t); \
+ if (likely(tlb_store_tag[vpn % TLB_ENTRIES] == vpn)) { \
+ if (proc) WRITE_MEM(addr, val, size); \
*(type##_t*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr) = to_le(val); \
+ } \
else if (unlikely(tlb_store_tag[vpn % TLB_ENTRIES] == (vpn | TLB_CHECK_TRIGGERS))) { \
if (!matched_trigger) { \
matched_trigger = trigger_exception(OPERATION_STORE, addr, val); \
if (matched_trigger) \
throw *matched_trigger; \
} \
+ if (proc) WRITE_MEM(addr, val, size); \
*(type##_t*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr) = to_le(val); \
} \
else { \
type##_t le_val = to_le(val); \
+ if (proc) WRITE_MEM(addr, val, size); \
store_slow_path(addr, sizeof(type##_t), (const uint8_t*)&le_val); \
} \
- if (proc) { \
- size_t size = sizeof(type##_t); \
- WRITE_MEM(addr, val, size); \
- } \
}
// template for functions that perform an atomic memory operation