#include "base/intmath.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
+#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;
}
void
-PageTable::allocate(Addr vaddr, int64_t size)
+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) {
- PTableItr iter = pTable.find(vaddr);
-
- if (iter != pTable.end()) {
+ 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);
+ 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]);
}
}
new_vaddr, size);
for (; size > 0; size -= pageSize, vaddr += pageSize, new_vaddr += pageSize) {
- PTableItr iter = pTable.find(vaddr);
-
- assert(iter != pTable.end());
+ assert(pTable.find(vaddr) != pTable.end());
pTable[new_vaddr] = pTable[vaddr];
pTable.erase(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);
-
- assert(iter != pTable.end());
+ assert(pTable.find(vaddr) != pTable.end());
pTable.erase(vaddr);
}
}
+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)
{
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);
{
int i = 0, count;
paramIn(cp, section, "ptable.size", count);
- Addr vaddr;
- TheISA::TlbEntry *entry;
pTable.clear();
- while(i < count) {
- paramIn(cp, csprintf("%s.Entry%d", process->name(), i), "vaddr", vaddr);
+ while (i < count) {
+ TheISA::TlbEntry *entry;
+ Addr 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;
+ delete entry;
++i;
}
}