arch, mem: Make the page table lookup function return a pointer.
authorGabe Black <gabeblack@google.com>
Fri, 5 Jan 2018 23:01:00 +0000 (15:01 -0800)
committerGabe Black <gabeblack@google.com>
Sat, 20 Jan 2018 08:06:56 +0000 (08:06 +0000)
This avoids having a copy in the lookup function itself, and the
declaration of a lot of temporary TLB entry pointers in callers. The
gpu TLB seems to have had the most dependence on the original signature
of the lookup function, partially because it was relying on a somewhat
unsafe copy to a TLB entry using a base class pointer type.

Change-Id: I8b1cf494468163deee000002d243541657faf57f
Reviewed-on: https://gem5-review.googlesource.com/7343
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>

13 files changed:
src/arch/alpha/faults.cc
src/arch/arm/remote_gdb.cc
src/arch/mips/remote_gdb.cc
src/arch/power/remote_gdb.cc
src/arch/riscv/remote_gdb.cc
src/arch/sparc/faults.cc
src/arch/sparc/remote_gdb.cc
src/arch/x86/remote_gdb.cc
src/arch/x86/tlb.cc
src/arch/x86/tlb.hh
src/gpu-compute/gpu_tlb.cc
src/mem/page_table.cc
src/mem/page_table.hh

index 4a829cd9b86c2e3e4a296594aabce916fb83c0f7..89b0ecea8b95b03b1073d9a843eec6c592f62c0e 100644 (file)
@@ -196,14 +196,11 @@ ItbPageFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
     }
 
     Process *p = tc->getProcessPtr();
-    TlbEntry entry;
-    bool success = p->pTable->lookup(pc, entry);
-    if (!success) {
-        panic("Tried to execute unmapped address %#x.\n", pc);
-    } else {
-        VAddr vaddr(pc);
-        dynamic_cast<TLB *>(tc->getITBPtr())->insert(vaddr.page(), entry);
-    }
+    TlbEntry *entry = p->pTable->lookup(pc);
+    panic_if(!entry, "Tried to execute unmapped address %#x.\n", pc);
+
+    VAddr vaddr(pc);
+    dynamic_cast<TLB *>(tc->getITBPtr())->insert(vaddr.page(), *entry);
 }
 
 void
@@ -215,17 +212,11 @@ NDtbMissFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
     }
 
     Process *p = tc->getProcessPtr();
-    TlbEntry entry;
-    bool success = p->pTable->lookup(vaddr, entry);
-    if (!success) {
-        if (p->fixupStackFault(vaddr))
-            success = p->pTable->lookup(vaddr, entry);
-    }
-    if (!success) {
-        panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
-    } else {
-        dynamic_cast<TLB *>(tc->getDTBPtr())->insert(vaddr.page(), entry);
-    }
+    TlbEntry *entry = p->pTable->lookup(vaddr);
+    if (!entry && p->fixupStackFault(vaddr))
+        entry = p->pTable->lookup(vaddr);
+    panic_if(!entry, "Tried to access unmapped address %#x.\n", (Addr)vaddr);
+    dynamic_cast<TLB *>(tc->getDTBPtr())->insert(vaddr.page(), *entry);
 }
 
 } // namespace AlphaISA
index f12734182043b438d4f07c94c5bfe7075f125747..f1919372b654b3e2f0f29a7a5215006ae286a382 100644 (file)
@@ -186,12 +186,9 @@ RemoteGDB::acc(Addr va, size_t len)
         DPRINTF(GDBAcc, "acc:   %#x mapping is valid\n", va);
         return true;
     } else {
-        TlbEntry entry;
-        //Check to make sure the first byte is mapped into the processes address
-        //space.
-        if (context()->getProcessPtr()->pTable->lookup(va, entry))
-            return true;
-        return false;
+        // Check to make sure the first byte is mapped into the processes
+        // address space.
+        return context()->getProcessPtr()->pTable->lookup(va) != nullptr;
     }
 }
 
