aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsoberl@nvidia.com <soberl@nvidia.com>2022-05-03 19:56:01 -0700
committersoberl@nvidia.com <soberl@nvidia.com>2022-05-04 18:26:25 -0700
commitb0fdd88d26ef4b20023e1d2a79cfcb1e9df047de (patch)
tree4edaa076b11e3138799d5e4be12cc35a5f18f696
parent115a9b3dc21aa001275ce898bc5bc73e43fccab5 (diff)
downloadriscv-isa-sim-b0fdd88d26ef4b20023e1d2a79cfcb1e9df047de.zip
riscv-isa-sim-b0fdd88d26ef4b20023e1d2a79cfcb1e9df047de.tar.gz
riscv-isa-sim-b0fdd88d26ef4b20023e1d2a79cfcb1e9df047de.tar.bz2
Update pmpaddr_csr_t::access_ok() for ePMP on matching regions
-rw-r--r--riscv/csrs.cc36
1 files changed, 31 insertions, 5 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc
index 1e9b544..8366d8a 100644
--- a/riscv/csrs.cc
+++ b/riscv/csrs.cc
@@ -192,11 +192,37 @@ bool pmpaddr_csr_t::subset_match(reg_t addr, reg_t len) const noexcept {
bool pmpaddr_csr_t::access_ok(access_type type, reg_t mode) const noexcept {
- return
- (mode == PRV_M && !(cfg & PMP_L)) ||
- (type == LOAD && (cfg & PMP_R)) ||
- (type == STORE && (cfg & PMP_W)) ||
- (type == FETCH && (cfg & PMP_X));
+ const bool cfgx = cfg & PMP_X;
+ const bool cfgw = cfg & PMP_W;
+ const bool cfgr = cfg & PMP_R;
+ const bool cfgl = cfg & PMP_L;
+
+ const bool prvm = mode == PRV_M;
+
+ const bool typer = type == LOAD;
+ const bool typex = type == FETCH;
+ const bool typew = type == STORE;
+ const bool normal_rwx = (typer && cfgr) || (typew && cfgw) || (typex && cfgx);
+ const bool mseccfg_mml = state->mseccfg->get_mml();
+
+ if (mseccfg_mml) {
+ if (cfgx && cfgw && cfgr && cfgl) {
+ // Locked Shared data region: Read only on both M and S/U mode.
+ return typer;
+ } else {
+ const bool mml_shared_region = !cfgr && cfgw;
+ const bool mml_chk_normal = (prvm == cfgl) && normal_rwx;
+ const bool mml_chk_shared =
+ (!cfgl && cfgx && (typer || typew)) ||
+ (!cfgl && !cfgx && (typer || (typew && prvm))) ||
+ (cfgl && typex) ||
+ (cfgl && typer && cfgx && prvm);
+ return mml_shared_region ? mml_chk_shared : mml_chk_normal;
+ }
+ } else {
+ const bool m_bypass = (prvm && !cfgl);
+ return m_bypass || normal_rwx;
+ }
}