diff options
author | Gabe Black <gabeblack@google.com> | 2018-01-08 23:37:57 -0800 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-01-23 20:39:17 +0000 |
commit | a4e722725c90677d555675eca616c9d0990393f1 (patch) | |
tree | ed9a8268f73742fd4b4acbaf8e8434b67dc5fed7 /src/mem/page_table.cc | |
parent | db8c55dede65e07cb9ea8e95c48badd2ea24462f (diff) | |
download | gem5-a4e722725c90677d555675eca616c9d0990393f1.tar.xz |
tarch, mem: Abstract the data stored in the SE page tables.
Rather than store the actual TLB entry that corresponds to a mapping,
we can just store some abstracted information (address, a few flags)
and then let the caller turn that into the appropriate entry. There
could potentially be some small amount of overhead from creating
entries vs. storing them and just installing them, but it's likely
pretty minimal since that only happens on a TLB miss (ideally rare),
and, if it is problematic, there could be some preallocated TLB
entries which are just minimally filled in as necessary.
This has the nice effect of finally making the page tables ISA
agnostic.
Change-Id: I11e630f60682f0a0029b0683eb8ff0135fbd4317
Reviewed-on: https://gem5-review.googlesource.com/7350
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/mem/page_table.cc')
-rw-r--r-- | src/mem/page_table.cc | 53 |
1 files changed, 20 insertions, 33 deletions
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)); } } |