index e17f8fd1dd63a74c87643209d00763a1f7e7bd65..d490fa518c7b24e2953d1569abc204459e9d6875 100644 (file)
@@ -162,13 +162,10 @@ RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc, int _port)
 bool
 RemoteGDB::acc(Addr va, size_t len)
 {
-    TlbEntry entry;
-    //Check to make sure the first byte is mapped into the processes address
-    //space.
-    if (FullSystem)
-        panic("acc not implemented for MIPS FS!");
-    else
-        return context()->getProcessPtr()->pTable->lookup(va, entry);
+    // Check to make sure the first byte is mapped into the processes address
+    // space.
+    panic_if(FullSystem, "acc not implemented for MIPS FS!");
+    return context()->getProcessPtr()->pTable->lookup(va) != nullptr;
 }
 
 void
index 7bdd3ba6a7f806e0275c6803f3c2d64d96b83337..b4082e0ee6338fc35dcc1518aa2ed78daee6f5c7 100644 (file)
@@ -162,16 +162,13 @@ RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc, int _port)
 bool
 RemoteGDB::acc(Addr va, size_t len)
 {
-    TlbEntry entry;
-    //Check to make sure the first byte is mapped into the processes address
-    //space.  At the time of this writing, the acc() check is used when
-    //processing the MemR/MemW packets before actually asking the translating
-    //port proxy to read/writeBlob.  I (bgs) am not convinced the first byte
-    //check is enough.
-    if (FullSystem)
-        panic("acc not implemented for POWER FS!");
-    else
-        return context()->getProcessPtr()->pTable->lookup(va, entry);
+    // Check to make sure the first byte is mapped into the processes address
+    // space.  At the time of this writing, the acc() check is used when
+    // processing the MemR/MemW packets before actually asking the translating
+    // port proxy to read/writeBlob.  I (bgs) am not convinced the first byte
+    // check is enough.
+    panic_if(FullSystem, "acc not implemented for POWER FS!");
+    return context()->getProcessPtr()->pTable->lookup(va) != nullptr;
 }
 
 void
index 4f423fc01ff721867e13ed3c06beef26d93b5d2b..f4e606e275af1f9f2306dd3ae5d3068a7cec367f 100644 (file)
@@ -156,11 +156,8 @@ RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc, int _port)
 bool
 RemoteGDB::acc(Addr va, size_t len)
 {
-    TlbEntry entry;
-    if (FullSystem)
-        panic("acc not implemented for RISCV FS!");
-    else
-        return context()->getProcessPtr()->pTable->lookup(va, entry);
+    panic_if(FullSystem, "acc not implemented for RISCV FS!");
+    return context()->getProcessPtr()->pTable->lookup(va) != nullptr;
 }
 
 void
index 5466115d04a200ee66df460654cb0912e98b6a91..0b6a289272f42018d7140a6bd61ead68c5c29a3f 100644 (file)
@@ -629,49 +629,46 @@ FastInstructionAccessMMUMiss::invoke(ThreadContext *tc,
     }
 
     Process *p = tc->getProcessPtr();
