TLB: Fix serialization issues with the tlb entries and make the page table store the process, not the system.

--HG--
extra : convert_revision : 2421af11f62f60fb48faeee6bddadac2987df0e8
This commit is contained in:
Gabe Black 2007-10-25 19:04:44 -07:00
parent 0711f4f17a
commit fddfa71658
13 changed files with 106 additions and 120 deletions

View file

@ -177,25 +177,12 @@ void ItbFault::invoke(ThreadContext * tc)
void ItbPageFault::invoke(ThreadContext * tc) void ItbPageFault::invoke(ThreadContext * tc)
{ {
Process *p = tc->getProcessPtr(); Process *p = tc->getProcessPtr();
Addr physaddr; TlbEntry entry;
bool success = p->pTable->translate(pc, physaddr); bool success = p->pTable->lookup(pc, entry);
if(!success) { if(!success) {
panic("Tried to execute unmapped address %#x.\n", pc); panic("Tried to execute unmapped address %#x.\n", pc);
} else { } else {
VAddr vaddr(pc); VAddr vaddr(pc);
VAddr paddr(physaddr);
TlbEntry entry;
entry.tag = vaddr.vpn();
entry.ppn = paddr.vpn();
entry.xre = 15; //This can be read in all modes.
entry.xwe = 1; //This can be written only in kernel mode.
entry.asn = p->M5_pid; //Address space number.
entry.asma = false; //Only match on this ASN.
entry.fonr = false; //Don't fault on read.
entry.fonw = false; //Don't fault on write.
entry.valid = true; //This entry is valid.
tc->getITBPtr()->insert(vaddr.page(), entry); tc->getITBPtr()->insert(vaddr.page(), entry);
} }
} }
@ -203,28 +190,15 @@ void ItbPageFault::invoke(ThreadContext * tc)
void NDtbMissFault::invoke(ThreadContext * tc) void NDtbMissFault::invoke(ThreadContext * tc)
{ {
Process *p = tc->getProcessPtr(); Process *p = tc->getProcessPtr();
Addr physaddr; TlbEntry entry;
bool success = p->pTable->translate(vaddr, physaddr); bool success = p->pTable->lookup(vaddr, entry);
if(!success) { if(!success) {
p->checkAndAllocNextPage(vaddr); p->checkAndAllocNextPage(vaddr);
success = p->pTable->translate(vaddr, physaddr); success = p->pTable->lookup(vaddr, entry);
} }
if(!success) { if(!success) {
panic("Tried to access unmapped address %#x.\n", (Addr)vaddr); panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
} else { } else {
VAddr paddr(physaddr);
TlbEntry entry;
entry.tag = vaddr.vpn();
entry.ppn = paddr.vpn();
entry.xre = 15; //This can be read in all modes.
entry.xwe = 15; //This can be written in all modes.
entry.asn = p->M5_pid; //Address space number.
entry.asma = false; //Only match on this ASN.
entry.fonr = false; //Don't fault on read.
entry.fonw = false; //Don't fault on write.
entry.valid = true; //This entry is valid.
tc->getDTBPtr()->insert(vaddr.page(), entry); tc->getDTBPtr()->insert(vaddr.page(), entry);
} }
} }

View file

@ -92,10 +92,21 @@ namespace AlphaISA {
// ITB/DTB table entry // ITB/DTB table entry
struct TlbEntry struct TlbEntry
{ {
Addr pageStart;
//Construct an entry that maps to physical address addr. //Construct an entry that maps to physical address addr.
TlbEntry(Addr addr) : pageStart(addr) TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr)
{} {
VAddr vaddr(_vaddr);
VAddr paddr(_paddr);
tag = vaddr.vpn();
ppn = paddr.vpn();
xre = 15;
xwe = 15;
asn = _asn;
asma = false;
fonr = false;
fonw = false;
valid = true;
}
TlbEntry() TlbEntry()
{} {}
@ -109,6 +120,11 @@ namespace AlphaISA {
bool fonw; // fault on write bool fonw; // fault on write
bool valid; // valid page table entry bool valid; // valid page table entry
Addr pageStart()
{
return ppn << PageShift;
}
void serialize(std::ostream &os); void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section); void unserialize(Checkpoint *cp, const std::string &section);
}; };

View file

@ -54,13 +54,13 @@ namespace MipsISA {
void void
TlbEntry::serialize(std::ostream &os) TlbEntry::serialize(std::ostream &os)
{ {
SERIALIZE_SCALAR(pageStart); SERIALIZE_SCALAR(_pageStart);
} }
void void
TlbEntry::unserialize(Checkpoint *cp, const std::string &section) TlbEntry::unserialize(Checkpoint *cp, const std::string &section)
{ {
UNSERIALIZE_SCALAR(pageStart); UNSERIALIZE_SCALAR(_pageStart);
} }
}; };

