From fddfa71658a35f91c249ce0b7b67984d979a4fb4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 25 Oct 2007 19:04:44 -0700 Subject: [PATCH] TLB: Fix serialization issues with the tlb entries and make the page table store the process, not the system. --HG-- extra : convert_revision : 2421af11f62f60fb48faeee6bddadac2987df0e8 --- src/arch/alpha/faults.cc | 36 ++++------------------------- src/arch/alpha/pagetable.hh | 22 +++++++++++++++--- src/arch/mips/tlb.cc | 4 ++-- src/arch/mips/tlb.hh | 9 ++++++-- src/arch/sparc/faults.cc | 46 ++++++------------------------------- src/arch/sparc/pagetable.hh | 33 +++++++++++++++++++++++--- src/arch/x86/faults.cc | 28 ++++------------------ src/arch/x86/pagetable.cc | 6 +++++ src/arch/x86/pagetable.hh | 22 +++++++++++------- src/arch/x86/tlb.cc | 2 +- src/mem/page_table.cc | 10 ++++---- src/mem/page_table.hh | 6 ++--- src/sim/process.cc | 2 +- 13 files changed, 106 insertions(+), 120 deletions(-) diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index 7d4de902a..20591b357 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -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); } } diff --git a/src/arch/alpha/pagetable.hh b/src/arch/alpha/pagetable.hh index 4375f24f1..8ce5b4e5d 100644 --- a/src/arch/alpha/pagetable.hh +++ b/src/arch/alpha/pagetable.hh @@ -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); }; diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc index b644ae18d..a911e3c0b 100644 --- a/src/arch/mips/tlb.cc +++ b/src/arch/mips/tlb.cc @@ -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); } }; diff --git a/src/arch/mips/tlb.hh b/src/arch/mips/tlb.hh index 78b4af94d..cff805bef 100644 --- a/src/arch/mips/tlb.hh +++ b/src/arch/mips/tlb.hh @@ -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); diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 07d332b58..e201cef95 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -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); } } diff --git a/src/arch/sparc/pagetable.hh b/src/arch/sparc/pagetable.hh index 961870579..bf7f34b60 100644 --- a/src/arch/sparc/pagetable.hh +++ b/src/arch/sparc/pagetable.hh @@ -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); diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index 69cbadc93..b9cac0297 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -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); diff --git a/src/arch/x86/pagetable.cc b/src/arch/x86/pagetable.cc index 49aaab068..e16d6e659 100644 --- a/src/arch/x86/pagetable.cc +++ b/src/arch/x86/pagetable.cc @@ -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) { diff --git a/src/arch/x86/pagetable.hh b/src/arch/x86/pagetable.hh index aaf82ed70..cc614168c 100644 --- a/src/arch/x86/pagetable.hh +++ b/src/arch/x86/pagetable.hh @@ -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); diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index d55f04080..6afee6d72 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -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 { diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc index 8889879c3..6220305b8 100644 --- a/src/mem/page_table.cc +++ b/src/mem/page_table.cc @@ -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; } diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh index 845bb9112..b8b52174c 100644 --- a/src/mem/page_table.hh +++ b/src/mem/page_table.hh @@ -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(); diff --git a/src/sim/process.cc b/src/sim/process.cc index 01155ae32..668be367d 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -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 } -- 2.30.2