-    TlbEntry entry;
-    bool success = p->pTable->lookup(vaddr, entry);
-    if (!success) {
-        panic("Tried to execute unmapped address %#x.\n", vaddr);
-    } else {
-        Addr alignedvaddr = p->pTable->pageAlign(vaddr);
-
-        // Grab fields used during instruction translation to figure out
-        // which context to use.
-        uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
-
-        // Inside a VM, a real address is the address that guest OS would
-        // interpret to be a physical address. To map to the physical address,
-        // it still needs to undergo a translation. The instruction
-        // translation code in the SPARC ITLB code assumes that the context is
-        // zero (kernel-level) if real addressing is being used.
-        bool is_real_address = !bits(tlbdata, 4);
-
-        // The SPARC ITLB code assumes that traps are executed in context
-        // zero so we carry that assumption through here.
-        bool trapped = bits(tlbdata, 18, 16) > 0;
-
-        // The primary context acts as a PASID. It allows the MMU to
-        // distinguish between virtual addresses that would alias to the
-        // same physical address (if two or more processes shared the same
-        // virtual address mapping).
-        int primary_context = bits(tlbdata, 47, 32);
-
-        // The partition id distinguishes between virtualized environments.
-        int const partition_id = 0;
-
-        // Given the assumptions in the translateInst code in the SPARC ITLB,
-        // the logic works out to the following for the context.
-        int context_id = (is_real_address || trapped) ? 0 : primary_context;
-
-        // Insert the TLB entry.
-        // The entry specifying whether the address is "real" is set to
-        // false for syscall emulation mode regardless of whether the
-        // address is real in preceding code. Not sure sure that this is
-        // correct, but also not sure if it matters at all.
-        dynamic_cast<TLB *>(tc->getITBPtr())->
-            insert(alignedvaddr, partition_id, context_id, false, entry.pte);
-    }
+    TlbEntry *entry = p->pTable->lookup(vaddr);
+    panic_if(!entry, "Tried to execute unmapped address %#x.\n", vaddr);
+
+    Addr alignedvaddr = p->pTable->pageAlign(vaddr);
+
+    // Grab fields used during instruction translation to figure out
+    // which context to use.
+    uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
+
+    // Inside a VM, a real address is the address that guest OS would
+    // interpret to be a physical address. To map to the physical address,
+    // it still needs to undergo a translation. The instruction
+    // translation code in the SPARC ITLB code assumes that the context is
+    // zero (kernel-level) if real addressing is being used.
+    bool is_real_address = !bits(tlbdata, 4);
+
+    // The SPARC ITLB code assumes that traps are executed in context
+    // zero so we carry that assumption through here.
+    bool trapped = bits(tlbdata, 18, 16) > 0;
+
+    // The primary context acts as a PASID. It allows the MMU to
+    // distinguish between virtual addresses that would alias to the
+    // same physical address (if two or more processes shared the same
+    // virtual address mapping).
+    int primary_context = bits(tlbdata, 47, 32);
+
+    // The partition id distinguishes between virtualized environments.
+    int const partition_id = 0;
+
+    // Given the assumptions in the translateInst code in the SPARC ITLB,
+    // the logic works out to the following for the context.
+    int context_id = (is_real_address || trapped) ? 0 : primary_context;
+
+    // Insert the TLB entry.
+    // The entry specifying whether the address is "real" is set to
+    // false for syscall emulation mode regardless of whether the
+    // address is real in preceding code. Not sure sure that this is
+    // correct, but also not sure if it matters at all.
+    dynamic_cast<TLB *>(tc->getITBPtr())->
+        insert(alignedvaddr, partition_id, context_id, false, entry->pte);
 }
 
 void
@@ -683,83 +680,78 @@ FastDataAccessMMUMiss::invoke(ThreadContext *tc, const StaticInstPtr &inst)
     }
 
     Process *p = tc->getProcessPtr();
