diff options
author | Scott Johnson <scott.johnson@arilinc.com> | 2021-02-24 09:14:55 -0800 |
---|---|---|
committer | Andrew Waterman <aswaterman@gmail.com> | 2021-09-08 07:59:02 -0700 |
commit | 7ad11c99067b9fc69f7f7beb5d8d19e0857a4770 (patch) | |
tree | 812f550cb095317447353468b3c4916728581e36 /riscv | |
parent | 8ad9331df2400933a4b2eb23ca0663a33e4f89aa (diff) | |
download | spike-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.cc | 24 | ||||
-rw-r--r-- | riscv/csrs.h | 3 | ||||
-rw-r--r-- | riscv/mmu.cc | 25 |
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; } |