63 #include "debug/PageTableWalker.hh"
114 bool walkComplete = senderWalk->
recvPacket(pkt);
120 if (walkerState == senderWalk) {
139 walker->recvReqRetry();
149 walkerState->
retry();
173 if (if_name ==
"port")
183 assert(state == Ready);
193 unsigned num_squashed = 0;
200 DPRINTF(PageTableWalker,
"Squashing table walk for address %#x\n",
205 std::make_shared<UnimpFault>(
"Squashed Inst"),
206 currState->
req, currState->
tc, currState->
mode);
227 setupWalk(req->getVaddr());
235 walker->port.sendAtomic(read);
237 fault = stepWalk(write);
238 assert(fault ==
NoFault || read == NULL);
242 walker->port.sendAtomic(write);
259 walker->port.sendFunctional(read);
263 fault = stepWalk(write);
264 assert(fault ==
NoFault || read == NULL);
268 logBytes = entry.logBytes;
277 assert(state != Ready && state != Waiting);
282 pte = read->
get<uint64_t>();
284 pte = read->get<uint32_t>();
285 VAddr
vaddr = entry.vaddr;
288 bool doWrite =
false;
289 bool doTLBInsert =
false;
290 bool doEndWalk =
false;
295 "Got long mode PML4 entry %#016x.\n", (uint64_t)pte);
296 nextRead = ((uint64_t)pte & (
mask(40) << 12)) + vaddr.longl3 * dataSize;
299 entry.writable = pte.w;
301 if (badNX || !pte.p) {
303 fault = pageFault(pte.p);
306 entry.noExec = pte.nx;
311 "Got long mode PDP entry %#016x.\n", (uint64_t)pte);
312 nextRead = ((uint64_t)pte & (
mask(40) << 12)) + vaddr.longl2 * dataSize;
315 entry.writable = entry.writable && pte.w;
316 entry.user = entry.user && pte.u;
317 if (badNX || !pte.p) {
319 fault = pageFault(pte.p);
326 "Got long mode PD entry %#016x.\n", (uint64_t)pte);
329 entry.writable = entry.writable && pte.w;
330 entry.user = entry.user && pte.u;
331 if (badNX || !pte.p) {
333 fault = pageFault(pte.p);
340 ((uint64_t)pte & (
mask(40) << 12)) + vaddr.longl1 * dataSize;
346 entry.paddr = (uint64_t)pte & (
mask(31) << 21);
348 entry.global = pte.g;
349 entry.patBit =
bits(pte, 12);
350 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
357 "Got long mode PTE entry %#016x.\n", (uint64_t)pte);
360 entry.writable = entry.writable && pte.w;
361 entry.user = entry.user && pte.u;
362 if (badNX || !pte.p) {
364 fault = pageFault(pte.p);
367 entry.paddr = (uint64_t)pte & (
mask(40) << 12);
369 entry.global = pte.g;
370 entry.patBit =
bits(pte, 12);
371 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
377 "Got legacy mode PAE PDP entry %#08x.\n", (uint32_t)pte);
378 nextRead = ((uint64_t)pte & (
mask(40) << 12)) + vaddr.pael2 * dataSize;
381 fault = pageFault(pte.p);
388 "Got legacy mode PAE PD entry %#08x.\n", (uint32_t)pte);
391 entry.writable = pte.w;
393 if (badNX || !pte.p) {
395 fault = pageFault(pte.p);
401 nextRead = ((uint64_t)pte & (
mask(40) << 12)) + vaddr.pael1 * dataSize;
407 entry.paddr = (uint64_t)pte & (
mask(31) << 21);
409 entry.global = pte.g;
410 entry.patBit =
bits(pte, 12);
411 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
418 "Got legacy mode PAE PTE entry %#08x.\n", (uint32_t)pte);
421 entry.writable = entry.writable && pte.w;
422 entry.user = entry.user && pte.u;
423 if (badNX || !pte.p) {
425 fault = pageFault(pte.p);
428 entry.paddr = (uint64_t)pte & (
mask(40) << 12);
430 entry.global = pte.g;
431 entry.patBit =
bits(pte, 7);
432 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
438 "Got legacy mode PSE PD entry %#08x.\n", (uint32_t)pte);
441 entry.writable = pte.w;
445 fault = pageFault(pte.p);
452 ((uint64_t)pte & (
mask(20) << 12)) + vaddr.norml2 * dataSize;
458 entry.paddr =
bits(pte, 20, 13) << 32 |
bits(pte, 31, 22) << 22;
460 entry.global = pte.g;
461 entry.patBit =
bits(pte, 12);
462 entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1);
469 "Got legacy mode PD entry %#08x.\n", (uint32_t)pte);
472 entry.writable = pte.w;
476 fault = pageFault(pte.p);
481 nextRead = ((uint64_t)pte & (
mask(20) << 12)) + vaddr.norml2 * dataSize;
486 "Got legacy mode PTE entry %#08x.\n", (uint32_t)pte);
489 entry.writable = pte.w;
493 fault = pageFault(pte.p);
496 entry.paddr = (uint64_t)pte & (
mask(20) << 12);
498 entry.global = pte.g;
499 entry.patBit =
bits(pte, 7);
500 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
505 panic(
"Unknown page table walker state %d!\n");
510 walker->tlb->insert(entry.vaddr, entry);
518 new Request(nextRead, oldRead->
getSize(), flags, walker->masterId);
525 write->
set<uint64_t>(pte);
557 topAddr = (cr3.longPdtb << 12) + addr.longl4 * dataSize;
565 topAddr = (cr3.paePdtb << 5) + addr.pael3 * dataSize;
569 topAddr = (cr3.pdtb << 12) + addr.norml2 * dataSize;
598 assert(state == Waiting);
611 timingFault = stepWalk(write);
613 assert(timingFault ==
NoFault || read == NULL);
615 writes.push_back(write);
621 if (inflight == 0 && read == NULL && writes.size() == 0) {
632 bool delayedResponse;
633 Fault fault = walker->tlb->translate(req, tc, NULL,
mode,
634 delayedResponse,
true);
635 assert(!delayedResponse);
637 translation->finish(fault, req, tc,
mode);
640 translation->finish(timingFault, req, tc,
mode);
660 if (!walker->sendTiming(
this, pkt)) {
668 while (writes.size()) {
672 if (!walker->sendTiming(
this, write)) {
674 writes.push_back(write);
709 DPRINTF(PageTableWalker,
"Raising page fault.\n");
713 return std::make_shared<PageFault>(entry.vaddr,
present,
mode,
714 m5reg.cpl == 3,
false);
720 X86PagetableWalkerParams::create()
void setupWalk(Addr vaddr)
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
bool sendTiming(WalkerState *sendingState, PacketPtr pkt)
decltype(nullptr) constexpr NoFault
void recvReqRetry()
Called by the slave port if sendTimingReq was called on this master port (causing recvTimingReq to be...
bool recvPacket(PacketPtr pkt)
Declaration of a request, the overall memory request consisting of the parts of the request that are ...
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the slave port by calling its corresponding receive function...
TLB::Translation * translation
ThreadContext is the external interface to all thread state for anything outside of the CPU...
T get(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness.
The virtual address is also the physical address.
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...
void initState(ThreadContext *_tc, BaseTLB::Mode _mode, bool _isTiming=false)
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Fault startFunctional(ThreadContext *_tc, Addr &addr, unsigned &logBytes, BaseTLB::Mode mode)
The request is to an uncacheable address.
Fault start(ThreadContext *_tc, BaseTLB::Translation *translation, RequestPtr req, BaseTLB::Mode mode)
Fault startFunctional(Addr &addr, unsigned &logBytes)
const RequestPtr req
A pointer to the original request.
EventWrapper< Walker,&Walker::startWalkWrapper > startWalkWrapperEvent
Event used to call startWalkWrapper.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Flags getFlags()
Accessor for flags.
BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a master port with a given name and index.
EndBitUnion(PageTableEntry) struct TlbEntry Addr vaddr
Fault stepWalk(PacketPtr &write)
MemCmd cmd
The command field of the packet.
A BaseMasterPort is a protocol-agnostic master port, responsible only for the structural connection t...
std::list< WalkerState * > currStates
bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the slave port.
void schedule(Event &event, Tick when)
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.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
Fault pageFault(bool present)
virtual void finish(const Fault &fault, RequestPtr req, ThreadContext *tc, Mode mode)=0
virtual bool squashed() const
This function is used by the page table walker to determine if it should translate the a pending requ...
std::shared_ptr< FaultBase > Fault
virtual BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a master port with a given name and index.
if(it_gpu==gpuTypeMap.end())
ProbePointArg< PacketInfo > Packet
Packet probe point.
bool isTimingMode() const
Is the system in timing mode?
bool recvTimingResp(PacketPtr pkt)