SE/FS: Make getProcessPtr available in both modes, and get rid of FULL_SYSTEMs.

This commit is contained in:
Gabe Black
2011-10-30 00:33:02 -07:00
parent 5b433568f0
commit facb40f3ff
18 changed files with 118 additions and 295 deletions

View File

@@ -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();
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, true);
}
} else if(IsKSeg1(vaddr)) {
// Address will not be translated through TLB, set response, and go!
req->setPaddr(KSeg02Phys(vaddr));
} 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
if (!FullSystem) {
//@TODO: This should actually use TLB instead of going directly
// to the page table in syscall mode.
/**
* Check for alignment faults
*/
Addr VPN = (vaddr >> 11) & 0xFFFFFFFC;
if (smallPages == 1) {
VPN = vaddr >> 11;
if (req->getVaddr() & (req->getSize() - 1)) {
DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(),
req->getSize());
return new AddressErrorFault(req->getVaddr(), write);
}
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);
}
Process * p = tc->getProcessPtr();
Fault fault = p->pTable->translate(req);
if (fault != NoFault)
return fault;
return NoFault;
} else {
panic("translateData not implemented in MIPS.\n");
}
return checkCacheability(req);
#endif
}
Fault

View File

@@ -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

View File

@@ -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;
}
}
///////////////////////////////////////////////////////////

View File

@@ -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<uint64_t>(sp + 92 +
(number-NumArgumentRegs) * sizeof(uint64_t));
return arg;
}
} else {
Addr sp = tc->readIntReg(StackPointerReg);
VirtualPort *vp = tc->getVirtPort();
uint64_t arg = vp->read<uint64_t>(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

View File

@@ -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);

View File

@@ -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;
};

View File

@@ -96,9 +96,8 @@ class CheckerThreadContext : public ThreadContext
TheISA::Kernel::Statistics *getKernelStats()
{ return actualTC->getKernelStats(); }
#else
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
#endif
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
TranslatingPort *getMemPort() { return actualTC->getMemPort(); }

View File

@@ -85,11 +85,7 @@ InOrderThreadContext::takeOverFrom(ThreadContext *old_context)
{
// some things should already be set up
assert(getSystemPtr() == old_context->getSystemPtr());
#if !FULL_SYSTEM
assert(getProcessPtr() == old_context->getProcessPtr());
#endif
// copy over functional state
setStatus(old_context->status());

View File

@@ -142,10 +142,9 @@ class InOrderThreadContext : public ThreadContext
{
return this->thread->quiesceEvent;
}
#else
#endif
/** Returns a pointer to this thread's process. */
Process *getProcessPtr() { return thread->getProcessPtr(); }
#endif
TranslatingPort *getMemPort() { return thread->getMemPort(); }

View File

@@ -98,10 +98,9 @@ class O3ThreadContext : public ThreadContext
{ return thread->kernelStats; }
virtual void connectMemPorts(ThreadContext *tc) { thread->connectMemPorts(tc); }
#else
#endif
/** Returns a pointer to this thread's process. */
virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
#endif
virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }

View File

@@ -70,9 +70,8 @@ O3ThreadContext<Impl>::takeOverFrom(ThreadContext *old_context)
// some things should already be set up
#if FULL_SYSTEM
assert(getSystemPtr() == old_context->getSystemPtr());
#else
assert(getProcessPtr() == old_context->getProcessPtr());
#endif
assert(getProcessPtr() == old_context->getProcessPtr());
// copy over functional state
setStatus(old_context->status());

View File

@@ -123,9 +123,8 @@ class OzoneCPU : public BaseCPU
TheISA::Kernel::Statistics *getKernelStats()
{ return thread->getKernelStats(); }
#else
Process *getProcessPtr() { return thread->getProcessPtr(); }
#endif
Process *getProcessPtr() { return thread->getProcessPtr(); }
TranslatingPort *getMemPort() { return thread->getMemPort(); }

View File

@@ -671,9 +671,8 @@ OzoneCPU<Impl>::OzoneTC::takeOverFrom(ThreadContext *old_context)
// some things should already be set up
#if FULL_SYSTEM
assert(getSystemPtr() == old_context->getSystemPtr());
#else
assert(getProcessPtr() == old_context->getProcessPtr());
#endif
assert(getProcessPtr() == old_context->getProcessPtr());
// copy over functional state
setStatus(old_context->status());

View File

@@ -41,6 +41,7 @@
#include "cpu/thread_context.hh"
#include "mem/vport.hh"
#include "params/BaseCPU.hh"
#include "sim/process.hh"
#if FULL_SYSTEM
#include "arch/kernel_stats.hh"
@@ -55,7 +56,6 @@
#include "sim/sim_exit.hh"
#else
#include "mem/translating_port.hh"
#include "sim/process.hh"
#include "sim/system.hh"
#endif
@@ -123,9 +123,8 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext)
// some things should already be set up
#if FULL_SYSTEM
assert(system == oldContext->getSystemPtr());
#else
assert(process == oldContext->getProcessPtr());
#endif
assert(process == oldContext->getProcessPtr());
copyState(oldContext);
#if FULL_SYSTEM

View File

@@ -129,9 +129,8 @@ class ThreadContext
virtual TheISA::Kernel::Statistics *getKernelStats() = 0;
virtual void connectMemPorts(ThreadContext *tc) = 0;
#else
virtual Process *getProcessPtr() = 0;
#endif
virtual Process *getProcessPtr() = 0;
virtual TranslatingPort *getMemPort() = 0;
@@ -299,9 +298,8 @@ class ProxyThreadContext : public ThreadContext
{ return actualTC->getKernelStats(); }
void connectMemPorts(ThreadContext *tc) { actualTC->connectMemPorts(tc); }
#else
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
#endif
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
TranslatingPort *getMemPort() { return actualTC->getMemPort(); }

View File

@@ -101,9 +101,8 @@ struct ThreadState {
void profileSample();
TheISA::Kernel::Statistics *getKernelStats() { return kernelStats; }
#else
Process *getProcessPtr() { return process; }
#endif
Process *getProcessPtr() { return process; }
TranslatingPort *getMemPort();

View File

@@ -34,12 +34,6 @@
#include "base/types.hh"
#include "config/full_system.hh"
#if FULL_SYSTEM
class Linux {};
#else //!FULL_SYSTEM
#include <string>
#include "kern/operatingsystem.hh"
@@ -180,7 +174,4 @@ class Linux : public OperatingSystem
}; // class Linux
#endif // FULL_SYSTEM
#endif // __LINUX_HH__

View File

@@ -32,13 +32,7 @@
#define __KERN_OPERATINGSYSTEM_HH__
#include "base/types.hh"
#include "config/full_system.hh"
#if FULL_SYSTEM
class OperatingSystem {};
#else //!FULL_SYSTEM
#include <string>
class LiveProcess;
@@ -128,7 +122,4 @@ class OperatingSystem {
}; // class OperatingSystem
#endif // FULL_SYSTEM
#endif // __OPERATINGSYSTEM_HH__