Go to the documentation of this file.
38 #include "debug/PMP.hh"
41 #include "params/PMP.hh"
49 pmpEntries(params.pmp_entries),
65 if (req->hasVaddr()) {
66 DPRINTF(
PMP,
"Checking pmp permissions for va: %#x , pa: %#x\n",
67 req->getVaddr(), req->getPaddr());
70 DPRINTF(
PMP,
"Checking pmp permissions for pa: %#x\n",
82 if (pmp_range.
contains(req->getPaddr()) &&
83 pmp_range.
contains(req->getPaddr() + req->getSize() - 1)) {
90 if ((match_index > -1)
92 uint8_t this_cfg =
pmpTable[match_index].pmpCfg;
97 }
else if ((
mode == BaseMMU::Mode::Read) &&
100 }
else if ((
mode == BaseMMU::Mode::Write) &&
103 }
else if ((
mode == BaseMMU::Mode::Execute) &&
107 if (req->hasVaddr()) {
118 }
else if (req->hasVaddr()) {
136 warn(
"pmp access fault.\n");
137 return std::make_shared<RiscvISA::AddressFault>(
vaddr, code);
144 uint8_t
a = cfg >> 3;
153 DPRINTF(
PMP,
"Can't update pmp entry config %u"
154 " because the index exceed the size of pmp entries %u",
159 DPRINTF(
PMP,
"Update pmp config with %u for pmp entry: %u \n",
160 (
unsigned)this_cfg, pmp_index);
162 DPRINTF(
PMP,
"Update pmp entry config %u failed because it locked\n",
166 pmpTable[pmp_index].pmpCfg = this_cfg;
181 if (pmp_index >= 1) {
182 prevAddr =
pmpTable[pmp_index - 1].rawAddr;
186 uint8_t this_cfg =
pmpTable[pmp_index].pmpCfg;
197 this_range =
AddrRange(prevAddr << 2, (this_addr << 2));
201 this_range =
AddrRange(this_addr << 2, ((this_addr << 2) + 4));
211 pmpTable[pmp_index].pmpAddr = this_range;
239 DPRINTF(
PMP,
"Can't update pmp entry address %u"
240 " because the index exceed the size of pmp entries %u",
245 DPRINTF(
PMP,
"Update pmp addr %#x for pmp entry %u \n",
246 (this_addr << 2), pmp_index);
249 DPRINTF(
PMP,
"Update pmp entry %u failed because the lock bit set\n",
252 }
else if (pmp_index <
pmpTable.size() - 1 &&
255 DPRINTF(
PMP,
"Update pmp entry %u failed because the entry %u lock bit"
256 " set and A field is TOR\n",
257 pmp_index, pmp_index+1);
264 pmpTable[pmp_index].rawAddr = this_addr;
291 uint64_t range = (1ULL << (
t1+3));
This class helps to implement RISCV's physical memory protection (pmp) primitive.
constexpr decltype(nullptr) NoFault
PMP(const Params ¶ms)
bool contains(const Addr &a) const
Determine if the range contains an address.
bool shouldCheckPMP(RiscvISA::PrivilegeMode pmode, ThreadContext *tc)
This function is called during a memory access to determine if the pmp table should be consulted for ...
bool hasLockEntry
variable to keep track of any lock of entry
void pmpUpdateRule(uint32_t pmp_index)
pmpUpdateRule updates the pmp rule for a given pmp entry depending on the value of pmpaddr and pmpcfg...
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
constexpr int ctz64(uint64_t value)
Count trailing zeros in a 64-bit value.
bool pmpUpdateAddr(uint32_t pmp_index, Addr this_addr)
pmpUpdateAddr updates the pmpaddr for a pmp entry and calls pmpUpdateRule to update the rule of corre...
ThreadContext is the external interface to all thread state for anything outside of the CPU.
std::shared_ptr< FaultBase > Fault
int numRules
variable to keep track of active number of rules any time
Fault pmpCheck(const RequestPtr &req, BaseMMU::Mode mode, RiscvISA::PrivilegeMode pmode, ThreadContext *tc, Addr vaddr=0)
pmpCheck checks if a particular memory access is allowed based on the pmp rules.
std::shared_ptr< Request > RequestPtr
void pmpReset()
pmpReset reset when reset signal in trigger from CPU.
Fault createAddrfault(Addr vaddr, BaseMMU::Mode mode)
createAddrfault creates an address fault if the pmp checks fail to pass for a given access.
Abstract superclass for simulation objects.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
const uint8_t PMP_EXEC
pmpcfg address range execute permission mask
bool pmpUpdateCfg(uint32_t pmp_index, uint8_t this_cfg)
pmpUpdateCfg updates the pmpcfg for a pmp entry and calls pmpUpdateRule to update the rule of corresp...
const uint8_t PMP_WRITE
pmpcfg address range write permission mask
AddrRange pmpDecodeNapot(Addr pmpaddr)
This function decodes a pmpaddr register value into an address range when A field of pmpcfg register ...
uint8_t pmpGetAField(uint8_t cfg)
pmpGetAField extracts the A field (address matching mode) from an input pmpcfg register
const uint8_t PMP_LOCK
pmpcfg address range locked mask
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
const uint8_t PMP_READ
pmpcfg address range read permission mask
int pmpEntries
maximum number of entries in the pmp table
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
const uint8_t PMP_A_MASK
pmpcfg A field mask
std::vector< PmpEntry > pmpTable
a table of pmp entries
Generated on Sun Jul 30 2023 01:56:50 for gem5 by doxygen 1.8.17