X86: Implement the media floating point max instructions.
[gem5.git] / src / arch / x86 / pagetable_walker.cc
index 87f00dcbea18f44daa1e02579818fa6b70ecef83..d43502760c3bca70264e969e7a8f025314b2ac06 100644 (file)
@@ -98,9 +98,11 @@ Walker::doNext(PacketPtr &write)
     bool uncacheable = pte.pcd;
     Addr nextRead = 0;
     bool doWrite = false;
-    bool badNX = pte.nx && (!tlb->allowNX() || !enableNX);
+    bool badNX = pte.nx && mode == BaseTLB::Execute && enableNX;
     switch(state) {
       case LongPML4:
+        DPRINTF(PageTableWalker,
+                "Got long mode PML4 entry %#016x.\n", (uint64_t)pte);
         nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl3 * size;
         doWrite = !pte.a;
         pte.a = 1;
@@ -114,6 +116,8 @@ Walker::doNext(PacketPtr &write)
         nextState = LongPDP;
         break;
       case LongPDP:
+        DPRINTF(PageTableWalker,
+                "Got long mode PDP entry %#016x.\n", (uint64_t)pte);
         nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl2 * size;
         doWrite = !pte.a;
         pte.a = 1;
@@ -126,6 +130,8 @@ Walker::doNext(PacketPtr &write)
         nextState = LongPD;
         break;
       case LongPD:
+        DPRINTF(PageTableWalker,
+                "Got long mode PD entry %#016x.\n", (uint64_t)pte);
         doWrite = !pte.a;
         pte.a = 1;
         entry.writable = entry.writable && pte.w;
@@ -154,6 +160,8 @@ Walker::doNext(PacketPtr &write)
             return NoFault;
         }
       case LongPTE:
+        DPRINTF(PageTableWalker,
+                "Got long mode PTE entry %#016x.\n", (uint64_t)pte);
         doWrite = !pte.a;
         pte.a = 1;
         entry.writable = entry.writable && pte.w;
@@ -171,6 +179,8 @@ Walker::doNext(PacketPtr &write)
         stop();
         return NoFault;
       case PAEPDP:
+        DPRINTF(PageTableWalker,
+                "Got legacy mode PAE PDP entry %#08x.\n", (uint32_t)pte);
         nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael2 * size;
         if (!pte.p) {
             stop();
@@ -179,6 +189,8 @@ Walker::doNext(PacketPtr &write)
         nextState = PAEPD;
         break;
       case PAEPD:
+        DPRINTF(PageTableWalker,
+                "Got legacy mode PAE PD entry %#08x.\n", (uint32_t)pte);
         doWrite = !pte.a;
         pte.a = 1;
         entry.writable = pte.w;
@@ -206,6 +218,8 @@ Walker::doNext(PacketPtr &write)
             return NoFault;
         }
       case PAEPTE:
+        DPRINTF(PageTableWalker,
+                "Got legacy mode PAE PTE entry %#08x.\n", (uint32_t)pte);
         doWrite = !pte.a;
         pte.a = 1;
         entry.writable = entry.writable && pte.w;
@@ -223,6 +237,8 @@ Walker::doNext(PacketPtr &write)
         stop();
         return NoFault;
       case PSEPD:
+        DPRINTF(PageTableWalker,
+                "Got legacy mode PSE PD entry %#08x.\n", (uint32_t)pte);
         doWrite = !pte.a;
         pte.a = 1;
         entry.writable = pte.w;
@@ -251,6 +267,8 @@ Walker::doNext(PacketPtr &write)
             return NoFault;
         }
       case PD:
+        DPRINTF(PageTableWalker,
+                "Got legacy mode PD entry %#08x.\n", (uint32_t)pte);
         doWrite = !pte.a;
         pte.a = 1;
         entry.writable = pte.w;
@@ -265,6 +283,8 @@ Walker::doNext(PacketPtr &write)
         nextState = PTE;
         break;
       case PTE:
+        DPRINTF(PageTableWalker,
+                "Got legacy mode PTE entry %#08x.\n", (uint32_t)pte);
         doWrite = !pte.a;
         pte.a = 1;
         entry.writable = pte.w;
@@ -309,14 +329,13 @@ Walker::doNext(PacketPtr &write)
 
 Fault
 Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation,
-        RequestPtr _req, bool _write, bool _execute)
+              RequestPtr _req, BaseTLB::Mode _mode)
 {
     assert(state == Ready);
     tc = _tc;
     req = _req;
     Addr vaddr = req->getVaddr();
-    execute = _execute;
-    write = _write;
+    mode = _mode;
     translation = _translation;
 
     VAddr addr = vaddr;
@@ -431,14 +450,14 @@ Walker::recvTiming(PacketPtr pkt)
                  * well.
                  */
                 bool delayedResponse;
-                Fault fault = tlb->translate(req, tc, NULL, write, execute,
+                Fault fault = tlb->translate(req, tc, NULL, mode,
                         delayedResponse, true);
                 assert(!delayedResponse);
                 // Let the CPU continue.
-                translation->finish(fault, req, tc, write);
+                translation->finish(fault, req, tc, mode);
             } else {
                 // There was a fault during the walk. Let the CPU know.
-                translation->finish(timingFault, req, tc, write);
+                translation->finish(timingFault, req, tc, mode);
             }
         }
     } else if (pkt->wasNacked()) {
@@ -541,9 +560,11 @@ Walker::getPort(const std::string &if_name, int idx)
 Fault
 Walker::pageFault(bool present)
 {
+    DPRINTF(PageTableWalker, "Raising page fault.\n");
     HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
-    return new PageFault(entry.vaddr, present, write,
-            m5reg.cpl == 3, false, execute && enableNX);
+    if (mode == BaseTLB::Execute && !enableNX)
+        mode = BaseTLB::Read;
+    return new PageFault(entry.vaddr, present, mode, m5reg.cpl == 3, false);
 }
 
 }