|
|
|
@ -249,7 +249,10 @@ bool pmpcfg_csr_t::unlogged_write(const reg_t val) noexcept { |
|
|
|
if (i < proc->n_pmp) { |
|
|
|
const bool locked = (state->pmpaddr[i]->cfg & PMP_L); |
|
|
|
if (rlb || !locked) { |
|
|
|
uint8_t cfg = (val >> (8 * (i - i0))) & (PMP_R | PMP_W | PMP_X | PMP_A | PMP_L); |
|
|
|
uint8_t all_cfg_fields = (PMP_R | PMP_W | PMP_X | PMP_A | |
|
|
|
(proc->extension_enabled(EXT_SMPMPMT) ? PMP_MT : 0) | |
|
|
|
PMP_L); |
|
|
|
uint8_t cfg = (val >> (8 * (i - i0))) & all_cfg_fields; |
|
|
|
// Drop R=0 W=1 when MML = 0
|
|
|
|
// Remove the restriction when MML = 1
|
|
|
|
if (!mml) { |
|
|
|
@ -258,6 +261,9 @@ bool pmpcfg_csr_t::unlogged_write(const reg_t val) noexcept { |
|
|
|
// Disallow A=NA4 when granularity > 4
|
|
|
|
if (proc->lg_pmp_granularity != PMP_SHIFT && (cfg & PMP_A) == PMP_NA4) |
|
|
|
cfg |= PMP_NAPOT; |
|
|
|
// MT value 0x3 is reserved
|
|
|
|
if (get_field(cfg, PMP_MT) == 0x3) |
|
|
|
cfg = set_field(cfg, PMP_MT, 0); |
|
|
|
/*
|
|
|
|
* Adding a rule with executable privileges that either is M-mode-only or a locked Shared-Region |
|
|
|
* is not possible and such pmpcfg writes are ignored, leaving pmpcfg unchanged. |
|
|
|
|