summaryrefslogtreecommitdiff
path: root/mem/page_table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'mem/page_table.cc')
-rw-r--r--mem/page_table.cc115
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)