diff options
author | Andrew Waterman <andrew@sifive.com> | 2020-05-10 00:53:27 -0700 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2020-05-10 01:40:19 -0700 |
commit | 9b579a624c03d42490468c0e8a98873940ae510e (patch) | |
tree | 9b8fe64e85bda6fbe90a1df72bea92e6bef429a1 /riscv | |
parent | d5a98bd2d43ffcc70a2d28bc1aeeeee946d644f6 (diff) | |
download | spike-9b579a624c03d42490468c0e8a98873940ae510e.zip spike-9b579a624c03d42490468c0e8a98873940ae510e.tar.gz spike-9b579a624c03d42490468c0e8a98873940ae510e.tar.bz2 |
Implement CSR read/write behavior for coarse-grain PMP
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/processor.cc | 11 | ||||
-rw-r--r-- | riscv/processor.h | 2 |
2 files changed, 11 insertions, 2 deletions
diff --git a/riscv/processor.cc b/riscv/processor.cc index 86f647d..dea0245 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -657,6 +657,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; } } @@ -919,8 +921,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 0e3a86c..7ff79ef 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; |