revert pmp check implementation
This commit is contained in:
parent
f90c48e881
commit
43d7b99905
|
@ -554,37 +554,74 @@ template <typename BASE, features_e FEAT> bool riscv_hart_mu_p<BASE, FEAT>::pmp_
|
||||||
constexpr auto PMP_TOR =0x1U;
|
constexpr auto PMP_TOR =0x1U;
|
||||||
constexpr auto PMP_NA4 =0x2U;
|
constexpr auto PMP_NA4 =0x2U;
|
||||||
constexpr auto PMP_NAPOT =0x3U;
|
constexpr auto PMP_NAPOT =0x3U;
|
||||||
constexpr auto pmp_num_regs = 16;
|
reg_t base = 0;
|
||||||
reg_t tor_base = 0;
|
|
||||||
auto any_active = false;
|
auto any_active = false;
|
||||||
auto lower_addr = addr >>2;
|
for (size_t i = 0; i < 16; i++) {
|
||||||
auto upper_addr = (addr+len-1)>>2;
|
reg_t tor = csr[pmpaddr0+i] << PMP_SHIFT;
|
||||||
for (size_t i = 0; i < pmp_num_regs; i++) {
|
|
||||||
uint8_t cfg = csr[pmpcfg0+(i/4)]>>(i%4);
|
uint8_t cfg = csr[pmpcfg0+(i/4)]>>(i%4);
|
||||||
uint8_t cfg_next = i==(pmp_num_regs-1)? 0 : csr[pmpcfg0+((i+1)/4)]>>((i+1)%4);
|
|
||||||
auto pmpaddr = csr[pmpaddr0+i];
|
|
||||||
if (cfg & PMP_A) {
|
if (cfg & PMP_A) {
|
||||||
any_active=true;
|
any_active=true;
|
||||||
auto is_tor = bit_sub<3, 2>(cfg) == PMP_TOR;
|
auto pmp_a = (cfg & PMP_A) >> 3;
|
||||||
auto is_napot = bit_sub<4, 1>(cfg) && bit_sub<3, 2>(cfg_next)!= PMP_TOR;
|
auto is_tor = pmp_a == PMP_TOR;
|
||||||
if(is_napot) {
|
auto is_na4 = pmp_a == PMP_NA4;
|
||||||
reg_t mask = bit_sub<3, 1>(cfg)?~( pmpaddr & ~(pmpaddr + 1)): 0x3fffffff;
|
|
||||||
auto mpmpaddr = pmpaddr & mask;
|
reg_t mask = (csr[pmpaddr0+i] << 1) | (!is_na4);
|
||||||
if((lower_addr&mask) == mpmpaddr && (upper_addr&mask)==mpmpaddr)
|
mask = ~(mask & ~(mask + 1)) << PMP_SHIFT;
|
||||||
return (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) ||
|
|
||||||
(type == access_type::READ && (cfg & PMP_R)) ||
|
// Check each 4-byte sector of the access
|
||||||
(type == access_type::WRITE && (cfg & PMP_W)) ||
|
auto any_match = false;
|
||||||
(type == access_type::FETCH && (cfg & PMP_X));
|
auto all_match = true;
|
||||||
} else if(is_tor) {
|
for (reg_t offset = 0; offset < len; offset += 1 << PMP_SHIFT) {
|
||||||
if(lower_addr>=tor_base && upper_addr<=pmpaddr)
|
reg_t cur_addr = addr + offset;
|
||||||
return (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) ||
|
auto napot_match = ((cur_addr ^ tor) & mask) == 0;
|
||||||
(type == access_type::READ && (cfg & PMP_R)) ||
|
auto tor_match = base <= cur_addr && cur_addr < tor;
|
||||||
(type == access_type::WRITE && (cfg & PMP_W)) ||
|
auto match = is_tor ? tor_match : napot_match;
|
||||||
(type == access_type::FETCH && (cfg & PMP_X));
|
any_match |= match;
|
||||||
|
all_match &= match;
|
||||||
|
}
|
||||||
|
if (any_match) {
|
||||||
|
// If the PMP matches only a strict subset of the access, fail it
|
||||||
|
if (!all_match)
|
||||||
|
return false;
|
||||||
|
return (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) ||
|
||||||
|
(type == access_type::READ && (cfg & PMP_R)) ||
|
||||||
|
(type == access_type::WRITE && (cfg & PMP_W)) ||
|
||||||
|
(type == access_type::FETCH && (cfg & PMP_X));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tor_base = pmpaddr;
|
base = tor;
|
||||||
}
|
}
|
||||||
|
// constexpr auto pmp_num_regs = 16;
|
||||||
|
// reg_t tor_base = 0;
|
||||||
|
// auto any_active = false;
|
||||||
|
// auto lower_addr = addr >>2;
|
||||||
|
// auto upper_addr = (addr+len-1)>>2;
|
||||||
|
// for (size_t i = 0; i < pmp_num_regs; i++) {
|
||||||
|
// uint8_t cfg = csr[pmpcfg0+(i/4)]>>(i%4);
|
||||||
|
// uint8_t cfg_next = i==(pmp_num_regs-1)? 0 : csr[pmpcfg0+((i+1)/4)]>>((i+1)%4);
|
||||||
|
// auto pmpaddr = csr[pmpaddr0+i];
|
||||||
|
// if (cfg & PMP_A) {
|
||||||
|
// any_active=true;
|
||||||
|
// auto is_tor = bit_sub<3, 2>(cfg) == PMP_TOR;
|
||||||
|
// auto is_napot = bit_sub<4, 1>(cfg) && bit_sub<3, 2>(cfg_next)!= PMP_TOR;
|
||||||
|
// if(is_napot) {
|
||||||
|
// reg_t mask = bit_sub<3, 1>(cfg)?~( pmpaddr & ~(pmpaddr + 1)): 0x3fffffff;
|
||||||
|
// auto mpmpaddr = pmpaddr & mask;
|
||||||
|
// if((lower_addr&mask) == mpmpaddr && (upper_addr&mask)==mpmpaddr)
|
||||||
|
// return (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) ||
|
||||||
|
// (type == access_type::READ && (cfg & PMP_R)) ||
|
||||||
|
// (type == access_type::WRITE && (cfg & PMP_W)) ||
|
||||||
|
// (type == access_type::FETCH && (cfg & PMP_X));
|
||||||
|
// } else if(is_tor) {
|
||||||
|
// if(lower_addr>=tor_base && upper_addr<=pmpaddr)
|
||||||
|
// return (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) ||
|
||||||
|
// (type == access_type::READ && (cfg & PMP_R)) ||
|
||||||
|
// (type == access_type::WRITE && (cfg & PMP_W)) ||
|
||||||
|
// (type == access_type::FETCH && (cfg & PMP_X));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// tor_base = pmpaddr;
|
||||||
|
// }
|
||||||
return !any_active || this->reg.PRIV == PRIV_M;
|
return !any_active || this->reg.PRIV == PRIV_M;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue