#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;
}
}
+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)
#include <map>
#include "base/trace.hh"
-#include "mem/mem_req.hh"
-#include "mem/mem_cmd.hh"
+#include "mem/request.hh"
+#include "mem/packet.hh"
#include "sim/sim_object.hh"
-class System;
+class PhysicalMemory;
/**
* Page Table Decleration.
*/
-class PageTable
+class PageTable : public SimObject
{
protected:
std::map<Addr,Addr> pTable;
- const Addr pageSize;
- const Addr offsetMask;
-
- System *system;
+ PhysicalMemory *mem;
public:
- PageTable(System *_system, Addr _pageSize = VMPageSize);
+ /**
+ * 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();
- Addr pageAlign(Addr a) { return (a & ~offsetMask); }
- Addr pageOffset(Addr a) { return (a & offsetMask); }
+ void setPhysMem(PhysicalMemory *_mem) { mem = _mem; }
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.
*/
- bool translate(Addr vaddr, Addr &paddr);
+ Addr translate(Addr vaddr, unsigned asid);
/**
* Perform a translation on the memory request, fills in paddr field of mem_req.
* @param req The memory request.
*/
- Fault translate(MemReqPtr &req);
+ Fault translate(CpuRequestPtr &req);
};