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");
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);