summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mem/page_table.cc111
-rw-r--r--mem/page_table.hh28
2 files changed, 51 insertions, 88 deletions
diff --git a/mem/page_table.cc b/mem/page_table.cc
index cd93c0692..63b60de24 100644
--- a/mem/page_table.cc
+++ b/mem/page_table.cc
@@ -34,33 +34,25 @@
#include <map>
#include <fstream>
-using namespace std;
-
+#include "base/bitfield.hh"
#include "base/intmath.hh"
#include "base/trace.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(const std::string &name)
- : SimObject(name)
+PageTable::PageTable(System *_system, Addr _pageSize)
+ : pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))),
+ system(_system)
{
+ 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
@@ -89,78 +81,49 @@ 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);
-}
-Addr
-PageTable::translate(Addr vaddr, unsigned asid)
+void
+PageTable::allocate(Addr vaddr, int size)
{
- Addr hash_addr;
- std::map<Addr,Addr>::iterator iter;
-
- //DPRINTF(PageTable,"PageTable: Virtual Address %#x Translating for ASID %i\n",
- // vaddr,asid);
-
- //Create the hash_addr
- //Combine vaddr and asid
- hash_addr = vaddr & (~(VMPageSize - 1)) | asid;
-
- //DPRINTF(PageTable,"PageTable: Hash Address %#x\n",hash_addr);
-
- //Look into the page table
- iter=pTable.find(hash_addr);
-
- //bool page_fault = true;
+ // starting address must be page aligned
+ assert(pageOffset(vaddr) == 0);
- //Store the translated address if found, and return
- if (iter != pTable.end()) //Found??
- {
- Addr return_addr = iter->second + (vaddr & (VMPageSize - 1));
+ for (; size > 0; size -= pageSize, vaddr += pageSize) {
+ std::map<Addr,Addr>::iterator iter = pTable.find(vaddr);
- return return_addr;
- }
- else//Alocate a new page, register translation
- {
- Addr return_addr;
-
- //DPRINTF(PageTable,"PageTable: Page Not Found. Allocating new page\n");
-
- Addr new_page = mem->new_page();
-
- pTable[hash_addr] = new_page;
-
- return_addr = new_page + (vaddr & (VMPageSize - 1));
+ if (iter != pTable.end()) {
+ // already mapped
+ fatal("PageTable::allocate: address 0x%x already mapped", vaddr);
+ }
- return return_addr;
+ pTable[vaddr] = system->new_page();
}
}
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(PageTable)
- SimObjectParam<PhysicalMemory *> physmem;
-END_DECLARE_SIM_OBJECT_PARAMS(PageTable)
+bool
+PageTable::translate(Addr vaddr, Addr &paddr)
+{
+ Addr page_addr = pageAlign(vaddr);
+ std::map<Addr,Addr>::iterator iter = pTable.find(page_addr);
-BEGIN_INIT_SIM_OBJECT_PARAMS(PageTable)
+ if (iter == pTable.end()) {
+ return false;
+ }
- INIT_PARAM_DFLT(physmem, "Pointer to functional memory", NULL)
+ paddr = iter->second + pageOffset(vaddr);
+ return true;
+}
-END_INIT_SIM_OBJECT_PARAMS(PageTable)
-CREATE_SIM_OBJECT(PageTable)
+Fault
+PageTable::translate(CpuRequestPtr &req)
{
- PageTable *pTable = new PageTable(getInstanceName());
-
- if (physmem)
- pTable->setPhysMem(physmem);
-
- return pTable;
+ 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);
}
-
-REGISTER_SIM_OBJECT("PageTable", PageTable)
diff --git a/mem/page_table.hh b/mem/page_table.hh
index 7e534899f..d318783be 100644
--- a/mem/page_table.hh
+++ b/mem/page_table.hh
@@ -42,44 +42,44 @@
#include "mem/packet.hh"
#include "sim/sim_object.hh"
-class PhysicalMemory;
+class System;
/**
* Page Table Decleration.
*/
-class PageTable : public SimObject
+class PageTable
{
protected:
std::map<Addr,Addr> pTable;
- PhysicalMemory *mem;
+ const Addr pageSize;
+ const Addr offsetMask;
+
+ System *system;
public:
- /**
- * Construct this interface.
- * @param name The name of this interface.
- * @param hier Pointer to the hierarchy wide parameters.
- * @param _mem the connected memory.
- */
- PageTable(const std::string &name);
+ PageTable(System *_system, Addr _pageSize = VMPageSize);
~PageTable();
- void setPhysMem(PhysicalMemory *_mem) { mem = _mem; }
+ Addr pageAlign(Addr a) { return (a & ~offsetMask); }
+ Addr pageOffset(Addr a) { return (a & offsetMask); }
Fault page_check(Addr addr, int size) const;
+ void allocate(Addr vaddr, int size);
+
/**
* Translate function
* @param vaddr The virtual address.
- * @param asid The address space id.
* @return Physical address from translation.
*/
- Addr translate(Addr vaddr, unsigned asid);
+ bool translate(Addr vaddr, Addr &paddr);
/**
- * Perform a translation on the memory request, fills in paddr field of mem_req.
+ * Perform a translation on the memory request, fills in paddr
+ * field of mem_req.
* @param req The memory request.
*/
Fault translate(CpuRequestPtr &req);