diff options
author | soberl@nvidia.com <soberl@nvidia.com> | 2022-05-03 19:56:01 -0700 |
---|---|---|
committer | soberl@nvidia.com <soberl@nvidia.com> | 2022-05-04 18:26:25 -0700 |
commit | b0fdd88d26ef4b20023e1d2a79cfcb1e9df047de (patch) | |
tree | 4edaa076b11e3138799d5e4be12cc35a5f18f696 | |
parent | 115a9b3dc21aa001275ce898bc5bc73e43fccab5 (diff) | |
download | riscv-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.cc | 36 |
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; + } } |