61 #include "debug/PageTableWalker.hh"
112 bool walkComplete = senderWalk->
recvPacket(pkt);
118 if (walkerState == senderWalk) {
137 walker->recvReqRetry();
147 walkerState->
retry();
171 if (if_name ==
"port")
181 assert(state == Ready);
191 unsigned num_squashed = 0;
198 DPRINTF(PageTableWalker,
"Squashing table walk for address %#x\n",
199 currState->
req->getVaddr());
203 std::make_shared<UnimpFault>(
"Squashed Inst"),
204 currState->
req, currState->
tc, currState->
mode);
231 setupWalk(req->getVaddr());
239 walker->port.sendAtomic(read);
241 fault = stepWalk(write);
242 assert(fault ==
NoFault || read == NULL);
246 walker->port.sendAtomic(write);
263 walker->port.sendFunctional(read);
267 fault = stepWalk(write);
268 assert(fault ==
NoFault || read == NULL);
272 logBytes = entry.logBytes;
281 assert(state != Ready && state != Waiting);
286 pte = read->
getLE<uint64_t>();
288 pte = read->getLE<uint32_t>();
289 VAddr
vaddr = entry.vaddr;
290 bool uncacheable = pte.pcd;
292 bool doWrite =
false;
293 bool doTLBInsert =
false;
294 bool doEndWalk =
false;
299 "Got long mode PML4 entry %#016x.\n", (uint64_t)pte);
300 nextRead = ((uint64_t)pte & (
mask(40) << 12)) +
vaddr.longl3 * dataSize;
303 entry.writable = pte.w;
305 if (badNX || !pte.p) {
307 fault = pageFault(pte.p);
310 entry.noExec = pte.nx;
315 "Got long mode PDP entry %#016x.\n", (uint64_t)pte);
316 nextRead = ((uint64_t)pte & (
mask(40) << 12)) +
vaddr.longl2 * dataSize;
319 entry.writable = entry.writable && pte.w;
320 entry.user = entry.user && pte.u;
321 if (badNX || !pte.p) {
323 fault = pageFault(pte.p);
330 "Got long mode PD entry %#016x.\n", (uint64_t)pte);
333 entry.writable = entry.writable && pte.w;
334 entry.user = entry.user && pte.u;
335 if (badNX || !pte.p) {
337 fault = pageFault(pte.p);
344 ((uint64_t)pte & (
mask(40) << 12)) +
vaddr.longl1 * dataSize;
350 entry.paddr = (uint64_t)pte & (
mask(31) << 21);
351 entry.uncacheable = uncacheable;
352 entry.global = pte.g;
353 entry.patBit =
bits(pte, 12);
354 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
361 "Got long mode PTE entry %#016x.\n", (uint64_t)pte);
364 entry.writable = entry.writable && pte.w;
365 entry.user = entry.user && pte.u;
366 if (badNX || !pte.p) {
368 fault = pageFault(pte.p);
371 entry.paddr = (uint64_t)pte & (
mask(40) << 12);
372 entry.uncacheable = uncacheable;
373 entry.global = pte.g;
374 entry.patBit =
bits(pte, 12);
375 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
381 "Got legacy mode PAE PDP entry %#08x.\n", (uint32_t)pte);
382 nextRead = ((uint64_t)pte & (
mask(40) << 12)) +
vaddr.pael2 * dataSize;
385 fault = pageFault(pte.p);
392 "Got legacy mode PAE PD entry %#08x.\n", (uint32_t)pte);
395 entry.writable = pte.w;
397 if (badNX || !pte.p) {
399 fault = pageFault(pte.p);
405 nextRead = ((uint64_t)pte & (
mask(40) << 12)) +
vaddr.pael1 * dataSize;
411 entry.paddr = (uint64_t)pte & (
mask(31) << 21);
412 entry.uncacheable = uncacheable;
413 entry.global = pte.g;
414 entry.patBit =
bits(pte, 12);
415 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
422 "Got legacy mode PAE PTE entry %#08x.\n", (uint32_t)pte);
425 entry.writable = entry.writable && pte.w;
426 entry.user = entry.user && pte.u;
427 if (badNX || !pte.p) {
429 fault = pageFault(pte.p);
432 entry.paddr = (uint64_t)pte & (
mask(40) << 12);
433 entry.uncacheable = uncacheable;
434 entry.global = pte.g;
435 entry.patBit =
bits(pte, 7);
436 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
442 "Got legacy mode PSE PD entry %#08x.\n", (uint32_t)pte);
445 entry.writable = pte.w;
449 fault = pageFault(pte.p);
456 ((uint64_t)pte & (
mask(20) << 12)) +
vaddr.norml2 * dataSize;
462 entry.paddr =
bits(pte, 20, 13) << 32 |
bits(pte, 31, 22) << 22;
463 entry.uncacheable = uncacheable;
464 entry.global = pte.g;
465 entry.patBit =
bits(pte, 12);
466 entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1);
473 "Got legacy mode PD entry %#08x.\n", (uint32_t)pte);
476 entry.writable = pte.w;
480 fault = pageFault(pte.p);
485 nextRead = ((uint64_t)pte & (
mask(20) << 12)) +
vaddr.norml2 * dataSize;
490 "Got legacy mode PTE entry %#08x.\n", (uint32_t)pte);
493 entry.writable = pte.w;
497 fault = pageFault(pte.p);
500 entry.paddr = (uint64_t)pte & (
mask(20) << 12);
501 entry.uncacheable = uncacheable;
502 entry.global = pte.g;
503 entry.patBit =
bits(pte, 7);
504 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
509 panic(
"Unknown page table walker state %d!\n");
514 walker->tlb->insert(entry.vaddr, entry);
521 RequestPtr request = std::make_shared<Request>(
522 nextRead, oldRead->
getSize(), flags, walker->requestorId);
529 write->
setLE<uint64_t>(pte);
559 topAddr = (cr3.longPdtb << 12) +
addr.longl4 * dataSize;
567 topAddr = (cr3.paePdtb << 5) +
addr.pael3 * dataSize;
571 topAddr = (cr3.pdtb << 12) +
addr.norml2 * dataSize;
590 RequestPtr request = std::make_shared<Request>(
591 topAddr, dataSize, flags, walker->requestorId);
602 assert(state == Waiting);
607 return (inflight == 0);
620 timingFault = stepWalk(write);
622 assert(timingFault ==
NoFault || read == NULL);
624 writes.push_back(write);
630 if (inflight == 0 && read == NULL && writes.size() == 0) {
641 bool delayedResponse;
642 Fault fault = walker->tlb->translate(req, tc, NULL,
mode,
643 delayedResponse,
true);
644 assert(!delayedResponse);
646 translation->finish(fault, req, tc,
mode);
649 translation->finish(timingFault, req, tc,
mode);
669 if (!walker->sendTiming(
this, pkt)) {
677 while (writes.size()) {
681 if (!walker->sendTiming(
this, write)) {
683 writes.push_back(write);
730 DPRINTF(PageTableWalker,
"Raising page fault.\n");
734 return std::make_shared<PageFault>(entry.vaddr,
present,
mode,
735 m5reg.cpl == 3,
false);
741 X86PagetableWalkerParams::create()