aboutsummaryrefslogtreecommitdiff
path: root/riscv/processor.cc
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2018-12-21 13:55:23 -0800
committerAndrew Waterman <andrew@sifive.com>2018-12-21 14:00:25 -0800
commit06bafbf547564f14efac995ab4887d6b0dd9be71 (patch)
treeb2ea9105aefde034f8e71da31a1a83989e54591d /riscv/processor.cc
parentc20d84c6f3f8f38f5624c31078d60d7fb1298eee (diff)
downloadspike-06bafbf547564f14efac995ab4887d6b0dd9be71.zip
spike-06bafbf547564f14efac995ab4887d6b0dd9be71.tar.gz
spike-06bafbf547564f14efac995ab4887d6b0dd9be71.tar.bz2
Reserve the PMP R=0 W=1 combination
This was a post-v1.10 amendment to the privileged spec. https://github.com/riscv/riscv-isa-manual/commit/059f64c941856f249d8a0647e23e150dbdb1f62c
Diffstat (limited to 'riscv/processor.cc')
-rw-r--r--riscv/processor.cc7
1 files changed, 5 insertions, 2 deletions
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 00612f0..3d8ad78 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -350,8 +350,11 @@ void processor_t::set_csr(int which, reg_t val)
if (which >= CSR_PMPCFG0 && which < CSR_PMPCFG0 + state.n_pmp / 4) {
for (size_t i0 = (which - CSR_PMPCFG0) * 4, i = i0; i < i0 + xlen / 8; i++) {
- if (!(state.pmpcfg[i] & PMP_L))
- state.pmpcfg[i] = (val >> (8 * (i - i0))) & (PMP_R | PMP_W | PMP_X | PMP_A | PMP_L);
+ if (!(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
+ state.pmpcfg[i] = cfg;
+ }
}
mmu->flush_tlb();
}