summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/multi_level_page_table.hh2
-rw-r--r--src/mem/multi_level_page_table_impl.hh12
-rw-r--r--src/mem/page_table.cc84
-rw-r--r--src/mem/page_table.hh132
-rw-r--r--src/mem/se_translating_port_proxy.hh6
5 files changed, 56 insertions, 180 deletions
diff --git a/src/mem/multi_level_page_table.hh b/src/mem/multi_level_page_table.hh
index 952c2b068..10e411eb1 100644
--- a/src/mem/multi_level_page_table.hh
+++ b/src/mem/multi_level_page_table.hh
@@ -100,7 +100,7 @@ class System;
* @see MultiLevelPageTable
*/
template <class ISAOps>
-class MultiLevelPageTable : public FuncPageTable
+class MultiLevelPageTable : public EmulationPageTable
{
/**
* ISA specific operations
diff --git a/src/mem/multi_level_page_table_impl.hh b/src/mem/multi_level_page_table_impl.hh
index 702c08c0a..3222f5f11 100644
--- a/src/mem/multi_level_page_table_impl.hh
+++ b/src/mem/multi_level_page_table_impl.hh
@@ -48,7 +48,7 @@ template <class ISAOps>
MultiLevelPageTable<ISAOps>::MultiLevelPageTable(const std::string &__name,
uint64_t _pid, System *_sys,
Addr pageSize)
- : FuncPageTable(__name, _pid, pageSize), system(_sys),
+ : EmulationPageTable(__name, _pid, pageSize), system(_sys),
logLevelSize(PageTableLayout),
numLevels(logLevelSize.size())
{
@@ -136,7 +136,7 @@ void
MultiLevelPageTable<ISAOps>::map(Addr vaddr, Addr paddr,
int64_t size, uint64_t flags)
{
- FuncPageTable::map(vaddr, paddr, size, flags);
+ EmulationPageTable::map(vaddr, paddr, size, flags);
PortProxy &p = system->physProxy;
@@ -165,7 +165,7 @@ template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::remap(Addr vaddr, int64_t size, Addr new_vaddr)
{
- FuncPageTable::remap(vaddr, size, new_vaddr);
+ EmulationPageTable::remap(vaddr, size, new_vaddr);
PortProxy &p = system->physProxy;
@@ -199,7 +199,7 @@ template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::unmap(Addr vaddr, int64_t size)
{
- FuncPageTable::unmap(vaddr, size);
+ EmulationPageTable::unmap(vaddr, size);
PortProxy &p = system->physProxy;
@@ -222,7 +222,7 @@ template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::serialize(CheckpointOut &cp) const
{
- FuncPageTable::serialize(cp);
+ EmulationPageTable::serialize(cp);
/** Since, the page table is stored in system memory
* which is serialized separately, we will serialize
* just the base pointer
@@ -234,6 +234,6 @@ template <class ISAOps>
void
MultiLevelPageTable<ISAOps>::unserialize(CheckpointIn &cp)
{
- FuncPageTable::unserialize(cp);
+ EmulationPageTable::unserialize(cp);
paramIn(cp, "ptable.pointer", basePtr);
}
diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc
index 4f06c29e8..3854a8ccd 100644
--- a/src/mem/page_table.cc
+++ b/src/mem/page_table.cc
@@ -48,35 +48,29 @@
using namespace std;
using namespace TheISA;
-FuncPageTable::FuncPageTable(const std::string &__name,
- uint64_t _pid, Addr _pageSize)
- : PageTableBase(__name, _pid, _pageSize)
-{
-}
-
-FuncPageTable::~FuncPageTable()
+EmulationPageTable::~EmulationPageTable()
{
for (auto &iter : pTable)
delete iter.second;
}
void
-FuncPageTable::map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags)
+EmulationPageTable::map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags)
{
bool clobber = flags & Clobber;
// starting address must be page aligned
assert(pageOffset(vaddr) == 0);
- DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr+ size);
+ DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr + size);
- for (; size > 0; size -= pageSize, vaddr += pageSize, paddr += pageSize) {
+ while (size > 0) {
auto it = pTable.find(vaddr);
if (it != pTable.end()) {
if (clobber) {
delete it->second;
} else {
// already mapped
- fatal("FuncPageTable::allocate: addr %#x already mapped",
+ fatal("EmulationPageTable::allocate: addr %#x already mapped",
vaddr);
}
} else {
@@ -86,13 +80,14 @@ FuncPageTable::map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags)
it->second = new TheISA::TlbEntry(pid, vaddr, paddr,
flags & Uncacheable,
flags & ReadOnly);
- eraseCacheEntry(vaddr);
- updateCache(vaddr, pTable[vaddr]);
+ size -= pageSize;
+ vaddr += pageSize;
+ paddr += pageSize;
}
}
void
-FuncPageTable::remap(Addr vaddr, int64_t size, Addr new_vaddr)
+EmulationPageTable::remap(Addr vaddr, int64_t size, Addr new_vaddr)
{
assert(pageOffset(vaddr) == 0);
assert(pageOffset(new_vaddr) == 0);
@@ -100,91 +95,73 @@ FuncPageTable::remap(Addr vaddr, int64_t size, Addr new_vaddr)
DPRINTF(MMU, "moving pages from vaddr %08p to %08p, size = %d\n", vaddr,
new_vaddr, size);
- for (; size > 0;
- size -= pageSize, vaddr += pageSize, new_vaddr += pageSize)
- {
+ while (size > 0) {
auto new_it = pTable.find(new_vaddr);
auto old_it = pTable.find(vaddr);
assert(old_it != pTable.end() && new_it == pTable.end());
new_it->second = old_it->second;
pTable.erase(old_it);
- eraseCacheEntry(vaddr);
new_it->second->updateVaddr(new_vaddr);
- updateCache(new_vaddr, new_it->second);
+ size -= pageSize;
+ vaddr += pageSize;
+ new_vaddr += pageSize;
}
}
void
-FuncPageTable::getMappings(std::vector<std::pair<Addr, Addr>> *addr_maps)
+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()));
}
void
-FuncPageTable::unmap(Addr vaddr, int64_t size)
+EmulationPageTable::unmap(Addr vaddr, int64_t size)
{
assert(pageOffset(vaddr) == 0);
DPRINTF(MMU, "Unmapping page: %#x-%#x\n", vaddr, vaddr+ size);
- for (; size > 0; size -= pageSize, vaddr += pageSize) {
+ while (size > 0) {
auto it = pTable.find(vaddr);
assert(it != pTable.end());
- eraseCacheEntry(vaddr);
delete it->second;
pTable.erase(it);
+ size -= pageSize;
+ vaddr += pageSize;
}
-
}
bool
-FuncPageTable::isUnmapped(Addr vaddr, int64_t size)
+EmulationPageTable::isUnmapped(Addr vaddr, int64_t size)
{
// starting address must be page aligned
assert(pageOffset(vaddr) == 0);
- for (; size > 0; size -= pageSize, vaddr += pageSize) {
- if (pTable.find(vaddr) != pTable.end()) {
+ for (int64_t offset = 0; offset < size; offset += pageSize)
+ if (pTable.find(vaddr + offset) != pTable.end())
return false;
- }
- }
return true;
}
bool
-FuncPageTable::lookup(Addr vaddr, TheISA::TlbEntry &entry)
+EmulationPageTable::lookup(Addr vaddr, TheISA::TlbEntry &entry)
{
Addr page_addr = pageAlign(vaddr);
- if (pTableCache[0].entry && pTableCache[0].vaddr == page_addr) {
- entry = *pTableCache[0].entry;
- return true;
- }
- if (pTableCache[1].entry && pTableCache[1].vaddr == page_addr) {
- entry = *pTableCache[1].entry;
- return true;
- }
- if (pTableCache[2].entry && pTableCache[2].vaddr == page_addr) {
- entry = *pTableCache[2].entry;
- return true;
- }
-
PTableItr iter = pTable.find(page_addr);
- if (iter == pTable.end()) {
+ if (iter == pTable.end())
return false;
- }
- updateCache(page_addr, iter->second);
entry = *iter->second;
return true;
}
bool
-PageTableBase::translate(Addr vaddr, Addr &paddr)
+EmulationPageTable::translate(Addr vaddr, Addr &paddr)
{
TheISA::TlbEntry entry;
if (!lookup(vaddr, entry)) {
@@ -197,14 +174,13 @@ PageTableBase::translate(Addr vaddr, Addr &paddr)
}
Fault
-PageTableBase::translate(RequestPtr req)
+EmulationPageTable::translate(RequestPtr req)
{
Addr paddr;
- assert(pageAlign(req->getVaddr() + req->getSize() - 1)
- == pageAlign(req->getVaddr()));
- if (!translate(req->getVaddr(), paddr)) {
+ assert(pageAlign(req->getVaddr() + req->getSize() - 1) ==
+ pageAlign(req->getVaddr()));
+ if (!translate(req->getVaddr(), paddr))
return Fault(new GenericPageTableFault(req->getVaddr()));
- }
req->setPaddr(paddr);
if ((paddr & (pageSize - 1)) + req->getSize() > pageSize) {
panic("Request spans page boundaries!\n");
@@ -214,7 +190,7 @@ PageTableBase::translate(RequestPtr req)
}
void
-FuncPageTable::serialize(CheckpointOut &cp) const
+EmulationPageTable::serialize(CheckpointOut &cp) const
{
paramOut(cp, "ptable.size", pTable.size());
@@ -229,7 +205,7 @@ FuncPageTable::serialize(CheckpointOut &cp) const
}
void
-FuncPageTable::unserialize(CheckpointIn &cp)
+EmulationPageTable::unserialize(CheckpointIn &cp)
{
int count;
paramIn(cp, "ptable.size", count);
diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh
index fa584873a..30437a6f9 100644
--- a/src/mem/page_table.hh
+++ b/src/mem/page_table.hh
@@ -49,20 +49,13 @@
#include "sim/serialize.hh"
class ThreadContext;
-class System;
-/**
- * Declaration of base class for page table
- */
-class PageTableBase : public Serializable
+class EmulationPageTable : public Serializable
{
protected:
- struct cacheElement {
- Addr vaddr;
- TheISA::TlbEntry *entry;
- };
-
- struct cacheElement pTableCache[3];
+ typedef std::unordered_map<Addr, TheISA::TlbEntry *> PTable;
+ typedef PTable::iterator PTableItr;
+ PTable pTable;
const Addr pageSize;
const Addr offsetMask;
@@ -72,17 +65,15 @@ class PageTableBase : public Serializable
public:
- PageTableBase(const std::string &__name, uint64_t _pid, Addr _pageSize)
- : pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))),
- pid(_pid), _name(__name)
+ EmulationPageTable(
+ const std::string &__name, uint64_t _pid, Addr _pageSize) :
+ pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))),
+ pid(_pid), _name(__name)
{
assert(isPowerOf2(pageSize));
- pTableCache[0].entry = nullptr;
- pTableCache[1].entry = nullptr;
- pTableCache[2].entry = nullptr;
}
- virtual ~PageTableBase() {};
+ virtual ~EmulationPageTable();
/* generic page table mapping flags
* unset | set
@@ -99,7 +90,7 @@ class PageTableBase : public Serializable
ReadOnly = 8,
};
- virtual void initState(ThreadContext* tc) = 0;
+ virtual void initState(ThreadContext* tc) {};
// for DPRINTF compatibility
const std::string name() const { return _name; }
@@ -115,10 +106,9 @@ class PageTableBase : public Serializable
* @param flags Generic mapping flags that can be set by or-ing values
* from MappingFlags enum.
*/
- virtual void map(Addr vaddr, Addr paddr, int64_t size,
- uint64_t flags = 0) = 0;
- virtual void remap(Addr vaddr, int64_t size, Addr new_vaddr) = 0;
- virtual void unmap(Addr vaddr, int64_t size) = 0;
+ virtual void map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags = 0);
+ virtual void remap(Addr vaddr, int64_t size, Addr new_vaddr);
+ virtual void unmap(Addr vaddr, int64_t size);
/**
* Check if any pages in a region are already allocated
@@ -126,14 +116,14 @@ class PageTableBase : public Serializable
* @param size The length of the region.
* @return True if no pages in the region are mapped.
*/
- virtual bool isUnmapped(Addr vaddr, int64_t size) = 0;
+ virtual bool isUnmapped(Addr vaddr, int64_t size);
/**
* Lookup function
* @param vaddr The virtual address.
* @return entry The page table entry corresponding to vaddr.
*/
- virtual bool lookup(Addr vaddr, TheISA::TlbEntry &entry) = 0;
+ virtual bool lookup(Addr vaddr, TheISA::TlbEntry &entry);
/**
* Translate function
@@ -157,100 +147,10 @@ class PageTableBase : public Serializable
*/
Fault translate(RequestPtr req);
- /**
- * Update the page table cache.
- * @param vaddr virtual address (page aligned) to check
- * @param pte page table entry to return
- * @return A pointer to any entry which is displaced from the cache.
- */
- TheISA::TlbEntry *
- updateCache(Addr vaddr, TheISA::TlbEntry *entry)
- {
- TheISA::TlbEntry *evicted = pTableCache[2].entry;
-
- pTableCache[2].entry = pTableCache[1].entry;
- pTableCache[2].vaddr = pTableCache[1].vaddr;
-
- pTableCache[1].entry = pTableCache[0].entry;
- pTableCache[1].vaddr = pTableCache[0].vaddr;
-
- pTableCache[0].entry = entry;
- pTableCache[0].vaddr = vaddr;
-
- return evicted;
- }
-
- /**
- * Erase an entry from the page table cache.
- * @param vaddr virtual address (page aligned) to check
- * @return A pointer to the entry (if any) which is kicked out.
- */
- TheISA::TlbEntry *
- eraseCacheEntry(Addr vaddr)
- {
- TheISA::TlbEntry *evicted = nullptr;
- // Invalidate cached entries if necessary
- if (pTableCache[0].entry && pTableCache[0].vaddr == vaddr) {
- evicted = pTableCache[0].entry;
- pTableCache[0].entry = nullptr;
- } else if (pTableCache[1].entry && pTableCache[1].vaddr == vaddr) {
- evicted = pTableCache[1].entry;
- pTableCache[1].entry = nullptr;
- } else if (pTableCache[2].entry && pTableCache[2].vaddr == vaddr) {
- evicted = pTableCache[2].entry;
- pTableCache[2].entry = nullptr;
- }
- return evicted;
- }
-
- virtual void getMappings(std::vector<std::pair<Addr, Addr>>
- *addr_mappings) {};
-};
-
-/**
- * Declaration of functional page table.
- */
-class FuncPageTable : public PageTableBase
-{
- private:
- typedef std::unordered_map<Addr, TheISA::TlbEntry *> PTable;
- typedef PTable::iterator PTableItr;
- PTable pTable;
-
- public:
-
- FuncPageTable(const std::string &__name, uint64_t _pid, Addr _pageSize);
-
- ~FuncPageTable();
-
- void initState(ThreadContext* tc) override
- {
- }
-
- void map(Addr vaddr, Addr paddr, int64_t size,
- uint64_t flags = 0) override;
- void remap(Addr vaddr, int64_t size, Addr new_vaddr) override;
- void unmap(Addr vaddr, int64_t size) override;
-
- /**
- * Check if any pages in a region are already allocated
- * @param vaddr The starting virtual address of the region.
- * @param size The length of the region.
- * @return True if no pages in the region are mapped.
- */
- bool isUnmapped(Addr vaddr, int64_t size) override;
-
- /**
- * Lookup function
- * @param vaddr The virtual address.
- * @return entry The page table entry corresponding to vaddr.
- */
- bool lookup(Addr vaddr, TheISA::TlbEntry &entry) override;
+ void getMappings(std::vector<std::pair<Addr, Addr>> *addr_mappings);
void serialize(CheckpointOut &cp) const override;
void unserialize(CheckpointIn &cp) override;
-
- void getMappings(std::vector<std::pair<Addr, Addr>> *addr_maps) override;
};
#endif // __MEM_PAGE_TABLE_HH__
diff --git a/src/mem/se_translating_port_proxy.hh b/src/mem/se_translating_port_proxy.hh
index 5ac6b5286..2f2a81b59 100644
--- a/src/mem/se_translating_port_proxy.hh
+++ b/src/mem/se_translating_port_proxy.hh
@@ -47,7 +47,7 @@
#include "mem/port_proxy.hh"
-class PageTableBase;
+class EmulationPageTable;
class Process;
/**
@@ -75,7 +75,7 @@ class SETranslatingPortProxy : public PortProxy
};
private:
- PageTableBase *pTable;
+ EmulationPageTable *pTable;
Process *process;
AllocType allocating;
@@ -83,7 +83,7 @@ class SETranslatingPortProxy : public PortProxy
SETranslatingPortProxy(MasterPort& port, Process* p, AllocType alloc);
virtual ~SETranslatingPortProxy();
- void setPageTable(PageTableBase *p) { pTable = p; }
+ void setPageTable(EmulationPageTable *p) { pTable = p; }
void setProcess(Process *p) { process = p; }
bool tryReadBlob(Addr addr, uint8_t *p, int size) const;
bool tryWriteBlob(Addr addr, const uint8_t *p, int size) const;