-    TlbEntry entry;
-    bool success = p->pTable->lookup(vaddr, entry);
-    if (!success) {
-        if (p->fixupStackFault(vaddr))
-            success = p->pTable->lookup(vaddr, entry);
-    }
-    if (!success) {
-        panic("Tried to access unmapped address %#x.\n", vaddr);
-    } else {
-        Addr alignedvaddr = p->pTable->pageAlign(vaddr);
-
-        // Grab fields used during data translation to figure out
-        // which context to use.
-        uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
-
-        // The primary context acts as a PASID. It allows the MMU to
-        // distinguish between virtual addresses that would alias to the
-        // same physical address (if two or more processes shared the same
-        // virtual address mapping). There's a secondary context used in the
-        // DTLB translation code, but it should __probably__ be zero for
-        // syscall emulation code. (The secondary context is used by Solaris
-        // to allow kernel privilege code to access user space code:
-        // [ISBN 0-13-022496-0]:PG199.)
-        int primary_context = bits(tlbdata, 47, 32);
-
-        // "Hyper-Privileged Mode" is in use. There are three main modes of
-        // operation for Sparc: Hyper-Privileged Mode, Privileged Mode, and
-        // User Mode.
-        int hpriv = bits(tlbdata, 0);
-
-        // Reset, Error and Debug state is in use. Something horrible has
-        // happened or the system is operating in Reset Mode.
-        int red = bits(tlbdata, 1);
-
-        // Inside a VM, a real address is the address that guest OS would
-        // interpret to be a physical address. To map to the physical address,
-        // it still needs to undergo a translation. The instruction
-        // translation code in the SPARC ITLB code assumes that the context is
-        // zero (kernel-level) if real addressing is being used.
-        int is_real_address = !bits(tlbdata, 5);
-
-        // Grab the address space identifier register from the thread context.
-        // XXX: Inspecting how setMiscReg and setMiscRegNoEffect behave for
-        // MISCREG_ASI causes me to think that the ASI register implementation
-        // might be bugged. The NoEffect variant changes the ASI register
-        // value in the architectural state while the normal variant changes
-        // the context field in the thread context's currently decoded request
-        // but does not directly affect the ASI register value in the
-        // architectural state. The ASI values and the context field in the
-        // request packet seem to have completely different uses.
-        MiscReg reg_asi = tc->readMiscRegNoEffect(MISCREG_ASI);
-        ASI asi = static_cast<ASI>(reg_asi);
-
-        // The SPARC DTLB code assumes that traps are executed in context
-        // zero if the asi value is ASI_IMPLICIT (which is 0x0). There's also
-        // an assumption that the nucleus address space is being used, but
-        // the context is the relevant issue since we need to pass it to TLB.
-        bool trapped = bits(tlbdata, 18, 16) > 0;
-
-        // Given the assumptions in the translateData code in the SPARC DTLB,
-        // the logic works out to the following for the context.
-        int context_id = ((!hpriv && !red && is_real_address) ||
-                          asiIsReal(asi) ||
-                          (trapped && asi == ASI_IMPLICIT))
-                         ? 0 : primary_context;
-
-        // The partition id distinguishes between virtualized environments.
-        int const partition_id = 0;
-
-        // Insert the TLB entry.
-        // The entry specifying whether the address is "real" is set to
-        // false for syscall emulation mode regardless of whether the
-        // address is real in preceding code. Not sure sure that this is
-        // correct, but also not sure if it matters at all.
-        dynamic_cast<TLB *>(tc->getDTBPtr())->
-            insert(alignedvaddr, partition_id, context_id, false, entry.pte);
-    }
+    TlbEntry *entry = p->pTable->lookup(vaddr);
+    if (!entry && p->fixupStackFault(vaddr))
+        entry = p->pTable->lookup(vaddr);
+    panic_if(!entry, "Tried to access unmapped address %#x.\n", vaddr);
+
+    Addr alignedvaddr = p->pTable->pageAlign(vaddr);
+
+    // Grab fields used during data translation to figure out
+    // which context to use.
+    uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
+
+    // The primary context acts as a PASID. It allows the MMU to
+    // distinguish between virtual addresses that would alias to the
+    // same physical address (if two or more processes shared the same
+    // virtual address mapping). There's a secondary context used in the
+    // DTLB translation code, but it should __probably__ be zero for
+    // syscall emulation code. (The secondary context is used by Solaris
+    // to allow kernel privilege code to access user space code:
+    // [ISBN 0-13-022496-0]:PG199.)
+    int primary_context = bits(tlbdata, 47, 32);
+
+    // "Hyper-Privileged Mode" is in use. There are three main modes of
+    // operation for Sparc: Hyper-Privileged Mode, Privileged Mode, and
+    // User Mode.
+    int hpriv = bits(tlbdata, 0);
+
+    // Reset, Error and Debug state is in use. Something horrible has
+    // happened or the system is operating in Reset Mode.
+    int red = bits(tlbdata, 1);
+
+    // Inside a VM, a real address is the address that guest OS would
+    // interpret to be a physical address. To map to the physical address,
+    // it still needs to undergo a translation. The instruction
+    // translation code in the SPARC ITLB code assumes that the context is
+    // zero (kernel-level) if real addressing is being used.
+    int is_real_address = !bits(tlbdata, 5);
+
+    // Grab the address space identifier register from the thread context.
+    // XXX: Inspecting how setMiscReg and setMiscRegNoEffect behave for
+    // MISCREG_ASI causes me to think that the ASI register implementation
+    // might be bugged. The NoEffect variant changes the ASI register
+    // value in the architectural state while the normal variant changes
+    // the context field in the thread context's currently decoded request
+    // but does not directly affect the ASI register value in the
+    // architectural state. The ASI values and the context field in the
+    // request packet seem to have completely different uses.
+    MiscReg reg_asi = tc->readMiscRegNoEffect(MISCREG_ASI);
+    ASI asi = static_cast<ASI>(reg_asi);
+
+    // The SPARC DTLB code assumes that traps are executed in context
+    // zero if the asi value is ASI_IMPLICIT (which is 0x0). There's also
+    // an assumption that the nucleus address space is being used, but
+    // the context is the relevant issue since we need to pass it to TLB.
+    bool trapped = bits(tlbdata, 18, 16) > 0;
+
+    // Given the assumptions in the translateData code in the SPARC DTLB,
+    // the logic works out to the following for the context.
+    int context_id = ((!hpriv && !red && is_real_address) ||
+                      asiIsReal(asi) ||
+                      (trapped && asi == ASI_IMPLICIT))
+                     ? 0 : primary_context;
+
+    // The partition id distinguishes between virtualized environments.
+    int const partition_id = 0;
+
+    // Insert the TLB entry.
+    // The entry specifying whether the address is "real" is set to
+    // false for syscall emulation mode regardless of whether the
+    // address is real in preceding code. Not sure sure that this is
+    // correct, but also not sure if it matters at all.
+    dynamic_cast<TLB *>(tc->getDTBPtr())->
+        insert(alignedvaddr, partition_id, context_id, false, entry->pte);
 }
 
 void