View file

@ -39,9 +39,14 @@ namespace MipsISA
{ {
struct TlbEntry struct TlbEntry
{ {
Addr pageStart; Addr _pageStart;
TlbEntry() {} TlbEntry() {}
TlbEntry(Addr paddr) : pageStart(paddr) {} TlbEntry(Addr asn, Addr vaddr, Addr paddr) : _pageStart(paddr) {}
Addr pageStart()
{
return _pageStart;
}
void serialize(std::ostream &os); void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section); void unserialize(Checkpoint *cp, const std::string &section);

View file

@ -623,64 +623,32 @@ void PowerOnReset::invoke(ThreadContext * tc)
void FastInstructionAccessMMUMiss::invoke(ThreadContext *tc) void FastInstructionAccessMMUMiss::invoke(ThreadContext *tc)
{ {
Process *p = tc->getProcessPtr(); Process *p = tc->getProcessPtr();
Addr paddr; TlbEntry entry;
bool success = p->pTable->translate(vaddr, paddr); bool success = p->pTable->lookup(vaddr, entry);
if(!success) { if(!success) {
panic("Tried to execute unmapped address %#x.\n", vaddr); panic("Tried to execute unmapped address %#x.\n", vaddr);
} else { } else {
uint64_t entry = 0;
entry |= 0ULL << 1; // Not writable
entry |= 0ULL << 2; // Available in nonpriveleged mode
entry |= 0ULL << 3; // No side effects
entry |= 1ULL << 4; // Virtually cachable
entry |= 1ULL << 5; // Physically cachable
entry |= 0ULL << 6; // Not locked
entry |= mbits(paddr, 39, 13); // Physical address
entry |= 0ULL << 48; // size = 8k
entry |= 0uLL << 59; // Endianness not inverted
entry |= 0ULL << 60; // Not no fault only
entry |= 0ULL << 61; // size = 8k
entry |= 1ULL << 63; // valid
PageTableEntry PTE(entry);
Addr alignedVaddr = p->pTable->pageAlign(vaddr); Addr alignedVaddr = p->pTable->pageAlign(vaddr);
tc->getITBPtr()->insert(alignedVaddr, 0 /*partition id*/, tc->getITBPtr()->insert(alignedVaddr, 0 /*partition id*/,
p->M5_pid /*context id*/, false, PTE); p->M5_pid /*context id*/, false, entry.pte);
} }
} }
void FastDataAccessMMUMiss::invoke(ThreadContext *tc) void FastDataAccessMMUMiss::invoke(ThreadContext *tc)
{ {
Process *p = tc->getProcessPtr(); Process *p = tc->getProcessPtr();
Addr paddr; TlbEntry entry;
bool success = p->pTable->translate(vaddr, paddr); bool success = p->pTable->lookup(vaddr, entry);
if(!success) { if(!success) {
p->checkAndAllocNextPage(vaddr); p->checkAndAllocNextPage(vaddr);
success = p->pTable->translate(vaddr, paddr); success = p->pTable->lookup(vaddr, entry);
} }
if(!success) { if(!success) {
panic("Tried to access unmapped address %#x.\n", vaddr); panic("Tried to access unmapped address %#x.\n", vaddr);
} else { } else {
uint64_t entry = 0;
entry |= 1ULL << 1; // Writable
entry |= 0ULL << 2; // Available in nonpriveleged mode
entry |= 0ULL << 3; // No side effects
entry |= 1ULL << 4; // Virtually cachable
entry |= 1ULL << 5; // Physically cachable
entry |= 0ULL << 6; // Not locked
entry |= mbits(paddr, 39, 13); // Physical address
entry |= 0ULL << 48; // size = 8k
entry |= 0uLL << 59; // Endianness not inverted
entry |= 0ULL << 60; // Not no fault only
entry |= 0ULL << 61; // size = 8k
entry |= 1ULL << 63; // valid
PageTableEntry PTE(entry);
Addr alignedVaddr = p->pTable->pageAlign(vaddr); Addr alignedVaddr = p->pTable->pageAlign(vaddr);
tc->getDTBPtr()->insert(alignedVaddr, 0 /*partition id*/, tc->getDTBPtr()->insert(alignedVaddr, 0 /*partition id*/,
p->M5_pid /*context id*/, false, PTE); p->M5_pid /*context id*/, false, entry.pte);
} }
} }

View file

@ -190,16 +190,43 @@ struct TlbRange {
struct TlbEntry { struct TlbEntry {
Addr pageStart; TlbEntry(Addr asn, Addr vaddr, Addr paddr)
{
uint64_t entry = 0;
entry |= 1ULL << 1; // Writable
entry |= 0ULL << 2; // Available in nonpriveleged mode
entry |= 0ULL << 3; // No side effects
entry |= 1ULL << 4; // Virtually cachable
entry |= 1ULL << 5; // Physically cachable
entry |= 0ULL << 6; // Not locked
entry |= mbits(paddr, 39, 13); // Physical address
entry |= 0ULL << 48; // size = 8k
entry |= 0uLL << 59; // Endianness not inverted
entry |= 0ULL << 60; // Not no fault only
entry |= 0ULL << 61; // size = 8k
entry |= 1ULL << 63; // valid
pte = PageTableEntry(entry);
range.va = vaddr;
range.size = 8*(1<<10);
range.contextId = asn;
range.partitionId = 0;
range.real = false;
valid = true;
}
TlbEntry() TlbEntry()
{} {}
TlbEntry(Addr addr) : pageStart(addr)
{}
TlbRange range; TlbRange range;
PageTableEntry pte; PageTableEntry pte;
bool used; bool used;
bool valid; bool valid;
Addr pageStart()
{
return pte.paddr();
}
void serialize(std::ostream &os); void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section); void unserialize(Checkpoint *cp, const std::string &section);

View file

@ -118,20 +118,11 @@ namespace X86ISA
DPRINTF(TLB, "Invoking an ITLB fault for address %#x at pc %#x.\n", DPRINTF(TLB, "Invoking an ITLB fault for address %#x at pc %#x.\n",
vaddr, tc->readPC()); vaddr, tc->readPC());
Process *p = tc->getProcessPtr(); Process *p = tc->getProcessPtr();
Addr paddr; TlbEntry entry;
bool success = p->pTable->translate(vaddr, paddr); bool success = p->pTable->lookup(vaddr, entry);
if(!success) { if(!success) {
panic("Tried to execute unmapped address %#x.\n", vaddr); panic("Tried to execute unmapped address %#x.\n", vaddr);
} else { } else {
TlbEntry entry;
entry.pageStart = p->pTable->pageAlign(paddr);
entry.writeable = false;
entry.user = true;
entry.uncacheable = false;
entry.global = false;
entry.patBit = 0;
entry.noExec = false;
entry.size = PageBytes;
Addr alignedVaddr = p->pTable->pageAlign(vaddr); Addr alignedVaddr = p->pTable->pageAlign(vaddr);
DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, entry.pageStart); DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, entry.pageStart);
tc->getITBPtr()->insert(alignedVaddr, entry); tc->getITBPtr()->insert(alignedVaddr, entry);
@ -143,24 +134,15 @@ namespace X86ISA
DPRINTF(TLB, "Invoking an DTLB fault for address %#x at pc %#x.\n", DPRINTF(TLB, "Invoking an DTLB fault for address %#x at pc %#x.\n",
vaddr, tc->readPC()); vaddr, tc->readPC());
Process *p = tc->getProcessPtr(); Process *p = tc->getProcessPtr();
Addr paddr; TlbEntry entry;
bool success = p->pTable->translate(vaddr, paddr); bool success = p->pTable->lookup(vaddr, entry);
if(!success) { if(!success) {
p->checkAndAllocNextPage(vaddr); p->checkAndAllocNextPage(vaddr);
success = p->pTable->translate(vaddr, paddr); success = p->pTable->lookup(vaddr, entry);
} }
if(!success) { if(!success) {
panic("Tried to access unmapped address %#x.\n", vaddr); panic("Tried to access unmapped address %#x.\n", vaddr);
} else { } else {
TlbEntry entry;
entry.pageStart = p->pTable->pageAlign(paddr);
entry.writeable = true;
entry.user = true;
entry.uncacheable = false;
entry.global = false;
entry.patBit = 0;
entry.noExec = true;
entry.size = PageBytes;
Addr alignedVaddr = p->pTable->pageAlign(vaddr); Addr alignedVaddr = p->pTable->pageAlign(vaddr);
DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, entry.pageStart); DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, entry.pageStart);
tc->getDTBPtr()->insert(alignedVaddr, entry); tc->getDTBPtr()->insert(alignedVaddr, entry);

View file

@ -55,12 +55,18 @@
* Authors: Gabe Black * Authors: Gabe Black
*/ */
#include "arch/x86/isa_traits.hh"
#include "arch/x86/pagetable.hh" #include "arch/x86/pagetable.hh"
#include "sim/serialize.hh" #include "sim/serialize.hh"
namespace X86ISA namespace X86ISA
{ {
TlbEntry::TlbEntry(Addr asn, Addr _vaddr, Addr _paddr) :
paddr(_paddr), vaddr(_vaddr), size(PageBytes), writable(true), user(true),
uncacheable(false), global(false), patBit(0), noExec(false)
{}
void void
TlbEntry::serialize(std::ostream &os) TlbEntry::serialize(std::ostream &os)
{ {

View file

@ -76,10 +76,16 @@ namespace X86ISA
struct TlbEntry struct TlbEntry
{ {
// The base of the physical page. // The base of the physical page.
Addr pageStart; Addr paddr;
// The beginning of the virtual page this entry maps.
Addr vaddr;
// The size of the page this entry represents.
Addr size;
// Read permission is always available, assuming it isn't blocked by // Read permission is always available, assuming it isn't blocked by
// other mechanisms. // other mechanisms.
bool writeable; bool writable;
// Whether this page is accesible without being in supervisor mode. // Whether this page is accesible without being in supervisor mode.
bool user; bool user;
// Whether to use write through or write back. M5 ignores this and // Whether to use write through or write back. M5 ignores this and
@ -94,13 +100,13 @@ namespace X86ISA
// Whether or not memory on this page can be executed. // Whether or not memory on this page can be executed.
bool noExec; bool noExec;
// The beginning of the virtual page this entry maps. TlbEntry(Addr asn, Addr _vaddr, Addr _paddr);
Addr vaddr;
// The size of the page this entry represents.
Addr size;
TlbEntry() {} TlbEntry() {}
TlbEntry(Addr paddr) : pageStart(paddr) {}
Addr pageStart()
{
return paddr;
}
void serialize(std::ostream &os); void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section); void unserialize(Checkpoint *cp, const std::string &section);

View file

@ -494,7 +494,7 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
#endif #endif
} else { } else {
// Do paging protection checks. // Do paging protection checks.
Addr paddr = entry->pageStart | (vaddr & mask(12)); Addr paddr = entry->paddr | (vaddr & mask(12));
req->setPaddr(paddr); req->setPaddr(paddr);
} }
} else { } else {

View file

@ -43,15 +43,16 @@
#include "base/intmath.hh" #include "base/intmath.hh"
#include "base/trace.hh" #include "base/trace.hh"
#include "mem/page_table.hh" #include "mem/page_table.hh"
#include "sim/process.hh"
#include "sim/sim_object.hh" #include "sim/sim_object.hh"
#include "sim/system.hh" #include "sim/system.hh"
using namespace std; using namespace std;
using namespace TheISA; using namespace TheISA;
PageTable::PageTable(System *_system, Addr _pageSize) PageTable::PageTable(Process *_process, Addr _pageSize)
: pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))), : pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))),
system(_system) process(_process)
{ {
assert(isPowerOf2(pageSize)); assert(isPowerOf2(pageSize));
pTableCache[0].vaddr = 0; pTableCache[0].vaddr = 0;
@ -80,7 +81,8 @@ PageTable::allocate(Addr vaddr, int64_t size)
vaddr); vaddr);
} }
pTable[vaddr] = TheISA::TlbEntry(system->new_page()); pTable[vaddr] = TheISA::TlbEntry(process->M5_pid, vaddr,
process->system->new_page());
updateCache(vaddr, pTable[vaddr]); updateCache(vaddr, pTable[vaddr]);
} }
} }
@ -122,7 +124,7 @@ PageTable::translate(Addr vaddr, Addr &paddr)
DPRINTF(MMU, "Couldn't Translate: %#x\n", vaddr); DPRINTF(MMU, "Couldn't Translate: %#x\n", vaddr);
return false; return false;
} }
paddr = pageOffset(vaddr) + entry.pageStart; paddr = pageOffset(vaddr) + entry.pageStart();
DPRINTF(MMU, "Translating: %#x->%#x\n", vaddr, paddr); DPRINTF(MMU, "Translating: %#x->%#x\n", vaddr, paddr);
return true; return true;
} }

View file

@ -46,7 +46,7 @@
#include "sim/host.hh" #include "sim/host.hh"
#include "sim/serialize.hh" #include "sim/serialize.hh"
class System; class Process;
/** /**
* Page Table Declaration. * Page Table Declaration.
@ -68,11 +68,11 @@ class PageTable
const Addr pageSize; const Addr pageSize;
const Addr offsetMask; const Addr offsetMask;
System *system; Process *process;
public: public:
PageTable(System *_system, Addr _pageSize = TheISA::VMPageSize); PageTable(Process *_process, Addr _pageSize = TheISA::VMPageSize);
~PageTable(); ~PageTable();

View file

@ -125,7 +125,7 @@ Process::Process(ProcessParams * params)
mmap_start = mmap_end = 0; mmap_start = mmap_end = 0;
nxm_start = nxm_end = 0; nxm_start = nxm_end = 0;
pTable = new PageTable(system); pTable = new PageTable(this);
// other parameters will be initialized when the program is loaded // other parameters will be initialized when the program is loaded
} }