diff options
Diffstat (limited to 'mem/page_table.cc')
-rw-r--r-- | mem/page_table.cc | 115 |
1 files changed, 75 insertions, 40 deletions
diff --git a/mem/page_table.cc b/mem/page_table.cc index 2b2145503..cd93c0692 100644 --- a/mem/page_table.cc +++ b/mem/page_table.cc @@ -34,34 +34,40 @@ #include <map> #include <fstream> -#include "base/bitfield.hh" +using namespace std; + #include "base/intmath.hh" #include "base/trace.hh" -#include "mem/mem_cmd.hh" -#include "mem/mem_req.hh" +#include "mem/physical.hh" #include "mem/page_table.hh" #include "sim/builder.hh" #include "sim/sim_object.hh" -#include "sim/system.hh" - -using namespace std; -PageTable::PageTable(System *_system, Addr _pageSize) - : pageSize(_pageSize), offsetMask(mask(FloorLog2(_pageSize))), - system(_system) +PageTable::PageTable(const std::string &name) + : SimObject(name) { - assert(IsPowerOf2(pageSize)); } PageTable::~PageTable() { + //Iterate the page table freeing the memoruy + //Addr addr; + //std::map<Addr,Addr>::iterator iter; + + //iter = pTable.begin(); + //while(iter != pTable.end()) + //{ + //delete [] (uint8_t *)iter->second; +// iter ++; + // } + } Fault PageTable::page_check(Addr addr, int size) const { if (size < sizeof(uint64_t)) { - if (!IsPowerOf2(size)) { + if (!isPowerOf2(size)) { panic("Invalid request size!\n"); return Machine_Check_Fault; } @@ -83,49 +89,78 @@ PageTable::page_check(Addr addr, int size) const } +Fault +PageTable::translate(CpuRequestPtr &req) +{ +//Should I check here for accesses that are > VMPageSize? + req->paddr = translate(req->vaddr, req->asid); + return page_check(req->paddr, req->size); +} -void -PageTable::allocate(Addr vaddr, int size) +Addr +PageTable::translate(Addr vaddr, unsigned asid) { - // starting address must be page aligned - assert(pageOffset(vaddr) == 0); + Addr hash_addr; + std::map<Addr,Addr>::iterator iter; - for (; size > 0; size -= pageSize, vaddr += pageSize) { - std::map<Addr,Addr>::iterator iter = pTable.find(vaddr); + //DPRINTF(PageTable,"PageTable: Virtual Address %#x Translating for ASID %i\n", + // vaddr,asid); - if (iter != pTable.end()) { - // already mapped - fatal("PageTable::allocate: address 0x%x already mapped", vaddr); - } + //Create the hash_addr + //Combine vaddr and asid + hash_addr = vaddr & (~(VMPageSize - 1)) | asid; - pTable[vaddr] = system->new_page(); - } -} + //DPRINTF(PageTable,"PageTable: Hash Address %#x\n",hash_addr); + //Look into the page table + iter=pTable.find(hash_addr); + //bool page_fault = true; -bool -PageTable::translate(Addr vaddr, Addr &paddr) -{ - Addr page_addr = pageAlign(vaddr); - std::map<Addr,Addr>::iterator iter = pTable.find(page_addr); + //Store the translated address if found, and return + if (iter != pTable.end()) //Found?? + { + Addr return_addr = iter->second + (vaddr & (VMPageSize - 1)); - if (iter == pTable.end()) { - return false; + return return_addr; } + else//Alocate a new page, register translation + { + Addr return_addr; + + //DPRINTF(PageTable,"PageTable: Page Not Found. Allocating new page\n"); - paddr = iter->second + pageOffset(vaddr); - return true; + Addr new_page = mem->new_page(); + + pTable[hash_addr] = new_page; + + return_addr = new_page + (vaddr & (VMPageSize - 1)); + + return return_addr; + } } +BEGIN_DECLARE_SIM_OBJECT_PARAMS(PageTable) -Fault -PageTable::translate(MemReqPtr &req) + SimObjectParam<PhysicalMemory *> physmem; + +END_DECLARE_SIM_OBJECT_PARAMS(PageTable) + +BEGIN_INIT_SIM_OBJECT_PARAMS(PageTable) + + INIT_PARAM_DFLT(physmem, "Pointer to functional memory", NULL) + +END_INIT_SIM_OBJECT_PARAMS(PageTable) + +CREATE_SIM_OBJECT(PageTable) { - assert(pageAlign(req->vaddr + req->size - 1) == pageAlign(req->vaddr)); - if (!translate(req->vaddr, req->paddr)) { - return Machine_Check_Fault; - } - return page_check(req->paddr, req->size); + PageTable *pTable = new PageTable(getInstanceName()); + + if (physmem) + pTable->setPhysMem(physmem); + + return pTable; } + +REGISTER_SIM_OBJECT("PageTable", PageTable) |