61 #include "debug/PageTableWalker.hh"
115 bool walkComplete = senderWalk->
recvPacket(pkt);
121 if (walkerState == senderWalk) {
140 walker->recvReqRetry();
150 walkerState->
retry();
174 if (if_name ==
"port")
184 assert(state == Ready);
194 unsigned num_squashed = 0;
201 DPRINTF(PageTableWalker,
"Squashing table walk for address %#x\n",
202 currState->
req->getVaddr());
206 std::make_shared<UnimpFault>(
"Squashed Inst"),
207 currState->
req, currState->
tc, currState->
mode);
234 setupWalk(req->getVaddr());
242 walker->port.sendAtomic(read);
244 fault = stepWalk(write);
245 assert(fault ==
NoFault || read == NULL);
249 walker->port.sendAtomic(write);
266 walker->port.sendFunctional(read);
270 fault = stepWalk(write);
271 assert(fault ==
NoFault || read == NULL);
275 logBytes = entry.logBytes;
284 assert(state != Ready && state != Waiting);
289 pte = read->getLE<uint64_t>();
291 pte = read->getLE<uint32_t>();
292 VAddr
vaddr = entry.vaddr;
293 bool uncacheable = pte.pcd;
295 bool doWrite =
false;
296 bool doTLBInsert =
false;
297 bool doEndWalk =
false;
302 "Got long mode PML4 entry %#016x.\n", (uint64_t)pte);
303 nextRead = ((uint64_t)pte & (
mask(40) << 12)) +
vaddr.longl3 * dataSize;
306 entry.writable = pte.w;
308 if (badNX || !pte.p) {
310 fault = pageFault(pte.p);
313 entry.noExec = pte.nx;
318 "Got long mode PDP entry %#016x.\n", (uint64_t)pte);
319 nextRead = ((uint64_t)pte & (
mask(40) << 12)) +
vaddr.longl2 * dataSize;
322 entry.writable = entry.writable && pte.w;
323 entry.user = entry.user && pte.u;
324 if (badNX || !pte.p) {
326 fault = pageFault(pte.p);
333 "Got long mode PD entry %#016x.\n", (uint64_t)pte);
336 entry.writable = entry.writable && pte.w;
337 entry.user = entry.user && pte.u;
338 if (badNX || !pte.p) {
340 fault = pageFault(pte.p);
347 ((uint64_t)pte & (
mask(40) << 12)) +
vaddr.longl1 * dataSize;
353 entry.paddr = (uint64_t)pte & (
mask(31) << 21);
354 entry.uncacheable = uncacheable;
355 entry.global = pte.g;
356 entry.patBit =
bits(pte, 12);
357 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
364 "Got long mode PTE entry %#016x.\n", (uint64_t)pte);
367 entry.writable = entry.writable && pte.w;
368 entry.user = entry.user && pte.u;
369 if (badNX || !pte.p) {
371 fault = pageFault(pte.p);
374 entry.paddr = (uint64_t)pte & (
mask(40) << 12);
375 entry.uncacheable = uncacheable;
376 entry.global = pte.g;
377 entry.patBit =
bits(pte, 12);
378 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
384 "Got legacy mode PAE PDP entry %#08x.\n", (uint32_t)pte);
385 nextRead = ((uint64_t)pte & (
mask(40) << 12)) +
vaddr.pael2 * dataSize;
388 fault = pageFault(pte.p);
395 "Got legacy mode PAE PD entry %#08x.\n", (uint32_t)pte);
398 entry.writable = pte.w;
400 if (badNX || !pte.p) {
402 fault = pageFault(pte.p);
408 nextRead = ((uint64_t)pte & (
mask(40) << 12)) +
vaddr.pael1 * dataSize;
414 entry.paddr = (uint64_t)pte & (
mask(31) << 21);
415 entry.uncacheable = uncacheable;
416 entry.global = pte.g;
417 entry.patBit =
bits(pte, 12);
418 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
425 "Got legacy mode PAE PTE entry %#08x.\n", (uint32_t)pte);
428 entry.writable = entry.writable && pte.w;
429 entry.user = entry.user && pte.u;
430 if (badNX || !pte.p) {
432 fault = pageFault(pte.p);
435 entry.paddr = (uint64_t)pte & (
mask(40) << 12);
436 entry.uncacheable = uncacheable;
437 entry.global = pte.g;
438 entry.patBit =
bits(pte, 7);
439 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
445 "Got legacy mode PSE PD entry %#08x.\n", (uint32_t)pte);
448 entry.writable = pte.w;
452 fault = pageFault(pte.p);
459 ((uint64_t)pte & (
mask(20) << 12)) +
vaddr.norml2 * dataSize;
465 entry.paddr =
bits(pte, 20, 13) << 32 |
bits(pte, 31, 22) << 22;
466 entry.uncacheable = uncacheable;
467 entry.global = pte.g;
468 entry.patBit =
bits(pte, 12);
469 entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1);
476 "Got legacy mode PD entry %#08x.\n", (uint32_t)pte);
479 entry.writable = pte.w;
483 fault = pageFault(pte.p);
488 nextRead = ((uint64_t)pte & (
mask(20) << 12)) +
vaddr.norml2 * dataSize;
493 "Got legacy mode PTE entry %#08x.\n", (uint32_t)pte);
496 entry.writable = pte.w;
500 fault = pageFault(pte.p);
503 entry.paddr = (uint64_t)pte & (
mask(20) << 12);
504 entry.uncacheable = uncacheable;
505 entry.global = pte.g;
506 entry.patBit =
bits(pte, 7);
507 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
512 panic(
"Unknown page table walker state %d!\n");
517 walker->tlb->insert(entry.vaddr, entry);
524 RequestPtr request = std::make_shared<Request>(
525 nextRead, oldRead->
getSize(), flags, walker->requestorId);
532 write->
setLE<uint64_t>(pte);
562 topAddr = (cr3.longPdtb << 12) +
addr.longl4 * dataSize;
570 topAddr = (cr3.paePdtb << 5) +
addr.pael3 * dataSize;
574 topAddr = (cr3.pdtb << 12) +
addr.norml2 * dataSize;
593 RequestPtr request = std::make_shared<Request>(
594 topAddr, dataSize, flags, walker->requestorId);
605 assert(state == Waiting);
610 return (inflight == 0);
623 timingFault = stepWalk(write);
625 assert(timingFault ==
NoFault || read == NULL);
627 writes.push_back(write);
633 if (inflight == 0 && read == NULL && writes.size() == 0) {
644 bool delayedResponse;
645 Fault fault = walker->tlb->translate(req, tc, NULL,
mode,
646 delayedResponse,
true);
647 assert(!delayedResponse);
649 translation->finish(fault, req, tc,
mode);
652 translation->finish(timingFault, req, tc,
mode);
672 if (!walker->sendTiming(
this, pkt)) {
680 while (writes.size()) {
684 if (!walker->sendTiming(
this, write)) {
686 writes.push_back(write);
733 DPRINTF(PageTableWalker,
"Raising page fault.\n");
737 return std::make_shared<PageFault>(entry.vaddr,
present,
mode,
738 m5reg.cpl == 3,
false);