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)
{
Process *p = tc->getProcessPtr();
Addr physaddr;
bool success = p->pTable->translate(pc, physaddr);
TlbEntry entry;
bool success = p->pTable->lookup(pc, entry);
if(!success) {
panic("Tried to execute unmapped address %#x.\n", pc);
} else {
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);
}
}
@ -203,28 +190,15 @@ void ItbPageFault::invoke(ThreadContext * tc)
void NDtbMissFault::invoke(ThreadContext * tc)
{
Process *p = tc->getProcessPtr();
Addr physaddr;
bool success = p->pTable->translate(vaddr, physaddr);
TlbEntry entry;
bool success = p->pTable->lookup(vaddr, entry);
if(!success) {
p->checkAndAllocNextPage(vaddr);
success = p->pTable->translate(vaddr, physaddr);
success = p->pTable->lookup(vaddr, entry);
}
if(!success) {
panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
} 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);
}
}

View file

@ -92,10 +92,21 @@ namespace AlphaISA {
// ITB/DTB table entry
struct TlbEntry
{
Addr pageStart;
//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()
{}
@ -109,6 +120,11 @@ namespace AlphaISA {
bool fonw; // fault on write
bool valid; // valid page table entry
Addr pageStart()
{
return ppn << PageShift;
}
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
};

View file

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

View file

@ -39,9 +39,14 @@ namespace MipsISA
{
struct TlbEntry
{
Addr pageStart;
Addr _pageStart;
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 unserialize(Checkpoint *cp, const std::string &section);

View file

@ -623,64 +623,32 @@ void PowerOnReset::invoke(ThreadContext * tc)
void FastInstructionAccessMMUMiss::invoke(ThreadContext *tc)
{
Process *p = tc->getProcessPtr();
Addr paddr;
bool success = p->pTable->translate(vaddr, paddr);
TlbEntry entry;
bool success = p->pTable->lookup(vaddr, entry);
if(!success) {
panic("Tried to execute unmapped address %#x.\n", vaddr);
} 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);
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)
{
Process *p = tc->getProcessPtr();
Addr paddr;
bool success = p->pTable->translate(vaddr, paddr);
TlbEntry entry;
bool success = p->pTable->lookup(vaddr, entry);
if(!success) {
p->checkAndAllocNextPage(vaddr);
success = p->pTable->translate(vaddr, paddr);
success = p->pTable->lookup(vaddr, entry);
}
if(!success) {
panic("Tried to access unmapped address %#x.\n", vaddr);
} 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);
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 {
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(Addr addr) : pageStart(addr)
{}
TlbRange range;
PageTableEntry pte;
bool used;
bool valid;
Addr pageStart()
{
return pte.paddr();
}
void serialize(std::ostream &os);
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",
vaddr, tc->readPC());
Process *p = tc->getProcessPtr();
Addr paddr;
bool success = p->pTable->translate(vaddr, paddr);
TlbEntry entry;
bool success = p->pTable->lookup(vaddr, entry);
if(!success) {
panic("Tried to execute unmapped address %#x.\n", vaddr);
} 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);
DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, entry.pageStart);
tc->getITBPtr()->insert(alignedVaddr, entry);
@ -143,24 +134,15 @@ namespace X86ISA
DPRINTF(TLB, "Invoking an DTLB fault for address %#x at pc %#x.\n",
vaddr, tc->readPC());
Process *p = tc->getProcessPtr();
Addr paddr;
bool success = p->pTable->translate(vaddr, paddr);
TlbEntry entry;
bool success = p->pTable->lookup(vaddr, entry);
if(!success) {
p->checkAndAllocNextPage(vaddr);
success = p->pTable->translate(vaddr, paddr);
success = p->pTable->lookup(vaddr, entry);
}
if(!success) {
panic("Tried to access unmapped address %#x.\n", vaddr);
} 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);
DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, entry.pageStart);
tc->getDTBPtr()->insert(alignedVaddr, entry);

View file

@ -55,12 +55,18 @@
* Authors: Gabe Black
*/
#include "arch/x86/isa_traits.hh"
#include "arch/x86/pagetable.hh"
#include "sim/serialize.hh"
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
TlbEntry::serialize(std::ostream &os)
{

View file

@ -76,10 +76,16 @@ namespace X86ISA
struct TlbEntry
{
// 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
// other mechanisms.
bool writeable;
bool writable;
// Whether this page is accesible without being in supervisor mode.
bool user;
// 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.
bool noExec;
// The beginning of the virtual page this entry maps.
Addr vaddr;
// The size of the page this entry represents.
Addr size;
TlbEntry(Addr asn, Addr _vaddr, Addr _paddr);
TlbEntry() {}
TlbEntry(Addr paddr) : pageStart(paddr) {}
Addr pageStart()
{
return paddr;
}
void serialize(std::ostream &os);
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
} else {
// Do paging protection checks.
Addr paddr = entry->pageStart | (vaddr & mask(12));
Addr paddr = entry->paddr | (vaddr & mask(12));
req->setPaddr(paddr);
}
} else {

View file

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

View file

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

View file

@ -125,7 +125,7 @@ Process::Process(ProcessParams * params)
mmap_start = mmap_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
}