Go to the documentation of this file.
62 #include "debug/PageTableWalker.hh"
116 bool walkComplete = senderWalk->
recvPacket(pkt);
122 if (walkerState == senderWalk) {
141 walker->recvReqRetry();
151 walkerState->
retry();
175 if (if_name ==
"port")
185 assert(state == Ready);
192 pmode = walker->tlb->getMemPriv(tc,
mode);
194 assert(satp.mode == AddrXlateMode::SV39);
200 unsigned num_squashed = 0;
207 DPRINTF(PageTableWalker,
"Squashing table walk for address %#x\n",
208 currState->
req->getVaddr());
212 std::make_shared<UnimpFault>(
"Squashed Inst"),
213 currState->
req, currState->
tc, currState->
mode);
240 setupWalk(req->getVaddr());
248 walker->port.sendAtomic(read);
250 fault = stepWalk(write);
251 assert(fault ==
NoFault || read == NULL);
255 walker->port.sendAtomic(write);
272 walker->port.sendFunctional(read);
276 fault = stepWalk(write);
277 assert(fault ==
NoFault || read == NULL);
281 logBytes = entry.logBytes;
290 assert(state != Ready && state != Waiting);
293 PTESv39 pte = read->
getLE<uint64_t>();
295 bool doWrite =
false;
296 bool doTLBInsert =
false;
297 bool doEndWalk =
false;
299 DPRINTF(PageTableWalker,
"Got level%d PTE: %#x\n",
level, pte);
304 walker->pma->check(read->req);
307 fault = walker->pmp->pmpCheck(read->req,
mode,
312 if (!pte.v || (!pte.r && pte.w)) {
314 DPRINTF(PageTableWalker,
"PTE invalid, raising PF\n");
315 fault = pageFault(pte.v);
319 if (pte.r || pte.x) {
322 fault = walker->tlb->checkPermissions(
status, pmode,
323 entry.vaddr,
mode, pte);
327 if (
level >= 1 && pte.ppn0 != 0) {
329 "PTE has misaligned PPN, raising PF\n");
330 fault = pageFault(
true);
332 else if (
level == 2 && pte.ppn1 != 0) {
334 "PTE has misaligned PPN, raising PF\n");
335 fault = pageFault(
true);
356 walker->pma->check(read->req);
358 fault = walker->pmp->pmpCheck(read->req,
359 mode, pmode, tc, entry.vaddr);
367 entry.paddr = pte.ppn;
368 entry.vaddr &= ~((1 << entry.logBytes) - 1);
381 DPRINTF(PageTableWalker,
"No leaf PTE found,"
384 fault = pageFault(
true);
388 nextRead = (pte.ppn <<
PageShift) + (idx *
sizeof(pte));
389 nextState = Translate;
402 if (!functional && doWrite) {
403 DPRINTF(PageTableWalker,
"Writing level%d PTE to %#x: %#x\n",
406 write->
setLE<uint64_t>(pte);
415 walker->tlb->insert(entry.vaddr, entry);
417 DPRINTF(PageTableWalker,
"Translated %#x -> %#x\n",
419 (entry.vaddr &
mask(entry.logBytes)));
426 RequestPtr request = std::make_shared<Request>(
427 nextRead, oldRead->
getSize(), flags, walker->requestorId);
432 "Loading level%d PTE from %#x\n",
level, nextRead);
453 Addr topAddr = (satp.ppn <<
PageShift) + (idx *
sizeof(PTESv39));
456 DPRINTF(PageTableWalker,
"Performing table walk for address %#x\n",
vaddr);
457 DPRINTF(PageTableWalker,
"Loading level%d PTE from %#x\n",
level, topAddr);
462 entry.asid = satp.asid;
465 RequestPtr request = std::make_shared<Request>(
466 topAddr,
sizeof(PTESv39), flags, walker->requestorId);
477 assert(state == Waiting);
482 return (inflight == 0);
495 timingFault = stepWalk(write);
497 assert(timingFault ==
NoFault || read == NULL);
499 writes.push_back(write);
505 if (inflight == 0 && read == NULL && writes.size() == 0) {
518 Addr paddr = walker->tlb->translateWithTLB(
vaddr, satp.asid,
mode);
519 req->setPaddr(paddr);
520 walker->pma->check(req);
525 timingFault = walker->pmp->pmpCheck(req,
mode, pmode, tc);
528 translation->finish(timingFault, req, tc,
mode);
531 translation->finish(timingFault, req, tc,
mode);
551 if (!walker->sendTiming(
this, pkt)) {
559 while (writes.size()) {
563 if (!walker->sendTiming(
this, write)) {
565 writes.push_back(write);
612 DPRINTF(PageTableWalker,
"Raising page fault.\n");
613 return walker->tlb->createPagefault(entry.vaddr,
mode);
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
virtual bool squashed() const
This function is used by the page table walker to determine if it should translate the a pending requ...
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
constexpr decltype(nullptr) NoFault
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
void setupWalk(Addr vaddr)
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...
RequestPtr req
A pointer to the original request.
Fault startFunctional(ThreadContext *_tc, Addr &addr, unsigned &logBytes, BaseMMU::Mode mode)
Fault startFunctional(Addr &addr, unsigned &logBytes)
@ PHYSICAL
The virtual address is also the physical address.
void schedule(Event &event, Tick when)
bool recvPacket(PacketPtr pkt)
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Fault start(ThreadContext *_tc, BaseMMU::Translation *translation, const RequestPtr &req, BaseMMU::Mode mode)
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
BaseMMU::Translation * translation
Fault pageFault(bool present)
ThreadContext is the external interface to all thread state for anything outside of the CPU.
std::shared_ptr< FaultBase > Fault
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
ProbePointArg< PacketInfo > Packet
Packet probe point.
std::shared_ptr< Request > RequestPtr
EventFunctionWrapper startWalkWrapperEvent
Event used to call startWalkWrapper.
bool isTimingMode() const
Is the system in timing mode?
MemCmd cmd
The command field of the packet.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
unsigned numInflight() const
void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
Fault stepWalk(PacketPtr &write)
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...
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
Ports are used to interface objects to each other.
bool recvTimingResp(PacketPtr pkt)
bool sendTiming(WalkerState *sendingState, PacketPtr pkt)
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
void setLE(T v)
Set the value in the data pointer to v as little endian.
std::list< WalkerState * > currStates
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode)=0
void initState(ThreadContext *_tc, BaseMMU::Mode _mode, bool _isTiming=false)
bool scheduled() const
Determine if the current event is scheduled.
Generated on Tue Sep 21 2021 12:24:51 for gem5 by doxygen 1.8.17