index baec0e7be822220f7a0e4805e4ac49a417c7be1e..057cea150bca0f37be074533389972fcb9381898 100644 (file)
@@ -163,16 +163,11 @@ RemoteGDB::acc(Addr va, size_t len)
     // from va to va + len have valid page map entries. Not
     // sure how this will work for other OSes or in general.
     if (FullSystem) {
-        if (va)
-            return true;
-        return false;
+        return va != 0;
     } else {
-        TlbEntry entry;
         // Check to make sure the first byte is mapped into the processes
         // address space.
-        if (context()->getProcessPtr()->pTable->lookup(va, entry))
-            return true;
-        return false;
+        return context()->getProcessPtr()->pTable->lookup(va) != nullptr;
     }
 }
 
index 175cabba3bba35e010dd7dd4c0e7b78e0bf581c1..956459373dd7ad668e9d8a014f5e97ba58b41bf8 100644 (file)
@@ -88,8 +88,7 @@ RemoteGDB::acc(Addr va, size_t len)
                                         BaseTLB::Read);
         return fault == NoFault;
     } else {
-        TlbEntry entry;
-        return context()->getProcessPtr()->pTable->lookup(va, entry);
+        return context()->getProcessPtr()->pTable->lookup(va) != nullptr;
     }
 }
 
index 0b1df9e21d30f9d67fc9520177fb13ace1c49540..93369494d3b85762a9a82b88d59668464a82f72d 100644 (file)
@@ -94,7 +94,7 @@ TLB::evictLRU()
 }
 
 TlbEntry *
-TLB::insert(Addr vpn, TlbEntry &entry)
+TLB::insert(Addr vpn, const TlbEntry &entry)
 {
     // If somebody beat us to it, just use that existing entry.
     TlbEntry *newEntry = trie.lookup(vpn);
@@ -357,23 +357,22 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
                     assert(entry);
                 } else {
                     Process *p = tc->getProcessPtr();
-                    TlbEntry newEntry;
-                    bool success = p->pTable->lookup(vaddr, newEntry);
-                    if (!success && mode != Execute) {
+                    TlbEntry *newEntry = p->pTable->lookup(vaddr);
+                    if (!newEntry && mode != Execute) {
                         // Check if we just need to grow the stack.
                         if (p->fixupStackFault(vaddr)) {
                             // If we did, lookup the entry for the new page.
-                            success = p->pTable->lookup(vaddr, newEntry);
+                            newEntry = p->pTable->lookup(vaddr);
                         }
                     }
-                    if (!success) {
+                    if (!newEntry) {
                         return std::make_shared<PageFault>(vaddr, true, mode,
                                                            true, false);
                     } else {
                         Addr alignedVaddr = p->pTable->pageAlign(vaddr);
                         DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr,
-                                newEntry.pageStart());
-                        entry = insert(alignedVaddr, newEntry);
+                                newEntry->pageStart());
+                        entry = insert(alignedVaddr, *newEntry);
                     }
                     DPRINTF(TLB, "Miss was serviced.\n");
                 }
