diff options
-rw-r--r-- | src/arch/alpha/faults.cc | 22 | ||||
-rw-r--r-- | src/arch/sparc/faults.cc | 25 | ||||
-rw-r--r-- | src/arch/x86/tlb.cc | 16 | ||||
-rw-r--r-- | src/gpu-compute/gpu_tlb.cc | 50 | ||||
-rw-r--r-- | src/mem/page_table.cc | 53 | ||||
-rw-r--r-- | src/mem/page_table.hh | 25 | ||||
-rw-r--r-- | src/sim/syscall_emul.hh | 1 |
7 files changed, 105 insertions, 87 deletions
diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index 89b0ecea8..3433844c1 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -196,11 +196,14 @@ ItbPageFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) } Process *p = tc->getProcessPtr(); - TlbEntry *entry = p->pTable->lookup(pc); - panic_if(!entry, "Tried to execute unmapped address %#x.\n", pc); + const EmulationPageTable::Entry *pte = p->pTable->lookup(pc); + panic_if(!pte, "Tried to execute unmapped address %#x.\n", pc); VAddr vaddr(pc); - dynamic_cast<TLB *>(tc->getITBPtr())->insert(vaddr.page(), *entry); + TlbEntry entry(p->pTable->pid(), vaddr.page(), pte->paddr, + pte->flags & EmulationPageTable::Uncacheable, + pte->flags & EmulationPageTable::ReadOnly); + dynamic_cast<TLB *>(tc->getITBPtr())->insert(vaddr.page(), entry); } void @@ -212,11 +215,14 @@ NDtbMissFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) } Process *p = tc->getProcessPtr(); - 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); + const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr); + if (!pte && p->fixupStackFault(vaddr)) + pte = p->pTable->lookup(vaddr); + panic_if(!pte, "Tried to access unmapped address %#x.\n", (Addr)vaddr); + TlbEntry entry(p->pTable->pid(), vaddr.page(), pte->paddr, + pte->flags & EmulationPageTable::Uncacheable, + pte->flags & EmulationPageTable::ReadOnly); + dynamic_cast<TLB *>(tc->getDTBPtr())->insert(vaddr.page(), entry); } } // namespace AlphaISA diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 0b6a28927..0f042b4ae 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -35,6 +35,7 @@ #include "arch/sparc/isa_traits.hh" #include "arch/sparc/process.hh" +#include "arch/sparc/tlb.hh" #include "arch/sparc/types.hh" #include "base/bitfield.hh" #include "base/trace.hh" @@ -629,8 +630,8 @@ FastInstructionAccessMMUMiss::invoke(ThreadContext *tc, } Process *p = tc->getProcessPtr(); - TlbEntry *entry = p->pTable->lookup(vaddr); - panic_if(!entry, "Tried to execute unmapped address %#x.\n", vaddr); + const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr); + panic_if(!pte, "Tried to execute unmapped address %#x.\n", vaddr); Addr alignedvaddr = p->pTable->pageAlign(vaddr); @@ -662,13 +663,17 @@ FastInstructionAccessMMUMiss::invoke(ThreadContext *tc, // the logic works out to the following for the context. int context_id = (is_real_address || trapped) ? 0 : primary_context; + TlbEntry entry(p->pTable->pid(), alignedvaddr, pte->paddr, + pte->flags & EmulationPageTable::Uncacheable, + pte->flags & EmulationPageTable::ReadOnly); + // 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); + insert(alignedvaddr, partition_id, context_id, false, entry.pte); } void @@ -680,10 +685,10 @@ FastDataAccessMMUMiss::invoke(ThreadContext *tc, const StaticInstPtr &inst) } Process *p = tc->getProcessPtr(); - 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); + const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr); + if (!pte && p->fixupStackFault(vaddr)) + pte = p->pTable->lookup(vaddr); + panic_if(!pte, "Tried to access unmapped address %#x.\n", vaddr); Addr alignedvaddr = p->pTable->pageAlign(vaddr); @@ -745,13 +750,17 @@ FastDataAccessMMUMiss::invoke(ThreadContext *tc, const StaticInstPtr &inst) // The partition id distinguishes between virtualized environments. int const partition_id = 0; + TlbEntry entry(p->pTable->pid(), alignedvaddr, pte->paddr, + pte->flags & EmulationPageTable::Uncacheable, + pte->flags & EmulationPageTable::ReadOnly); + // 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); + insert(alignedvaddr, partition_id, context_id, false, entry.pte); } void diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 93369494d..a3aec1676 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -357,22 +357,26 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, assert(entry); } else { Process *p = tc->getProcessPtr(); - TlbEntry *newEntry = p->pTable->lookup(vaddr); - if (!newEntry && mode != Execute) { + const EmulationPageTable::Entry *pte = + p->pTable->lookup(vaddr); + if (!pte && 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. - newEntry = p->pTable->lookup(vaddr); + pte = p->pTable->lookup(vaddr); } } - if (!newEntry) { + if (!pte) { 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); + pte->paddr); + entry = insert(alignedVaddr, TlbEntry( + p->pTable->pid(), alignedVaddr, pte->paddr, + pte->flags & EmulationPageTable::Uncacheable, + pte->flags & EmulationPageTable::ReadOnly)); } DPRINTF(TLB, "Miss was serviced.\n"); } diff --git a/src/gpu-compute/gpu_tlb.cc b/src/gpu-compute/gpu_tlb.cc index 9cbf3e8fa..05d22dad6 100644 --- a/src/gpu-compute/gpu_tlb.cc +++ b/src/gpu-compute/gpu_tlb.cc @@ -808,18 +808,19 @@ namespace X86ISA "at pc %#x.\n", vaddr, tc->instAddr()); Process *p = tc->getProcessPtr(); - TlbEntry *newEntry = p->pTable->lookup(vaddr); + const EmulationPageTable::Entry *pte = + p->pTable->lookup(vaddr); - if (!newEntry && mode != BaseTLB::Execute) { + if (!pte && mode != BaseTLB::Execute) { // penalize a "page fault" more if (timing) latency += missLatency2; if (p->fixupStackFault(vaddr)) - newEntry = p->pTable->lookup(vaddr); + pte = p->pTable->lookup(vaddr); } - if (!newEntry) { + if (!pte) { return std::make_shared<PageFault>(vaddr, true, mode, true, false); @@ -827,11 +828,11 @@ namespace X86ISA Addr alignedVaddr = p->pTable->pageAlign(vaddr); DPRINTF(GPUTLB, "Mapping %#x to %#x\n", - alignedVaddr, newEntry->pageStart()); + alignedVaddr, pte->paddr); - GpuTlbEntry gpuEntry; - *(TlbEntry *)&gpuEntry = *newEntry; - gpuEntry.valid = true; + GpuTlbEntry gpuEntry( + p->pTable->pid(), alignedVaddr, + pte->paddr, true); entry = insert(alignedVaddr, gpuEntry); } @@ -1335,18 +1336,18 @@ namespace X86ISA Addr alignedVaddr = p->pTable->pageAlign(vaddr); assert(alignedVaddr == virtPageAddr); #endif - TlbEntry *newEntry = p->pTable->lookup(vaddr); - if (!newEntry && sender_state->tlbMode != BaseTLB::Execute && + const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr); + if (!pte && sender_state->tlbMode != BaseTLB::Execute && p->fixupStackFault(vaddr)) { - newEntry = p->pTable->lookup(vaddr); + pte = p->pTable->lookup(vaddr); } - if (newEntry) { + if (pte) { DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr, - newEntry->pageStart()); + pte->paddr); sender_state->tlbEntry = - new GpuTlbEntry(0, newEntry->vaddr, newEntry->paddr, true); + new GpuTlbEntry(0, virtPageAddr, pte->paddr, true); } else { sender_state->tlbEntry = new GpuTlbEntry(0, 0, 0, false); @@ -1533,10 +1534,11 @@ namespace X86ISA assert(alignedVaddr == virt_page_addr); #endif - TlbEntry *newEntry = p->pTable->lookup(vaddr); - if (!newEntry && sender_state->tlbMode != BaseTLB::Execute && + const EmulationPageTable::Entry *pte = + p->pTable->lookup(vaddr); + if (!pte && sender_state->tlbMode != BaseTLB::Execute && p->fixupStackFault(vaddr)) { - newEntry = p->pTable->lookup(vaddr); + pte = p->pTable->lookup(vaddr); } if (!sender_state->prefetch) { @@ -1545,23 +1547,23 @@ namespace X86ISA assert(success); DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr, - newEntry->pageStart()); + pte->paddr); sender_state->tlbEntry = - new GpuTlbEntry(0, newEntry->vaddr, - newEntry->paddr, success); + new GpuTlbEntry(0, virt_page_addr, + pte->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 (newEntry) { + if (pte) { DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr, - newEntry->pageStart()); + pte->paddr); sender_state->tlbEntry = - new GpuTlbEntry(0, newEntry->vaddr, - newEntry->paddr, success); + new GpuTlbEntry(0, virt_page_addr, + pte->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 ee504196a..8a11ada76 100644 --- a/src/mem/page_table.cc +++ b/src/mem/page_table.cc @@ -40,19 +40,11 @@ #include <string> #include "base/trace.hh" -#include "config/the_isa.hh" #include "debug/MMU.hh" #include "sim/faults.hh" #include "sim/serialize.hh" using namespace std; -using namespace TheISA; - -EmulationPageTable::~EmulationPageTable() -{ - for (auto &iter : pTable) - delete iter.second; -} void EmulationPageTable::map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags) @@ -66,20 +58,15 @@ EmulationPageTable::map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags) while (size > 0) { auto it = pTable.find(vaddr); if (it != pTable.end()) { - if (clobber) { - delete it->second; - } else { - // already mapped - panic("EmulationPageTable::allocate: addr %#x already mapped", - vaddr); - } + // already mapped + panic_if(!clobber, + "EmulationPageTable::allocate: addr %#x already mapped", + vaddr); + it->second = Entry(paddr, flags); } else { - it = pTable.emplace(vaddr, nullptr).first; + pTable.emplace(vaddr, Entry(paddr, flags)); } - it->second = new TheISA::TlbEntry(pid, vaddr, paddr, - flags & Uncacheable, - flags & ReadOnly); size -= pageSize; vaddr += pageSize; paddr += pageSize; @@ -102,7 +89,6 @@ EmulationPageTable::remap(Addr vaddr, int64_t size, Addr new_vaddr) new_it->second = old_it->second; pTable.erase(old_it); - new_it->second->updateVaddr(new_vaddr); size -= pageSize; vaddr += pageSize; new_vaddr += pageSize; @@ -113,7 +99,7 @@ void EmulationPageTable::getMappings(std::vector<std::pair<Addr, Addr>> *addr_maps) { for (auto &iter : pTable) - addr_maps->push_back(make_pair(iter.first, iter.second->pageStart())); + addr_maps->push_back(make_pair(iter.first, iter.second.paddr)); } void @@ -121,12 +107,11 @@ EmulationPageTable::unmap(Addr vaddr, int64_t size) { assert(pageOffset(vaddr) == 0); - DPRINTF(MMU, "Unmapping page: %#x-%#x\n", vaddr, vaddr+ size); + DPRINTF(MMU, "Unmapping page: %#x-%#x\n", vaddr, vaddr + size); while (size > 0) { auto it = pTable.find(vaddr); assert(it != pTable.end()); - delete it->second; pTable.erase(it); size -= pageSize; vaddr += pageSize; @@ -146,25 +131,25 @@ EmulationPageTable::isUnmapped(Addr vaddr, int64_t size) return true; } -TheISA::TlbEntry * +const EmulationPageTable::Entry * EmulationPageTable::lookup(Addr vaddr) { Addr page_addr = pageAlign(vaddr); PTableItr iter = pTable.find(page_addr); if (iter == pTable.end()) return nullptr; - return iter->second; + return &(iter->second); } bool EmulationPageTable::translate(Addr vaddr, Addr &paddr) { - TheISA::TlbEntry *entry = lookup(vaddr); + const Entry *entry = lookup(vaddr); if (!entry) { DPRINTF(MMU, "Couldn't Translate: %#x\n", vaddr); return false; } - paddr = pageOffset(vaddr) + entry->pageStart(); + paddr = pageOffset(vaddr) + entry->paddr; DPRINTF(MMU, "Translating: %#x->%#x\n", vaddr, paddr); return true; } @@ -195,7 +180,8 @@ EmulationPageTable::serialize(CheckpointOut &cp) const ScopedCheckpointSection sec(cp, csprintf("Entry%d", count++)); paramOut(cp, "vaddr", pte.first); - pte.second->serialize(cp); + paramOut(cp, "paddr", pte.second.paddr); + paramOut(cp, "flags", pte.second.flags); } assert(count == pTable.size()); } @@ -209,13 +195,14 @@ EmulationPageTable::unserialize(CheckpointIn &cp) for (int i = 0; i < count; ++i) { ScopedCheckpointSection sec(cp, csprintf("Entry%d", i)); - TheISA::TlbEntry *entry = new TheISA::TlbEntry(); - entry->unserialize(cp); - Addr vaddr; - paramIn(cp, "vaddr", vaddr); + UNSERIALIZE_SCALAR(vaddr); + Addr paddr; + uint64_t flags; + UNSERIALIZE_SCALAR(paddr); + UNSERIALIZE_SCALAR(flags); - pTable[vaddr] = entry; + pTable.emplace(vaddr, Entry(paddr, flags)); } } diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh index 733cdd2e3..fc0c0923e 100644 --- a/src/mem/page_table.hh +++ b/src/mem/page_table.hh @@ -40,11 +40,8 @@ #include <string> #include <unordered_map> -#include "arch/isa_traits.hh" -#include "arch/tlb.hh" #include "base/intmath.hh" #include "base/types.hh" -#include "config/the_isa.hh" #include "mem/request.hh" #include "sim/serialize.hh" @@ -52,15 +49,25 @@ class ThreadContext; class EmulationPageTable : public Serializable { + public: + struct Entry + { + Addr paddr; + uint64_t flags; + + Entry(Addr paddr, uint64_t flags) : paddr(paddr), flags(flags) {} + Entry() {} + }; + protected: - typedef std::unordered_map<Addr, TheISA::TlbEntry *> PTable; + typedef std::unordered_map<Addr, Entry> PTable; typedef PTable::iterator PTableItr; PTable pTable; const Addr pageSize; const Addr offsetMask; - const uint64_t pid; + const uint64_t _pid; const std::string _name; public: @@ -68,12 +75,14 @@ class EmulationPageTable : public Serializable EmulationPageTable( const std::string &__name, uint64_t _pid, Addr _pageSize) : pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))), - pid(_pid), _name(__name) + _pid(_pid), _name(__name) { assert(isPowerOf2(pageSize)); } - virtual ~EmulationPageTable(); + uint64_t pid() const { return _pid; }; + + virtual ~EmulationPageTable() {}; /* generic page table mapping flags * unset | set @@ -120,7 +129,7 @@ class EmulationPageTable : public Serializable * @param vaddr The virtual address. * @return The page table entry corresponding to vaddr. */ - virtual TheISA::TlbEntry *lookup(Addr vaddr); + const Entry *lookup(Addr vaddr); /** * Translate function diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index ef61299a0..eaa5e542c 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -93,6 +93,7 @@ #include <memory> #include <string> +#include "arch/generic/tlb.hh" #include "arch/utility.hh" #include "base/intmath.hh" #include "base/loader/object_file.hh" |