aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorScott Johnson <scott.johnson@arilinc.com>2021-02-24 09:14:55 -0800
committerAndrew Waterman <aswaterman@gmail.com>2021-09-08 07:59:02 -0700
commit7ad11c99067b9fc69f7f7beb5d8d19e0857a4770 (patch)
tree812f550cb095317447353468b3c4916728581e36 /riscv
parent8ad9331df2400933a4b2eb23ca0663a33e4f89aa (diff)
downloadspike-7ad11c99067b9fc69f7f7beb5d8d19e0857a4770.zip
spike-7ad11c99067b9fc69f7f7beb5d8d19e0857a4770.tar.gz
spike-7ad11c99067b9fc69f7f7beb5d8d19e0857a4770.tar.bz2
Move homogeneity detection into pmpaddr_csr_t
Diffstat (limited to 'riscv')
-rw-r--r--riscv/csrs.cc24
-rw-r--r--riscv/csrs.h3
-rw-r--r--riscv/mmu.cc25
3 files changed, 30 insertions, 22 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc
index 8ac71f0..62f207e 100644
--- a/riscv/csrs.cc
+++ b/riscv/csrs.cc
@@ -156,6 +156,30 @@ bool pmpaddr_csr_t::match4(reg_t addr) const noexcept {
}
+bool pmpaddr_csr_t::subset_match(reg_t addr, reg_t len) const noexcept {
+ if ((addr | len) & (len - 1))
+ abort();
+ state_t* const state = proc->get_state();
+ reg_t base = tor_base_paddr();
+ reg_t tor = tor_paddr();
+ uint8_t cfg = state->pmpcfg[pmpidx];
+
+ if ((cfg & PMP_A) == 0) return false;
+
+ bool is_tor = (cfg & PMP_A) == PMP_TOR;
+ bool begins_after_lower = addr >= base;
+ bool begins_after_upper = addr >= tor;
+ bool ends_before_lower = (addr & -len) < (base & -len);
+ bool ends_before_upper = (addr & -len) < (tor & -len);
+ bool tor_homogeneous = ends_before_lower || begins_after_upper ||
+ (begins_after_lower && ends_before_upper);
+
+ bool mask_homogeneous = ~(napot_mask() << 1) & len;
+ bool napot_homogeneous = mask_homogeneous || ((addr ^ tor) / len) != 0;
+
+ return !(is_tor ? tor_homogeneous : napot_homogeneous);
+}
+
// implement class pmpcfg_csr_t
pmpcfg_csr_t::pmpcfg_csr_t(processor_t* const proc, const reg_t addr):
logged_csr_t(proc, addr) {
diff --git a/riscv/csrs.h b/riscv/csrs.h
index 306553c..961630b 100644
--- a/riscv/csrs.h
+++ b/riscv/csrs.h
@@ -86,6 +86,9 @@ class pmpaddr_csr_t: public logged_csr_t {
// Does a 4-byte access at the specified address match this PMP entry?
bool match4(reg_t addr) const noexcept;
+ // Does the specified range match only a proper subset of this page?
+ bool subset_match(reg_t addr, reg_t len) const noexcept;
+
protected:
virtual bool unlogged_write(const reg_t val) noexcept override;
private:
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 6d1299b..480b77e 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -256,28 +256,9 @@ reg_t mmu_t::pmp_homogeneous(reg_t addr, reg_t len)
if (!proc)
return true;
- for (size_t i = 0; i < proc->n_pmp; i++) {
- reg_t base = proc->state.pmpaddr[i]->tor_base_paddr();
- reg_t tor = proc->state.pmpaddr[i]->tor_paddr();
- uint8_t cfg = proc->state.pmpcfg[i];
-
- if (cfg & PMP_A) {
- bool is_tor = (cfg & PMP_A) == PMP_TOR;
-
- bool begins_after_lower = addr >= base;
- bool begins_after_upper = addr >= tor;
- bool ends_before_lower = (addr & -len) < (base & -len);
- bool ends_before_upper = (addr & -len) < (tor & -len);
- bool tor_homogeneous = ends_before_lower || begins_after_upper ||
- (begins_after_lower && ends_before_upper);
-
- bool mask_homogeneous = ~(proc->state.pmpaddr[i]->napot_mask() << 1) & len;
- bool napot_homogeneous = mask_homogeneous || ((addr ^ tor) / len) != 0;
-
- if (!(is_tor ? tor_homogeneous : napot_homogeneous))
- return false;
- }
- }
+ for (size_t i = 0; i < proc->n_pmp; i++)
+ if (proc->state.pmpaddr[i]->subset_match(addr, len))
+ return false;
return true;
}