index c3dc83bb2979357bbaf831d54514c02704e362d4..08804a45579aed2c359a0a251e4fad7a4fc99abb 100644 (file)
@@ -144,7 +144,7 @@ namespace X86ISA
         Fault finalizePhysical(RequestPtr req, ThreadContext *tc,
                                Mode mode) const override;
 
-        TlbEntry * insert(Addr vpn, TlbEntry &entry);
+        TlbEntry *insert(Addr vpn, const TlbEntry &entry);
 
         /*
          * Function to register Stats
index b5411f82c01a3a0571408f652f245820384604ab..9cbf3e8faaeaf6da847a9424cb085300ce1a0fa9 100644 (file)
@@ -808,31 +808,31 @@ namespace X86ISA
                                 "at pc %#x.\n", vaddr, tc->instAddr());
 
                         Process *p = tc->getProcessPtr();
-                        GpuTlbEntry newEntry;
-                        bool success = p->pTable->lookup(vaddr, newEntry);
+                        TlbEntry *newEntry = p->pTable->lookup(vaddr);
 
-                        if (!success && mode != BaseTLB::Execute) {
+                        if (!newEntry && mode != BaseTLB::Execute) {
                             // penalize a "page fault" more
-                            if (timing) {
+                            if (timing)
                                 latency += missLatency2;
-                            }
 
                             if (p->fixupStackFault(vaddr))
-                                success = p->pTable->lookup(vaddr, newEntry);
+                                newEntry = p->pTable->lookup(vaddr);
                         }
 
-                        if (!success) {
+                        if (!newEntry) {
                             return std::make_shared<PageFault>(vaddr, true,
                                                                mode, true,
                                                                false);
                         } else {
-                            newEntry.valid = success;
                             Addr alignedVaddr = p->pTable->pageAlign(vaddr);
 
                             DPRINTF(GPUTLB, "Mapping %#x to %#x\n",
-                                    alignedVaddr, newEntry.pageStart());
+                                    alignedVaddr, newEntry->pageStart());
 
-                            entry = insert(alignedVaddr, newEntry);
+                            GpuTlbEntry gpuEntry;
+                            *(TlbEntry *)&gpuEntry = *newEntry;
+                            gpuEntry.valid = true;
+                            entry = insert(alignedVaddr, gpuEntry);
                         }
 
                         DPRINTF(GPUTLB, "Miss was serviced.\n");
@@ -1330,25 +1330,27 @@ namespace X86ISA
                 safe_cast<TranslationState*>(pkt->senderState);
 
             Process *p = sender_state->tc->getProcessPtr();
-            TlbEntry newEntry;
             Addr vaddr = pkt->req->getVaddr();
     #ifndef NDEBUG
             Addr alignedVaddr = p->pTable->pageAlign(vaddr);
             assert(alignedVaddr == virtPageAddr);
     #endif
-            bool success;
-            success = p->pTable->lookup(vaddr, newEntry);
-            if (!success && sender_state->tlbMode != BaseTLB::Execute) {
-                if (p->fixupStackFault(vaddr)) {
-                    success = p->pTable->lookup(vaddr, newEntry);
-                }
+            TlbEntry *newEntry = p->pTable->lookup(vaddr);
+            if (!newEntry && sender_state->tlbMode != BaseTLB::Execute &&
+                    p->fixupStackFault(vaddr)) {
+                newEntry = p->pTable->lookup(vaddr);
             }
 
-            DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr,
-                    newEntry.pageStart());
+            if (newEntry) {
+                DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr,
+                        newEntry->pageStart());
 
-            sender_state->tlbEntry =
-                new GpuTlbEntry(0, newEntry.vaddr, newEntry.paddr, success);
+                sender_state->tlbEntry =
+                    new GpuTlbEntry(0, newEntry->vaddr, newEntry->paddr, true);
+            } else {
+                sender_state->tlbEntry =
+                    new GpuTlbEntry(0, 0, 0, false);
+            }
 
             handleTranslationReturn(virtPageAddr, TLB_MISS, pkt);
         } else if (outcome == MISS_RETURN) {
@@ -1524,7 +1526,6 @@ namespace X86ISA
                         virt_page_addr);
 
                 Process *p = tc->getProcessPtr();
-                TlbEntry newEntry;
 
                 Addr vaddr = pkt->req->getVaddr();
     #ifndef NDEBUG
@@ -1532,10 +1533,10 @@ namespace X86ISA
                 assert(alignedVaddr == virt_page_addr);
     #endif
 
-                bool success = p->pTable->lookup(vaddr, newEntry);
-                if (!success && sender_state->tlbMode != BaseTLB::Execute) {
-                    if (p->fixupStackFault(vaddr))
-                        success = p->pTable->lookup(vaddr, newEntry);
+                TlbEntry *newEntry = p->pTable->lookup(vaddr);
+                if (!newEntry && sender_state->tlbMode != BaseTLB::Execute &&
+                        p->fixupStackFault(vaddr)) {
+                    newEntry = p->pTable->lookup(vaddr);
                 }
 
                 if (!sender_state->prefetch) {
@@ -1544,24 +1545,23 @@ namespace X86ISA
                     assert(success);
 
                     DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr,
-                           newEntry.pageStart());
+                           newEntry->pageStart());
 
-                    sender_state->tlbEntry = new GpuTlbEntry(0, newEntry.vaddr,
-                                                             newEntry.paddr,
-                                                             success);
+                    sender_state->tlbEntry =
+                        new GpuTlbEntry(0, newEntry->vaddr,
+                                        newEntry->paddr, success);
                 } else {
                     // If this was a prefetch, then do the normal thing if it
                     // was a successful translation.  Otherwise, send an empty
                     // TLB entry back so that it can be figured out as empty and
                     // handled accordingly.
-                    if (success) {
+                    if (newEntry) {
                         DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr,
-                               newEntry.pageStart());
+                               newEntry->pageStart());
 
-                        sender_state->tlbEntry = new GpuTlbEntry(0,
-                                                                 newEntry.vaddr,
-                                                                 newEntry.paddr,
-                                                                 success);
+                        sender_state->tlbEntry =
+                            new GpuTlbEntry(0, newEntry->vaddr,
+                                            newEntry->paddr, success);
                     } else {
                         DPRINTF(GPUPrefetch, "Prefetch failed %#x\n",
                                 alignedVaddr);
index 3854a8ccd176b095d3879a41a96e2e22ebfdb5ee..26cc6e5370b4f8c4b9c7aced56d32313a49009ae 100644 (file)
@@ -146,29 +146,25 @@ EmulationPageTable::isUnmapped(Addr vaddr, int64_t size)
     return true;
 }
 
-bool
-EmulationPageTable::lookup(Addr vaddr, TheISA::TlbEntry &entry)
+TheISA::TlbEntry *
+EmulationPageTable::lookup(Addr vaddr)
 {
     Addr page_addr = pageAlign(vaddr);
-
     PTableItr iter = pTable.find(page_addr);
-
     if (iter == pTable.end())
-        return false;
-
-    entry = *iter->second;
-    return true;
+        return nullptr;
+    return iter->second;
 }
 
 bool
 EmulationPageTable::translate(Addr vaddr, Addr &paddr)
 {
-    TheISA::TlbEntry entry;
-    if (!lookup(vaddr, entry)) {
+    TheISA::TlbEntry *entry = lookup(vaddr);
+    if (!entry) {
         DPRINTF(MMU, "Couldn't Translate: %#x\n", vaddr);
         return false;
     }
-    paddr = pageOffset(vaddr) + entry.pageStart();
+    paddr = pageOffset(vaddr) + entry->pageStart();
     DPRINTF(MMU, "Translating: %#x->%#x\n", vaddr, paddr);
     return true;
 }
index 30437a6f9e70a7d863027df353ac8b90009ce323..470a3e7d6ab9588a81e52d74cad7b6987ebf1e32 100644 (file)
@@ -121,9 +121,9 @@ class EmulationPageTable : public Serializable
     /**
      * Lookup function
      * @param vaddr The virtual address.
-     * @return entry The page table entry corresponding to vaddr.
+     * @return The page table entry corresponding to vaddr.
      */
-    virtual bool lookup(Addr vaddr, TheISA::TlbEntry &entry);
+    virtual TheISA::TlbEntry *lookup(Addr vaddr);
 
     /**
      * Translate function