Go to the documentation of this file.
63 #include "debug/PageTableWalker.hh"
117 bool walkComplete = senderWalk->
recvPacket(pkt);
123 if (walkerState == senderWalk) {
142 walker->recvReqRetry();
152 walkerState->
retry();
176 if (if_name ==
"port")
186 assert(
state == Ready);
193 pmode = walker->tlb->getMemPriv(tc,
mode);
195 assert(satp.mode == AddrXlateMode::SV39);
201 unsigned num_squashed = 0;
208 DPRINTF(PageTableWalker,
"Squashing table walk for address %#x\n",
209 currState->
req->getVaddr());
213 std::make_shared<UnimpFault>(
"Squashed Inst"),
214 currState->
req, currState->
tc, currState->
mode);
241 setupWalk(req->getVaddr());
249 walker->port.sendAtomic(read);
251 fault = stepWalk(write);
252 assert(fault ==
NoFault || read == NULL);
256 walker->port.sendAtomic(write);
273 walker->port.sendFunctional(read);
277 fault = stepWalk(write);
278 assert(fault ==
NoFault || read == NULL);
282 logBytes = entry.logBytes;
294 PTESv39 pte = read->
getLE<uint64_t>();
296 bool doWrite =
false;
297 bool doTLBInsert =
false;
298 bool doEndWalk =
false;
300 DPRINTF(PageTableWalker,
"Got level%d PTE: %#x\n",
level, pte);
305 walker->pma->check(read->req);
313 if (!pte.v || (!pte.r && pte.w)) {
315 DPRINTF(PageTableWalker,
"PTE invalid, raising PF\n");
316 fault = pageFault(pte.v);
320 if (pte.r || pte.x) {
323 fault = walker->tlb->checkPermissions(
status, pmode,
324 entry.vaddr,
mode, pte);
328 if (
level >= 1 && pte.ppn0 != 0) {
330 "PTE has misaligned PPN, raising PF\n");
331 fault = pageFault(
true);
333 else if (
level == 2 && pte.ppn1 != 0) {
335 "PTE has misaligned PPN, raising PF\n");
336 fault = pageFault(
true);
357 walker->pma->check(read->req);
359 fault = walker->pmp->pmpCheck(read->req,
368 entry.paddr = pte.ppn;
369 entry.vaddr &= ~((1 << entry.logBytes) - 1);
382 DPRINTF(PageTableWalker,
"No leaf PTE found,"
385 fault = pageFault(
true);
389 nextRead = (pte.ppn <<
PageShift) + (idx *
sizeof(pte));
390 nextState = Translate;
403 if (!functional && doWrite) {
404 DPRINTF(PageTableWalker,
"Writing level%d PTE to %#x: %#x\n",
407 write->
setLE<uint64_t>(pte);
416 walker->tlb->insert(entry.vaddr, entry);
418 DPRINTF(PageTableWalker,
"Translated %#x -> %#x\n",
420 (entry.vaddr &
mask(entry.logBytes)));
427 RequestPtr request = std::make_shared<Request>(
428 nextRead, oldRead->
getSize(),
flags, walker->requestorId);
437 "Loading level%d PTE from %#x\n",
level, nextRead);
458 Addr topAddr = (satp.ppn <<
PageShift) + (idx *
sizeof(PTESv39));
461 DPRINTF(PageTableWalker,
"Performing table walk for address %#x\n",
vaddr);
462 DPRINTF(PageTableWalker,
"Loading level%d PTE from %#x\n",
level, topAddr);
467 entry.asid = satp.asid;
470 RequestPtr request = std::make_shared<Request>(
471 topAddr,
sizeof(PTESv39),
flags, walker->requestorId);
482 assert(
state == Waiting);
487 return (inflight == 0);
500 timingFault = stepWalk(write);
502 assert(timingFault ==
NoFault || read == NULL);
504 writes.push_back(write);
512 if (inflight == 0 && read == NULL && writes.size() == 0) {
525 Addr paddr = walker->tlb->translateWithTLB(
vaddr, satp.asid,
mode);
526 req->setPaddr(paddr);
527 walker->pma->check(req);
532 timingFault = walker->pmp->pmpCheck(req,
mode, pmode, tc);
535 translation->finish(timingFault, req, tc,
mode);
538 translation->finish(timingFault, req, tc,
mode);
558 if (!walker->sendTiming(
this, pkt)) {
566 while (writes.size()) {
570 if (!walker->sendTiming(
this, write)) {
572 writes.push_back(write);
619 DPRINTF(PageTableWalker,
"Raising page fault.\n");
620 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)
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.
@ PHYSICAL
The virtual address is also the physical address.
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 Sun Jul 30 2023 01:56:47 for gem5 by doxygen 1.8.17