diff options
-rw-r--r-- | src/arch/alpha/process.cc | 3 | ||||
-rw-r--r-- | src/arch/arm/process.cc | 5 | ||||
-rw-r--r-- | src/arch/mips/process.cc | 3 | ||||
-rw-r--r-- | src/arch/power/process.cc | 3 | ||||
-rw-r--r-- | src/arch/riscv/process.cc | 4 | ||||
-rw-r--r-- | src/arch/sparc/process.cc | 3 | ||||
-rw-r--r-- | src/arch/x86/process.cc | 7 | ||||
-rw-r--r-- | src/mem/multi_level_page_table.hh | 2 | ||||
-rw-r--r-- | src/mem/multi_level_page_table_impl.hh | 12 | ||||
-rw-r--r-- | src/mem/page_table.cc | 84 | ||||
-rw-r--r-- | src/mem/page_table.hh | 132 | ||||
-rw-r--r-- | src/mem/se_translating_port_proxy.hh | 6 | ||||
-rw-r--r-- | src/sim/process.cc | 8 | ||||
-rw-r--r-- | src/sim/process.hh | 6 |
14 files changed, 80 insertions, 198 deletions
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 2c6f83309..112abbf4a 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -49,7 +49,8 @@ using namespace AlphaISA; using namespace std; AlphaProcess::AlphaProcess(ProcessParams *params, ObjectFile *objFile) - : Process(params, new FuncPageTable(params->name, params->pid, PageBytes), + : Process(params, + new EmulationPageTable(params->name, params->pid, PageBytes), objFile) { fatal_if(params->useArchPT, "Arch page tables not implemented."); diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc index aef714ed3..1bb23dec2 100644 --- a/src/arch/arm/process.cc +++ b/src/arch/arm/process.cc @@ -63,9 +63,10 @@ using namespace ArmISA; ArmProcess::ArmProcess(ProcessParams *params, ObjectFile *objFile, ObjectFile::Arch _arch) - : Process(params, new FuncPageTable(params->name, params->pid, PageBytes), + : Process(params, + new EmulationPageTable(params->name, params->pid, PageBytes), objFile), - arch(_arch) + arch(_arch) { fatal_if(params->useArchPT, "Arch page tables not implemented."); } diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index 62ccd5afe..b2957e0c4 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -50,7 +50,8 @@ using namespace std; using namespace MipsISA; MipsProcess::MipsProcess(ProcessParams *params, ObjectFile *objFile) - : Process(params, new FuncPageTable(params->name, params->pid, PageBytes), + : Process(params, + new EmulationPageTable(params->name, params->pid, PageBytes), objFile) { fatal_if(params->useArchPT, "Arch page tables not implemented."); diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc index 22627efe5..6561bff4e 100644 --- a/src/arch/power/process.cc +++ b/src/arch/power/process.cc @@ -50,7 +50,8 @@ using namespace std; using namespace PowerISA; PowerProcess::PowerProcess(ProcessParams *params, ObjectFile *objFile) - : Process(params, new FuncPageTable(params->name, params->pid, PageBytes), + : Process(params, + new EmulationPageTable(params->name, params->pid, PageBytes), objFile) { fatal_if(params->useArchPT, "Arch page tables not implemented."); diff --git a/src/arch/riscv/process.cc b/src/arch/riscv/process.cc index 73df5f50d..b3e98aefb 100644 --- a/src/arch/riscv/process.cc +++ b/src/arch/riscv/process.cc @@ -60,8 +60,8 @@ using namespace std; using namespace RiscvISA; RiscvProcess::RiscvProcess(ProcessParams *params, ObjectFile *objFile) : - Process(params, new FuncPageTable(params->name, params->pid, - PageBytes), + Process(params, + new EmulationPageTable(params->name, params->pid, PageBytes), objFile) { fatal_if(params->useArchPT, "Arch page tables not implemented."); diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 1fcb6cba3..e4cd874bd 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -56,7 +56,8 @@ static const int FirstArgumentReg = 8; SparcProcess::SparcProcess(ProcessParams *params, ObjectFile *objFile, Addr _StackBias) - : Process(params, new FuncPageTable(params->name, params->pid, PageBytes), + : Process(params, + new EmulationPageTable(params->name, params->pid, PageBytes), objFile), StackBias(_StackBias) { diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index bea002d34..52255af7a 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -99,12 +99,11 @@ static const int NumArgumentRegs32 M5_VAR_USED = X86Process::X86Process(ProcessParams *params, ObjectFile *objFile, SyscallDesc *_syscallDescs, int _numSyscallDescs) : Process(params, params->useArchPT ? - static_cast<PageTableBase *>( + static_cast<EmulationPageTable *>( new ArchPageTable(params->name, params->pid, params->system, PageBytes)) : - static_cast<PageTableBase *>( - new FuncPageTable(params->name, params->pid, - PageBytes)), + new EmulationPageTable(params->name, params->pid, + PageBytes), objFile), syscallDescs(_syscallDescs), numSyscallDescs(_numSyscallDescs) { 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; diff --git a/src/sim/process.cc b/src/sim/process.cc index 77d7903a7..07c936e76 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -101,7 +101,7 @@ using namespace std; using namespace TheISA; -Process::Process(ProcessParams *params, PageTableBase *pTable, +Process::Process(ProcessParams *params, EmulationPageTable *pTable, ObjectFile *obj_file) : SimObject(params), system(params->system), useArchPT(params->useArchPT), @@ -310,7 +310,8 @@ Process::allocateMem(Addr vaddr, int64_t size, bool clobber) int npages = divCeil(size, (int64_t)PageBytes); Addr paddr = system->allocPhysPages(npages); pTable->map(vaddr, paddr, size, - clobber ? PageTableBase::Clobber : PageTableBase::Zero); + clobber ? EmulationPageTable::Clobber : + EmulationPageTable::Zero); } void @@ -405,7 +406,8 @@ bool Process::map(Addr vaddr, Addr paddr, int size, bool cacheable) { pTable->map(vaddr, paddr, size, - cacheable ? PageTableBase::Zero : PageTableBase::Uncacheable); + cacheable ? EmulationPageTable::Zero : + EmulationPageTable::Uncacheable); return true; } diff --git a/src/sim/process.hh b/src/sim/process.hh index 6d465aca9..cb2a3e2be 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -54,7 +54,7 @@ struct ProcessParams; class EmulatedDriver; class ObjectFile; -class PageTableBase; +class EmulationPageTable; class SyscallDesc; class SyscallReturn; class System; @@ -63,7 +63,7 @@ class ThreadContext; class Process : public SimObject { public: - Process(ProcessParams *params, PageTableBase *pTable, + Process(ProcessParams *params, EmulationPageTable *pTable, ObjectFile *obj_file); void serialize(CheckpointOut &cp) const override; @@ -176,7 +176,7 @@ class Process : public SimObject bool useArchPT; // flag for using architecture specific page table bool kvmInSE; // running KVM requires special initialization - PageTableBase* pTable; + EmulationPageTable *pTable; SETranslatingPortProxy initVirtMem; // memory proxy for initial image load |