From facb40f3ffce30cd9bc3b904eed5761d2d8b91c9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 30 Oct 2011 00:33:02 -0700 Subject: SE/FS: Make getProcessPtr available in both modes, and get rid of FULL_SYSTEMs. --- src/arch/mips/tlb.cc | 185 ++++++------------------------------------- src/arch/sparc/faults.cc | 58 +++++++------- src/arch/sparc/remote_gdb.cc | 25 +++--- src/arch/sparc/utility.cc | 28 +++---- src/arch/sparc/utility.hh | 7 +- src/arch/x86/tlb.cc | 52 ++++++------ 6 files changed, 105 insertions(+), 250 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc index e35ac6d4a..52e13dfc3 100644 --- a/src/arch/mips/tlb.cc +++ b/src/arch/mips/tlb.cc @@ -295,182 +295,45 @@ TLB::regStats() Fault TLB::translateInst(RequestPtr req, ThreadContext *tc) { -#if !FULL_SYSTEM - Process * p = tc->getProcessPtr(); + if (!FullSystem) { + Process * p = tc->getProcessPtr(); - Fault fault = p->pTable->translate(req); - if (fault != NoFault) - return fault; + Fault fault = p->pTable->translate(req); + if (fault != NoFault) + return fault; - return NoFault; -#else - Addr vaddr = req->getVaddr(); - - bool misaligned = (req->getSize() - 1) & vaddr; - - if (IsKSeg0(vaddr)) { - // Address will not be translated through TLB, set response, and go! - req->setPaddr(KSeg02Phys(vaddr)); - if (getOperatingMode(tc->readMiscReg(MISCREG_STATUS)) != mode_kernel || - misaligned) { - return new AddressErrorFault(vaddr, false); - } - } else if(IsKSeg1(vaddr)) { - // Address will not be translated through TLB, set response, and go! - req->setPaddr(KSeg02Phys(vaddr)); + return NoFault; } else { - /* - * This is an optimization - smallPages is updated every time a TLB - * operation is performed. That way, we don't need to look at - * Config3 _ SP and PageGrain _ ESP every time we do a TLB lookup - */ - Addr VPN; - if (smallPages == 1) { - VPN = (vaddr >> 11); - } else { - VPN = ((vaddr >> 11) & 0xFFFFFFFC); - } - uint8_t Asid = req->getAsid(); - if (misaligned) { - // Unaligned address! - return new AddressErrorFault(vaddr, false); - } - PTE *pte = lookup(VPN,Asid); - if (pte != NULL) { - // Ok, found something - /* Check for valid bits */ - int EvenOdd; - bool Valid; - if ((((vaddr) >> pte->AddrShiftAmount) & 1) == 0) { - // Check even bits - Valid = pte->V0; - EvenOdd = 0; - } else { - // Check odd bits - Valid = pte->V1; - EvenOdd = 1; - } - - if (Valid == false) { - return new InvalidFault(Asid, vaddr, vpn, false); - } else { - // Ok, this is really a match, set paddr - Addr PAddr; - if (EvenOdd == 0) { - PAddr = pte->PFN0; - } else { - PAddr = pte->PFN1; - } - PAddr >>= (pte->AddrShiftAmount - 12); - PAddr <<= pte->AddrShiftAmount; - PAddr |= (vaddr & pte->OffsetMask); - req->setPaddr(PAddr); - } - } else { - // Didn't find any match, return a TLB Refill Exception - return new RefillFault(Asid, vaddr, vpn, false); - } + panic("translateInst not implemented in MIPS.\n"); } - return checkCacheability(req); -#endif } Fault TLB::translateData(RequestPtr req, ThreadContext *tc, bool write) { -#if !FULL_SYSTEM - //@TODO: This should actually use TLB instead of going directly - // to the page table in syscall mode. - /** - * Check for alignment faults - */ - if (req->getVaddr() & (req->getSize() - 1)) { - DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(), - req->getSize()); - return new AddressErrorFault(req->getVaddr(), write); - } - - - Process * p = tc->getProcessPtr(); + if (!FullSystem) { + //@TODO: This should actually use TLB instead of going directly + // to the page table in syscall mode. + /** + * Check for alignment faults + */ + if (req->getVaddr() & (req->getSize() - 1)) { + DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(), + req->getSize()); + return new AddressErrorFault(req->getVaddr(), write); + } - Fault fault = p->pTable->translate(req); - if (fault != NoFault) - return fault; - return NoFault; -#else - Addr vaddr = req->getVaddr(); + Process * p = tc->getProcessPtr(); - bool misaligned = (req->getSize() - 1) & vaddr; + Fault fault = p->pTable->translate(req); + if (fault != NoFault) + return fault; - if (IsKSeg0(vaddr)) { - // Address will not be translated through TLB, set response, and go! - req->setPaddr(KSeg02Phys(vaddr)); - if (getOperatingMode(tc->readMiscReg(MISCREG_STATUS)) != mode_kernel || - misaligned) { - return new AddressErrorFault(vaddr, true); - } - } else if(IsKSeg1(vaddr)) { - // Address will not be translated through TLB, set response, and go! - req->setPaddr(KSeg02Phys(vaddr)); + return NoFault; } else { - /* - * This is an optimization - smallPages is updated every time a TLB - * operation is performed. That way, we don't need to look at - * Config3 _ SP and PageGrain _ ESP every time we do a TLB lookup - */ - Addr VPN = (vaddr >> 11) & 0xFFFFFFFC; - if (smallPages == 1) { - VPN = vaddr >> 11; - } - uint8_t Asid = req->getAsid(); - PTE *pte = lookup(VPN, Asid); - if (misaligned) { - return new AddressErrorFault(vaddr, true); - } - if (pte != NULL) { - // Ok, found something - /* Check for valid bits */ - int EvenOdd; - bool Valid; - bool Dirty; - if ((((vaddr >> pte->AddrShiftAmount) & 1)) == 0) { - // Check even bits - Valid = pte->V0; - Dirty = pte->D0; - EvenOdd = 0; - } else { - // Check odd bits - Valid = pte->V1; - Dirty = pte->D1; - EvenOdd = 1; - } - - if (Valid == false) { - return new InvalidFault(Asid, vaddr, VPN, true); - } else { - // Ok, this is really a match, set paddr - if (!Dirty) { - return new TlbModifiedFault(Asid, vaddr, VPN); - } - Addr PAddr; - if (EvenOdd == 0) { - PAddr = pte->PFN0; - } else { - PAddr = pte->PFN1; - } - PAddr >>= (pte->AddrShiftAmount - 12); - PAddr <<= pte->AddrShiftAmount; - PAddr |= (vaddr & pte->OffsetMask); - req->setPaddr(PAddr); - } - } else { - // Didn't find any match, return a TLB Refill Exception - return new RefillFault(Asid, vaddr, VPN, true); - } + panic("translateData not implemented in MIPS.\n"); } - return checkCacheability(req); -#endif } Fault diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index fb0f6acb1..584b8299c 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -41,9 +41,9 @@ #include "cpu/thread_context.hh" #if !FULL_SYSTEM #include "arch/sparc/process.hh" +#endif #include "mem/page_table.hh" #include "sim/process.hh" -#endif #include "sim/full_system.hh" using namespace std; @@ -624,43 +624,43 @@ PowerOnReset::invoke(ThreadContext *tc, StaticInstPtr inst) void FastInstructionAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst) { -#if !FULL_SYSTEM - Process *p = tc->getProcessPtr(); - TlbEntry entry; - bool success = p->pTable->lookup(vaddr, entry); - if (!success) { - panic("Tried to execute unmapped address %#x.\n", vaddr); + if (FullSystem) { + SparcFaultBase::invoke(tc, inst); } else { - Addr alignedVaddr = p->pTable->pageAlign(vaddr); - tc->getITBPtr()->insert(alignedVaddr, 0 /*partition id*/, - p->M5_pid /*context id*/, false, entry.pte); + Process *p = tc->getProcessPtr(); + TlbEntry entry; + bool success = p->pTable->lookup(vaddr, entry); + if (!success) { + panic("Tried to execute unmapped address %#x.\n", vaddr); + } else { + Addr alignedVaddr = p->pTable->pageAlign(vaddr); + tc->getITBPtr()->insert(alignedVaddr, 0 /*partition id*/, + p->M5_pid /*context id*/, false, entry.pte); + } } -#else - SparcFaultBase::invoke(tc, inst); -#endif } void FastDataAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst) { -#if !FULL_SYSTEM - Process *p = tc->getProcessPtr(); - TlbEntry entry; - bool success = p->pTable->lookup(vaddr, entry); - if (!success) { - if (p->fixupStackFault(vaddr)) - success = p->pTable->lookup(vaddr, entry); - } - if (!success) { - panic("Tried to access unmapped address %#x.\n", vaddr); + if (FullSystem) { + SparcFaultBase::invoke(tc, inst); } else { - Addr alignedVaddr = p->pTable->pageAlign(vaddr); - tc->getDTBPtr()->insert(alignedVaddr, 0 /*partition id*/, - p->M5_pid /*context id*/, false, entry.pte); + Process *p = tc->getProcessPtr(); + TlbEntry entry; + bool success = p->pTable->lookup(vaddr, entry); + if (!success) { + if (p->fixupStackFault(vaddr)) + success = p->pTable->lookup(vaddr, entry); + } + if (!success) { + panic("Tried to access unmapped address %#x.\n", vaddr); + } else { + Addr alignedVaddr = p->pTable->pageAlign(vaddr); + tc->getDTBPtr()->insert(alignedVaddr, 0 /*partition id*/, + p->M5_pid /*context id*/, false, entry.pte); + } } -#else - SparcFaultBase::invoke(tc, inst); -#endif } void diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc index 712314e01..ed77000fe 100644 --- a/src/arch/sparc/remote_gdb.cc +++ b/src/arch/sparc/remote_gdb.cc @@ -135,6 +135,7 @@ #include "mem/physical.hh" #include "mem/port.hh" #include "sim/byteswap.hh" +#include "sim/full_system.hh" #include "sim/process.hh" #include "sim/system.hh" @@ -156,18 +157,18 @@ RemoteGDB::acc(Addr va, size_t len) //@Todo In NetBSD, this function checks if all addresses // from va to va + len have valid page map entries. Not // sure how this will work for other OSes or in general. -#if FULL_SYSTEM - if (va) - return true; - return false; -#else - TlbEntry entry; - // Check to make sure the first byte is mapped into the processes address - // space. - if (context->getProcessPtr()->pTable->lookup(va, entry)) - return true; - return false; -#endif + if (FullSystem) { + if (va) + return true; + return false; + } else { + TlbEntry entry; + // Check to make sure the first byte is mapped into the processes + // address space. + if (context->getProcessPtr()->pTable->lookup(va, entry)) + return true; + return false; + } } /////////////////////////////////////////////////////////// diff --git a/src/arch/sparc/utility.cc b/src/arch/sparc/utility.cc index c6616f43e..63b8e7960 100644 --- a/src/arch/sparc/utility.cc +++ b/src/arch/sparc/utility.cc @@ -31,10 +31,8 @@ #include "arch/sparc/faults.hh" #include "arch/sparc/utility.hh" -#if FULL_SYSTEM #include "arch/sparc/vtophys.hh" #include "mem/vport.hh" -#endif namespace SparcISA { @@ -48,21 +46,21 @@ namespace SparcISA { uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) { -#if FULL_SYSTEM - const int NumArgumentRegs = 6; - if (number < NumArgumentRegs) { - return tc->readIntReg(8 + number); + if (FullSystem) { + const int NumArgumentRegs = 6; + if (number < NumArgumentRegs) { + return tc->readIntReg(8 + number); + } else { + Addr sp = tc->readIntReg(StackPointerReg); + VirtualPort *vp = tc->getVirtPort(); + uint64_t arg = vp->read(sp + 92 + + (number-NumArgumentRegs) * sizeof(uint64_t)); + return arg; + } } else { - Addr sp = tc->readIntReg(StackPointerReg); - VirtualPort *vp = tc->getVirtPort(); - uint64_t arg = vp->read(sp + 92 + - (number-NumArgumentRegs) * sizeof(uint64_t)); - return arg; + panic("getArgument() only implemented for full system\n"); + M5_DUMMY_RETURN } -#else - panic("getArgument() only implemented for FULL_SYSTEM\n"); - M5_DUMMY_RETURN -#endif } void diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh index 76b551ac8..ee94ef29a 100644 --- a/src/arch/sparc/utility.hh +++ b/src/arch/sparc/utility.hh @@ -39,6 +39,7 @@ #include "cpu/static_inst.hh" #include "cpu/thread_context.hh" #include "sim/fault_fwd.hh" +#include "sim/full_system.hh" namespace SparcISA { @@ -73,13 +74,9 @@ void initCPU(ThreadContext *tc, int cpuId); inline void startupCPU(ThreadContext *tc, int cpuId) { -#if FULL_SYSTEM // Other CPUs will get activated by IPIs - if (cpuId == 0) + if (cpuId == 0 || !FullSystem) tc->activate(0); -#else - tc->activate(0); -#endif } void copyRegs(ThreadContext *src, ThreadContext *dest); diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 88eb19b54..ff30697e5 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -54,14 +54,10 @@ #include "cpu/thread_context.hh" #include "debug/TLB.hh" #include "mem/packet_access.hh" -#include "mem/request.hh" - -#if !FULL_SYSTEM #include "mem/page_table.hh" -#include "sim/process.hh" -#endif - +#include "mem/request.hh" #include "sim/full_system.hh" +#include "sim/process.hh" namespace X86ISA { @@ -302,7 +298,6 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, entry = lookup(vaddr); assert(entry); } else { -#if !FULL_SYSTEM DPRINTF(TLB, "Handling a TLB miss for " "address %#x at pc %#x.\n", vaddr, tc->instAddr()); @@ -326,7 +321,6 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, entry = insert(alignedVaddr, newEntry); } DPRINTF(TLB, "Miss was serviced.\n"); -#endif } } // Do paging protection checks. @@ -367,27 +361,29 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, req->setPaddr(vaddr); } // Check for an access to the local APIC -#if FULL_SYSTEM - LocalApicBase localApicBase = tc->readMiscRegNoEffect(MISCREG_APIC_BASE); - Addr baseAddr = localApicBase.base * PageBytes; - Addr paddr = req->getPaddr(); - if (baseAddr <= paddr && baseAddr + PageBytes > paddr) { - // The Intel developer's manuals say the below restrictions apply, - // but the linux kernel, because of a compiler optimization, breaks - // them. - /* - // Check alignment - if (paddr & ((32/8) - 1)) - return new GeneralProtection(0); - // Check access size - if (req->getSize() != (32/8)) - return new GeneralProtection(0); - */ - // Force the access to be uncacheable. - req->setFlags(Request::UNCACHEABLE); - req->setPaddr(x86LocalAPICAddress(tc->contextId(), paddr - baseAddr)); + if (FullSystem) { + LocalApicBase localApicBase = + tc->readMiscRegNoEffect(MISCREG_APIC_BASE); + Addr baseAddr = localApicBase.base * PageBytes; + Addr paddr = req->getPaddr(); + if (baseAddr <= paddr && baseAddr + PageBytes > paddr) { + // The Intel developer's manuals say the below restrictions apply, + // but the linux kernel, because of a compiler optimization, breaks + // them. + /* + // Check alignment + if (paddr & ((32/8) - 1)) + return new GeneralProtection(0); + // Check access size + if (req->getSize() != (32/8)) + return new GeneralProtection(0); + */ + // Force the access to be uncacheable. + req->setFlags(Request::UNCACHEABLE); + req->setPaddr(x86LocalAPICAddress(tc->contextId(), + paddr - baseAddr)); + } } -#endif return NoFault; }; -- cgit v1.2.3