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:
parent
0711f4f17a
commit
fddfa71658
13 changed files with 106 additions and 120 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 §ion);
|
||||
};
|
||||
|
|
|
@ -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 §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(pageStart);
|
||||
UNSERIALIZE_SCALAR(_pageStart);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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 §ion);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 §ion);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 §ion);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue