aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2020-05-10 00:53:27 -0700
committerChih-Min Chao <chihmin.chao@sifive.com>2020-05-19 19:57:08 -0700
commit0c565c6b9b725b63b6fddbcce786c9d876818547 (patch)
tree0bf39e369b8e92e03b235f420b2dbde8dc848ea6 /riscv
parent65cfc4bca7db24a387fdc8c8f04d77c41617dc82 (diff)
downloadspike-0c565c6b9b725b63b6fddbcce786c9d876818547.zip
spike-0c565c6b9b725b63b6fddbcce786c9d876818547.tar.gz
spike-0c565c6b9b725b63b6fddbcce786c9d876818547.tar.bz2
Implement CSR read/write behavior for coarse-grain PMP
Diffstat (limited to 'riscv')
-rw-r--r--riscv/processor.cc11
-rw-r--r--riscv/processor.h2
2 files changed, 11 insertions, 2 deletions
diff --git a/riscv/processor.cc b/riscv/processor.cc
index b3b53ee..b5ee590 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -705,6 +705,8 @@ void processor_t::set_csr(int which, reg_t val)
if (i < n_pmp && !(state.pmpcfg[i] & PMP_L)) {
uint8_t cfg = (val >> (8 * (i - i0))) & (PMP_R | PMP_W | PMP_X | PMP_A | PMP_L);
cfg &= ~PMP_W | ((cfg & PMP_R) ? PMP_W : 0); // Disallow R=0 W=1
+ if (lg_pmp_granularity != PMP_SHIFT && (cfg & PMP_A) == PMP_NA4)
+ cfg |= PMP_NAPOT; // Disallow A=NA4 when granularity > 4
state.pmpcfg[i] = cfg;
}
}
@@ -967,8 +969,13 @@ reg_t processor_t::get_csr(int which)
if (which >= CSR_MHPMEVENT3 && which <= CSR_MHPMEVENT31)
return 0;
- if (which >= CSR_PMPADDR0 && which < CSR_PMPADDR0 + state.max_pmp)
- return state.pmpaddr[which - CSR_PMPADDR0];
+ if (which >= CSR_PMPADDR0 && which < CSR_PMPADDR0 + state.max_pmp) {
+ reg_t i = which - CSR_PMPADDR0;
+ if ((state.pmpcfg[i] & PMP_A) >= PMP_NAPOT)
+ return state.pmpaddr[i] | (~pmp_tor_mask() >> 1);
+ else
+ return state.pmpaddr[i] & pmp_tor_mask();
+ }
if (which >= CSR_PMPCFG0 && which < CSR_PMPCFG0 + state.max_pmp / 4) {
require((which & ((xlen / 32) - 1)) == 0);
diff --git a/riscv/processor.h b/riscv/processor.h
index 52dbf3e..529a4f6 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -422,6 +422,8 @@ private:
void disasm(insn_t insn); // disassemble and print an instruction
int paddr_bits();
+ reg_t pmp_tor_mask() { return -(reg_t(1) << (lg_pmp_granularity - PMP_SHIFT)); }
+
void enter_debug_mode(uint8_t cause);
friend class mmu_t;