From 4d5f2c28a88f83d390e80407f55a8a02ead33878 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 22 Oct 2011 22:30:07 -0700 Subject: syscall_emul: implement MAP_FIXED option to mmap() --- src/mem/page_table.cc | 26 +++++++++++++++++++------- src/mem/page_table.hh | 10 +++++++++- 2 files changed, 28 insertions(+), 8 deletions(-) (limited to 'src/mem') diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc index a94d92480..745872319 100644 --- a/src/mem/page_table.cc +++ b/src/mem/page_table.cc @@ -67,7 +67,7 @@ PageTable::~PageTable() } void -PageTable::allocate(Addr vaddr, int64_t size) +PageTable::allocate(Addr vaddr, int64_t size, bool clobber) { // starting address must be page aligned assert(pageOffset(vaddr) == 0); @@ -75,16 +75,13 @@ PageTable::allocate(Addr vaddr, int64_t size) DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr+ size); for (; size > 0; size -= pageSize, vaddr += pageSize) { - PTableItr iter = pTable.find(vaddr); - - if (iter != pTable.end()) { + if (!clobber && (pTable.find(vaddr) != pTable.end())) { // already mapped - fatal("PageTable::allocate: address 0x%x already mapped", - vaddr); + fatal("PageTable::allocate: address 0x%x already mapped", vaddr); } pTable[vaddr] = TheISA::TlbEntry(process->M5_pid, vaddr, - process->system->new_page()); + process->system->new_page()); updateCache(vaddr, pTable[vaddr]); } } @@ -127,6 +124,21 @@ PageTable::deallocate(Addr vaddr, int64_t size) } +bool +PageTable::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()) { + return false; + } + } + + return true; +} + bool PageTable::lookup(Addr vaddr, TheISA::TlbEntry &entry) { diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh index 61da5f322..d60f4a433 100644 --- a/src/mem/page_table.hh +++ b/src/mem/page_table.hh @@ -79,10 +79,18 @@ class PageTable Addr pageAlign(Addr a) { return (a & ~offsetMask); } Addr pageOffset(Addr a) { return (a & offsetMask); } - void allocate(Addr vaddr, int64_t size); + void allocate(Addr vaddr, int64_t size, bool clobber = false); void remap(Addr vaddr, int64_t size, Addr new_vaddr); void deallocate(Addr vaddr, int64_t size); + /** + * 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); + /** * Lookup function * @param vaddr The virtual address. -- cgit v1.2.3 From 6f9d294e8685f49d91af48065736ac1d67e53718 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 22 Oct 2011 22:30:08 -0700 Subject: SE: move page allocation from PageTable to Process PageTable supported an allocate() call that called back through the Process to allocate memory, but did not have a method to map addresses without allocating new pages. It makes more sense for Process to do the allocation, so this method was renamed allocateMem() and moved to Process, and uses a new map() call on PageTable. The remaining uses of the process pointer in PageTable were only to get the name and the PID, so by passing these in directly in the constructor, we can make PageTable completely independent of Process. --- src/mem/page_table.cc | 23 ++++++++++------------- src/mem/page_table.hh | 15 +++++++++------ src/mem/translating_port.cc | 8 ++++---- 3 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src/mem') diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc index 745872319..7622c2d48 100644 --- a/src/mem/page_table.cc +++ b/src/mem/page_table.cc @@ -45,16 +45,14 @@ #include "debug/MMU.hh" #include "mem/page_table.hh" #include "sim/faults.hh" -#include "sim/process.hh" #include "sim/sim_object.hh" -#include "sim/system.hh" using namespace std; using namespace TheISA; -PageTable::PageTable(Process *_process, Addr _pageSize) +PageTable::PageTable(const std::string &__name, uint64_t _pid, Addr _pageSize) : pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))), - process(_process) + pid(_pid), _name(__name) { assert(isPowerOf2(pageSize)); pTableCache[0].vaddr = 0; @@ -67,21 +65,20 @@ PageTable::~PageTable() } void -PageTable::allocate(Addr vaddr, int64_t size, bool clobber) +PageTable::map(Addr vaddr, Addr paddr, int64_t size, bool clobber) { // starting address must be page aligned assert(pageOffset(vaddr) == 0); DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr+ size); - for (; size > 0; size -= pageSize, vaddr += pageSize) { + for (; size > 0; size -= pageSize, vaddr += pageSize, paddr += pageSize) { if (!clobber && (pTable.find(vaddr) != pTable.end())) { // already mapped fatal("PageTable::allocate: address 0x%x already mapped", vaddr); } - pTable[vaddr] = TheISA::TlbEntry(process->M5_pid, vaddr, - process->system->new_page()); + pTable[vaddr] = TheISA::TlbEntry(pid, vaddr, paddr); updateCache(vaddr, pTable[vaddr]); } } @@ -108,11 +105,11 @@ PageTable::remap(Addr vaddr, int64_t size, Addr new_vaddr) } void -PageTable::deallocate(Addr vaddr, int64_t size) +PageTable::unmap(Addr vaddr, int64_t size) { assert(pageOffset(vaddr) == 0); - DPRINTF(MMU, "Deallocating page: %#x-%#x\n", vaddr, vaddr+ size); + DPRINTF(MMU, "Unmapping page: %#x-%#x\n", vaddr, vaddr+ size); for (; size > 0; size -= pageSize, vaddr += pageSize) { PTableItr iter = pTable.find(vaddr); @@ -208,7 +205,7 @@ PageTable::serialize(std::ostream &os) PTableItr iter = pTable.begin(); PTableItr end = pTable.end(); while (iter != end) { - os << "\n[" << csprintf("%s.Entry%d", process->name(), count) << "]\n"; + os << "\n[" << csprintf("%s.Entry%d", name(), count) << "]\n"; paramOut(os, "vaddr", iter->first); iter->second.serialize(os); @@ -230,9 +227,9 @@ PageTable::unserialize(Checkpoint *cp, const std::string §ion) pTable.clear(); while(i < count) { - paramIn(cp, csprintf("%s.Entry%d", process->name(), i), "vaddr", vaddr); + paramIn(cp, csprintf("%s.Entry%d", name(), i), "vaddr", vaddr); entry = new TheISA::TlbEntry(); - entry->unserialize(cp, csprintf("%s.Entry%d", process->name(), i)); + entry->unserialize(cp, csprintf("%s.Entry%d", name(), i)); pTable[vaddr] = *entry; ++i; } diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh index d60f4a433..b1b5227be 100644 --- a/src/mem/page_table.hh +++ b/src/mem/page_table.hh @@ -46,8 +46,6 @@ #include "mem/request.hh" #include "sim/serialize.hh" -class Process; - /** * Page Table Declaration. */ @@ -68,20 +66,25 @@ class PageTable const Addr pageSize; const Addr offsetMask; - Process *process; + const uint64_t pid; + const std::string _name; public: - PageTable(Process *_process, Addr _pageSize = TheISA::VMPageSize); + PageTable(const std::string &__name, uint64_t _pid, + Addr _pageSize = TheISA::VMPageSize); ~PageTable(); + // for DPRINTF compatibility + const std::string name() const { return _name; } + Addr pageAlign(Addr a) { return (a & ~offsetMask); } Addr pageOffset(Addr a) { return (a & offsetMask); } - void allocate(Addr vaddr, int64_t size, bool clobber = false); + void map(Addr vaddr, Addr paddr, int64_t size, bool clobber = false); void remap(Addr vaddr, int64_t size, Addr new_vaddr); - void deallocate(Addr vaddr, int64_t size); + void unmap(Addr vaddr, int64_t size); /** * Check if any pages in a region are already allocated diff --git a/src/mem/translating_port.cc b/src/mem/translating_port.cc index 80c68c6bd..3ea728349 100644 --- a/src/mem/translating_port.cc +++ b/src/mem/translating_port.cc @@ -86,8 +86,8 @@ TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size) if (!pTable->translate(gen.addr(), paddr)) { if (allocating == Always) { - pTable->allocate(roundDown(gen.addr(), VMPageSize), - VMPageSize); + process->allocateMem(roundDown(gen.addr(), VMPageSize), + VMPageSize); } else if (allocating == NextPage) { // check if we've accessed the next page on the stack if (!process->fixupStackFault(gen.addr())) @@ -123,8 +123,8 @@ TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size) if (!pTable->translate(gen.addr(), paddr)) { if (allocating == Always) { - pTable->allocate(roundDown(gen.addr(), VMPageSize), - VMPageSize); + process->allocateMem(roundDown(gen.addr(), VMPageSize), + VMPageSize); pTable->translate(gen.addr(), paddr); } else { return false; -- cgit v1.2.3