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);
195 unsigned num_squashed = 0;
202 DPRINTF(PageTableWalker,
"Squashing table walk for address %#x\n",
203 currState->
req->getVaddr());
207 std::make_shared<UnimpFault>(
"Squashed Inst"),
208 currState->
req, currState->
tc, currState->
mode);
235 setupWalk(req->getVaddr());
243 walker->port.sendAtomic(read);
245 fault = stepWalk(write);
246 assert(fault ==
NoFault || read == NULL);
250 walker->port.sendAtomic(write);
267 walker->port.sendFunctional(read);
271 fault = stepWalk(write);
272 assert(fault ==
NoFault || read == NULL);
276 logBytes = entry.logBytes;
290 pte = read->getLE<uint64_t>();
292 pte = read->getLE<uint32_t>();
293 VAddr
vaddr = entry.vaddr;
294 bool uncacheable = pte.pcd;
296 bool doWrite =
false;
297 bool doTLBInsert =
false;
298 bool doEndWalk =
false;
302 DPRINTF(PageTableWalker,
"Got long mode PML4 entry %#016x.\n", pte);
303 nextRead =
mbits(pte, 51, 12) +
vaddr.longl3 * dataSize;
306 entry.writable = pte.w;
308 if (badNX || !pte.p) {
310 fault = pageFault(pte.p);
313 entry.noExec = pte.nx;
317 DPRINTF(PageTableWalker,
"Got long mode PDP entry %#016x.\n", pte);
318 nextRead =
mbits(pte, 51, 12) +
vaddr.longl2 * dataSize;
321 entry.writable = entry.writable && pte.w;
322 entry.user = entry.user && pte.u;
323 if (badNX || !pte.p) {
325 fault = pageFault(pte.p);
331 DPRINTF(PageTableWalker,
"Got long mode PD entry %#016x.\n", pte);
334 entry.writable = entry.writable && pte.w;
335 entry.user = entry.user && pte.u;
336 if (badNX || !pte.p) {
338 fault = pageFault(pte.p);
344 nextRead =
mbits(pte, 51, 12) +
vaddr.longl1 * dataSize;
350 entry.paddr =
mbits(pte, 51, 21);
351 entry.uncacheable = uncacheable;
352 entry.global = pte.g;
353 entry.patBit =
bits(pte, 12);
354 entry.vaddr =
mbits(entry.vaddr, 63, 21);
360 DPRINTF(PageTableWalker,
"Got long mode PTE entry %#016x.\n", pte);
363 entry.writable = entry.writable && pte.w;
364 entry.user = entry.user && pte.u;
365 if (badNX || !pte.p) {
367 fault = pageFault(pte.p);
370 entry.paddr =
mbits(pte, 51, 12);
371 entry.uncacheable = uncacheable;
372 entry.global = pte.g;
373 entry.patBit =
bits(pte, 12);
374 entry.vaddr =
mbits(entry.vaddr, 63, 12);
380 "Got legacy mode PAE PDP entry %#08x.\n", pte);
381 nextRead =
mbits(pte, 51, 12) +
vaddr.pael2 * dataSize;
384 fault = pageFault(pte.p);
390 DPRINTF(PageTableWalker,
"Got legacy mode PAE PD entry %#08x.\n", pte);
393 entry.writable = pte.w;
395 if (badNX || !pte.p) {
397 fault = pageFault(pte.p);
403 nextRead =
mbits(pte, 51, 12) +
vaddr.pael1 * dataSize;
409 entry.paddr =
mbits(pte, 51, 21);
410 entry.uncacheable = uncacheable;
411 entry.global = pte.g;
412 entry.patBit =
bits(pte, 12);
413 entry.vaddr =
mbits(entry.vaddr, 63, 21);
420 "Got legacy mode PAE PTE entry %#08x.\n", pte);
423 entry.writable = entry.writable && pte.w;
424 entry.user = entry.user && pte.u;
425 if (badNX || !pte.p) {
427 fault = pageFault(pte.p);
430 entry.paddr =
mbits(pte, 51, 12);
431 entry.uncacheable = uncacheable;
432 entry.global = pte.g;
433 entry.patBit =
bits(pte, 7);
434 entry.vaddr =
mbits(entry.vaddr, 63, 12);
439 DPRINTF(PageTableWalker,
"Got legacy mode PSE PD entry %#08x.\n", pte);
442 entry.writable = pte.w;
446 fault = pageFault(pte.p);
452 nextRead =
mbits(pte, 31, 12) +
vaddr.norml2 * dataSize;
458 entry.paddr =
bits(pte, 20, 13) << 32 |
mbits(pte, 31, 22);
459 entry.uncacheable = uncacheable;
460 entry.global = pte.g;
461 entry.patBit =
bits(pte, 12);
462 entry.vaddr =
mbits(entry.vaddr, 63, 22);
468 DPRINTF(PageTableWalker,
"Got legacy mode PD entry %#08x.\n", pte);
471 entry.writable = pte.w;
475 fault = pageFault(pte.p);
480 nextRead =
mbits(pte, 31, 12) +
vaddr.norml1 * dataSize;
484 DPRINTF(PageTableWalker,
"Got legacy mode PTE entry %#08x.\n", pte);
487 entry.writable = pte.w;
491 fault = pageFault(pte.p);
494 entry.paddr =
mbits(pte, 31, 12);
495 entry.uncacheable = uncacheable;
496 entry.global = pte.g;
497 entry.patBit =
bits(pte, 7);
498 entry.vaddr =
mbits(entry.vaddr, 31, 12);
503 panic(
"Unknown page table walker state %d!\n");
508 walker->tlb->insert(entry.vaddr, entry);
515 RequestPtr request = std::make_shared<Request>(
516 nextRead, oldRead->
getSize(),
flags, walker->requestorId);
524 write->
setLE<uint64_t>(pte);
526 write->
setLE<uint32_t>(pte);
556 topAddr = (cr3.longPdtb << 12) +
addr.longl4 * dataSize;
564 topAddr = (cr3.paePdtb << 5) +
addr.pael3 * dataSize;
568 topAddr = (cr3.pdtb << 12) +
addr.norml2 * dataSize;
587 RequestPtr request = std::make_shared<Request>(
588 topAddr, dataSize,
flags, walker->requestorId);
599 assert(
state == Waiting);
604 return (inflight == 0);
617 timingFault = stepWalk(write);
619 assert(timingFault ==
NoFault || read == NULL);
621 writes.push_back(write);
627 if (inflight == 0 && read == NULL && writes.size() == 0) {
638 bool delayedResponse;
639 Fault fault = walker->tlb->translate(req, tc, NULL,
mode,
640 delayedResponse,
true);
641 assert(!delayedResponse);
643 translation->finish(fault, req, tc,
mode);
646 translation->finish(timingFault, req, tc,
mode);
666 if (!walker->sendTiming(
this, pkt)) {
674 while (writes.size()) {
678 if (!walker->sendTiming(
this, write)) {
680 writes.push_back(write);
727 DPRINTF(PageTableWalker,
"Raising page fault.\n");
731 return std::make_shared<PageFault>(entry.vaddr,
present,
mode,
732 m5reg.cpl == 3,
false);
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.
BaseMMU::Translation * translation
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.
@ PHYSICAL
The virtual address is also the physical address.
bool recvTimingResp(PacketPtr pkt)
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Fault startFunctional(Addr &addr, unsigned &logBytes)
Fault start(ThreadContext *_tc, BaseMMU::Translation *translation, const RequestPtr &req, BaseMMU::Mode mode)
void schedule(Event &event, Tick when)
std::list< WalkerState * > currStates
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
void setupWalk(Addr vaddr)
bool recvPacket(PacketPtr pkt)
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
@ UNCACHEABLE
The request is to an uncacheable address.
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....
bool sendTiming(WalkerState *sendingState, PacketPtr pkt)
ProbePointArg< PacketInfo > Packet
Packet probe point.
std::shared_ptr< Request > RequestPtr
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
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.
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.
void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
Fault startFunctional(ThreadContext *_tc, Addr &addr, unsigned &logBytes, BaseMMU::Mode mode)
Ports are used to interface objects to each other.
unsigned numInflight() const
void setLE(T v)
Set the value in the data pointer to v as little endian.
EventFunctionWrapper startWalkWrapperEvent
Event used to call startWalkWrapper.
Fault stepWalk(PacketPtr &write)
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Fault pageFault(bool present)
void initState(ThreadContext *_tc, BaseMMU::Mode _mode, bool _isTiming=false)
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode)=0
bool scheduled() const
Determine if the current event is scheduled.
#define panic(...)
This implements a cprintf based panic() function.
bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
Generated on Thu Jul 28 2022 13:32:22 for gem5 by doxygen 1.8.17