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;
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);
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);
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);
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);
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");
513 walker->tlb->insert(entry.vaddr, entry, cr3.pcid);
519 walker->tlb->insert(entry.vaddr, entry, 0x000);
529 RequestPtr request = std::make_shared<Request>(
530 nextRead, oldRead->
getSize(),
flags, walker->requestorId);
538 write->
setLE<uint64_t>(pte);
540 write->
setLE<uint32_t>(pte);
571 topAddr = (cr3.longPdtb << 12) +
addr.longl4 * dataSize;
578 topAddr = (cr3.paePdtb << 5) +
addr.pael3 * dataSize;
582 topAddr = (cr3.pdtb << 12) +
addr.norml2 * dataSize;
601 if (!cr4.pcide && cr3.pcd)
604 RequestPtr request = std::make_shared<Request>(
605 topAddr, dataSize,
flags, walker->requestorId);
616 assert(
state == Waiting);
621 return (inflight == 0);
634 timingFault = stepWalk(write);
636 assert(timingFault ==
NoFault || read == NULL);
638 writes.push_back(write);
644 if (inflight == 0 && read == NULL && writes.size() == 0) {
655 bool delayedResponse;
656 Fault fault = walker->tlb->translate(req, tc, NULL,
mode,
657 delayedResponse,
true);
658 assert(!delayedResponse);
660 translation->finish(fault, req, tc,
mode);
663 translation->finish(timingFault, req, tc,
mode);
683 if (!walker->sendTiming(
this, pkt)) {
691 while (writes.size()) {
695 if (!walker->sendTiming(
this, write)) {
697 writes.push_back(write);
744 DPRINTF(PageTableWalker,
"Raising page fault.\n");
748 return std::make_shared<PageFault>(entry.vaddr,
present,
mode,
749 m5reg.cpl == 3,
false);
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...
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.
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
@ PHYSICAL
The virtual address is also the physical address.
@ UNCACHEABLE
The request is to an uncacheable address.
bool isTimingMode() const
Is the system in timing mode?
ThreadContext is the external interface to all thread state for anything outside of the CPU.
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.
void initState(ThreadContext *_tc, BaseMMU::Mode _mode, bool _isTiming=false)
void setupWalk(Addr vaddr)
Fault stepWalk(PacketPtr &write)
Fault startFunctional(Addr &addr, unsigned &logBytes)
Fault pageFault(bool present)
unsigned numInflight() const
bool recvPacket(PacketPtr pkt)
BaseMMU::Translation * translation
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
bool recvTimingResp(PacketPtr pkt)
bool sendTiming(WalkerState *sendingState, PacketPtr pkt)
Fault start(ThreadContext *_tc, BaseMMU::Translation *translation, const RequestPtr &req, BaseMMU::Mode mode)
EventFunctionWrapper startWalkWrapperEvent
Event used to call startWalkWrapper.
std::list< WalkerState * > currStates
Fault startFunctional(ThreadContext *_tc, Addr &addr, unsigned &logBytes, BaseMMU::Mode mode)
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
bool scheduled() const
Determine if the current event is scheduled.
void schedule(Event &event, Tick when)
void set(Type mask)
Set all flag's bits matching the given mask.
#define panic(...)
This implements a cprintf based panic() function.
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria 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 ...