63#include "debug/PageTableWalker.hh"
108 return walker->recvTimingResp(pkt);
117 bool walkComplete = senderWalk->
recvPacket(pkt);
123 if (walkerState == senderWalk) {
152 walkerState->
retry();
161 if (
port.sendTimingReq(pkt)) {
176 if (if_name ==
"port")
195 assert(
satp.mode == AddrXlateMode::SV39);
201 unsigned num_squashed = 0;
211 fault =
tlb->checkPermissions(currState->
status, currState->
pmode,
220 DPRINTF(PageTableWalker,
"Squashing table walk for address %#x\n",
221 currState->
req->getVaddr());
226 std::make_shared<UnimpFault>(
"Squashed Inst"),
227 currState->
req, currState->
tc, currState->
mode);
229 tlb->translateTiming(currState->
req, currState->
tc,
247 e =
tlb->lookup(vpn, currState->
satp.asid, currState->
mode,
250 fault =
tlb->checkPermissions(currState->
status,
252 currState->
mode,
e->pte);
287 walker->port.sendAtomic(write);
313 logBytes =
entry.logBytes;
325 PTESv39 pte =
read->getLE<uint64_t>();
327 bool doWrite =
false;
328 bool doTLBInsert =
false;
329 bool doEndWalk =
false;
331 DPRINTF(PageTableWalker,
"Got level%d PTE: %#x\n",
level, pte);
347 if (!pte.v || (!pte.r && pte.w)) {
349 DPRINTF(PageTableWalker,
"PTE invalid, raising PF\n");
354 if (pte.r || pte.x) {
362 if (
level >= 1 && pte.ppn0 != 0) {
364 "PTE has misaligned PPN, raising PF\n");
367 else if (
level == 2 && pte.ppn1 != 0) {
369 "PTE has misaligned PPN, raising PF\n");
374 "SVNAPOT PTE has wrong encoding, \
409 "#0 leaf node at level %d, with vpn %#x\n",
415 assert(!(pte.n) ||
level == 0);
431 walker->pagewalkerstats.num_2mb_walks++;
435 walker->pagewalkerstats.num_64kb_walks++;
437 walker->pagewalkerstats.num_4kb_walks++;
440 "#1 leaf node at level %d, with vpn %#x\n",
447 DPRINTF(PageTableWalker,
"No leaf PTE found,"
454 nextRead = (pte.ppn <<
PageShift) + (idx *
sizeof(pte));
469 DPRINTF(PageTableWalker,
"Writing level%d PTE to %#x: %#x\n",
472 write->
setLE<uint64_t>(pte);
484 DPRINTF(PageTableWalker,
"Translated %#x -> %#x\n",
493 RequestPtr request = std::make_shared<Request>(
503 "Loading level%d PTE from %#x\n",
level, nextRead);
527 DPRINTF(PageTableWalker,
"Performing table walk for address %#x\n",
vaddr);
528 DPRINTF(PageTableWalker,
"Loading level%d PTE from %#x\n",
level, topAddr);
536 RequestPtr request = std::make_shared<Request>(
537 topAddr,
sizeof(PTESv39), flags,
walker->requestorId);
593 req->setPaddr(paddr);
628 if (!
walker->sendTiming(
this, pkt)) {
640 if (!
walker->sendTiming(
this, write)) {
689 DPRINTF(PageTableWalker,
"Raising page fault.\n");
696 "Completed page walks with 4KB pages"),
698 "Completed page walks with 64KB pages"),
700 "Completed page walks with 2MB pages")
virtual bool squashed() const
This function is used by the page table walker to determine if it should translate the a pending requ...
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode)=0
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Cycles is a wrapper class for representing cycle counts, i.e.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void setLE(T v)
Set the value in the data pointer to v as little endian.
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
void pushSenderState(SenderState *sender_state)
Push a new sender state to the packet and make the current sender state the predecessor of the new on...
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
RequestPtr req
A pointer to the original request.
MemCmd cmd
The command field of the packet.
Ports are used to interface objects to each other.
@ PHYSICAL
The virtual address is also the physical address.
gem5::Flags< FlagsType > Flags
void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
Fault startFunctional(Addr &addr, unsigned &logBytes)
bool recvPacket(PacketPtr pkt)
std::vector< PacketPtr > writes
void setupWalk(Addr vaddr)
Fault stepWalk(PacketPtr &write)
BaseMMU::Translation * translation
Fault pageFault(bool present)
unsigned numInflight() const
void initState(ThreadContext *_tc, BaseMMU::Mode _mode, bool _isTiming=false)
Fault startFunctional(ThreadContext *_tc, Addr &addr, unsigned &logBytes, BaseMMU::Mode mode)
EventFunctionWrapper startWalkWrapperEvent
Event used to call startWalkWrapper.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
bool sendTiming(WalkerState *sendingState, PacketPtr pkt)
bool recvTimingResp(PacketPtr pkt)
std::list< WalkerState * > currStates
Fault start(ThreadContext *_tc, BaseMMU::Translation *translation, const RequestPtr &req, BaseMMU::Mode mode)
ThreadContext is the external interface to all thread state for anything outside of the CPU.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
constexpr uint64_t sext(uint64_t val)
Sign-extend an N-bit value to 64 bits.
void schedule(Event &event, Tick when)
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Addr getVPNFromVAddr(Addr vaddr, Addr mode)
Copyright (c) 2024 Arm Limited All rights reserved.
std::shared_ptr< FaultBase > Fault
std::shared_ptr< Request > RequestPtr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
constexpr decltype(nullptr) NoFault
Declaration of a request, the overall memory request consisting of the parts of the request that are ...
PagewalkerStats(statistics::Group *parent)
statistics::Scalar num_64kb_walks
statistics::Scalar num_4kb_walks
statistics::Scalar num_2mb_walks