diff options
-rw-r--r-- | src/arch/alpha/faults.cc | 29 | ||||
-rw-r--r-- | src/arch/arm/remote_gdb.cc | 9 | ||||
-rw-r--r-- | src/arch/mips/remote_gdb.cc | 11 | ||||
-rw-r--r-- | src/arch/power/remote_gdb.cc | 17 | ||||
-rw-r--r-- | src/arch/riscv/remote_gdb.cc | 7 | ||||
-rw-r--r-- | src/arch/sparc/faults.cc | 232 | ||||
-rw-r--r-- | src/arch/sparc/remote_gdb.cc | 9 | ||||
-rw-r--r-- | src/arch/x86/remote_gdb.cc | 3 | ||||
-rw-r--r-- | src/arch/x86/tlb.cc | 15 | ||||
-rw-r--r-- | src/arch/x86/tlb.hh | 2 | ||||
-rw-r--r-- | src/gpu-compute/gpu_tlb.cc | 72 | ||||
-rw-r--r-- | src/mem/page_table.cc | 18 | ||||
-rw-r--r-- | src/mem/page_table.hh | 4 |
13 files changed, 194 insertions, 234 deletions
diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index 4a829cd9b..89b0ecea8 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -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 diff --git a/src/arch/arm/remote_gdb.cc b/src/arch/arm/remote_gdb.cc index f12734182..f1919372b 100644 --- a/src/arch/arm/remote_gdb.cc +++ b/src/arch/arm/remote_gdb.cc @@ -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; } } diff --git a/src/arch/mips/remote_gdb.cc b/src/arch/mips/remote_gdb.cc index e17f8fd1d..d490fa518 100644 --- a/src/arch/mips/remote_gdb.cc +++ b/src/arch/mips/remote_gdb.cc @@ -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 diff --git a/src/arch/power/remote_gdb.cc b/src/arch/power/remote_gdb.cc index 7bdd3ba6a..b4082e0ee 100644 --- a/src/arch/power/remote_gdb.cc +++ b/src/arch/power/remote_gdb.cc @@ -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 diff --git a/src/arch/riscv/remote_gdb.cc b/src/arch/riscv/remote_gdb.cc index 4f423fc01..f4e606e27 100644 --- a/src/arch/riscv/remote_gdb.cc +++ b/src/arch/riscv/remote_gdb.cc @@ -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 diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 5466115d0..0b6a28927 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -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 diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc index baec0e7be..057cea150 100644 --- a/src/arch/sparc/remote_gdb.cc +++ b/src/arch/sparc/remote_gdb.cc @@ -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; } } diff --git a/src/arch/x86/remote_gdb.cc b/src/arch/x86/remote_gdb.cc index 175cabba3..956459373 100644 --- a/src/arch/x86/remote_gdb.cc +++ b/src/arch/x86/remote_gdb.cc @@ -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; } } diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 0b1df9e21..93369494d 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -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"); } diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh index c3dc83bb2..08804a455 100644 --- a/src/arch/x86/tlb.hh +++ b/src/arch/x86/tlb.hh @@ -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 diff --git a/src/gpu-compute/gpu_tlb.cc b/src/gpu-compute/gpu_tlb.cc index b5411f82c..9cbf3e8fa 100644 --- a/src/gpu-compute/gpu_tlb.cc +++ b/src/gpu-compute/gpu_tlb.cc @@ -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); diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc index 3854a8ccd..26cc6e537 100644 --- a/src/mem/page_table.cc +++ b/src/mem/page_table.cc @@ -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; } diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh index 30437a6f9..470a3e7d6 100644 --- a/src/mem/page_table.hh +++ b/src/mem/page_table.hh @@ -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 |