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
#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;
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
#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"
//@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;
+ }
}
///////////////////////////////////////////////////////////
#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 {
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
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "sim/fault_fwd.hh"
+#include "sim/full_system.hh"
namespace SparcISA
{
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);
#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 {
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());
entry = insert(alignedVaddr, newEntry);
}
DPRINTF(TLB, "Miss was serviced.\n");
-#endif
}
}
// Do paging protection checks.
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;
};
TheISA::Kernel::Statistics *getKernelStats()
{ return actualTC->getKernelStats(); }
-#else
- Process *getProcessPtr() { return actualTC->getProcessPtr(); }
#endif
+ Process *getProcessPtr() { return actualTC->getProcessPtr(); }
TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
{
// 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());
{
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(); }
{ 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(); }
// 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());
TheISA::Kernel::Statistics *getKernelStats()
{ return thread->getKernelStats(); }
-#else
- Process *getProcessPtr() { return thread->getProcessPtr(); }
#endif
+ Process *getProcessPtr() { return thread->getProcessPtr(); }
TranslatingPort *getMemPort() { return thread->getMemPort(); }
// 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());
#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"
#include "sim/sim_exit.hh"
#else
#include "mem/translating_port.hh"
-#include "sim/process.hh"
#include "sim/system.hh"
#endif
// 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
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;
{ 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(); }
void profileSample();
TheISA::Kernel::Statistics *getKernelStats() { return kernelStats; }
-#else
- Process *getProcessPtr() { return process; }
#endif
+ Process *getProcessPtr() { return process; }
TranslatingPort *getMemPort();
#include "base/types.hh"
#include "config/full_system.hh"
-#if FULL_SYSTEM
-
-class Linux {};
-
-#else //!FULL_SYSTEM
-
#include <string>
#include "kern/operatingsystem.hh"
}; // class Linux
-
-#endif // FULL_SYSTEM
-
#endif // __LINUX_HH__
#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;
}; // class OperatingSystem
-
-#endif // FULL_SYSTEM
-
#endif // __OPERATINGSYSTEM_HH__