Addr addr = 0;
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
Tick cpuFreq = tc->getCpuPtr()->frequency();
- Tick intrFreq = platform->intrFrequency();
+ assert(intrFreq);
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
}
}
LinuxAlphaSystem(Params *p);
~LinuxAlphaSystem();
+ /**
+ * Initialise the system
+ */
+ virtual void initState();
+
void setDelayLoop(ThreadContext *tc);
++
++ const Params *params() const { return (const Params *)_params; }
};
#endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__
bool
RemoteGDB::acc(Addr va, size_t len)
{
-#if !FULL_SYSTEM
- panic("acc function needs to be rewritten for SE mode\n");
-#else
- Addr last_va;
-
- va = TruncPage(va);
- last_va = RoundPage(va + len);
-
- do {
- if (IsK0Seg(va)) {
- if (va < (K0SegBase + pmem->size())) {
- DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
- "%#x < K0SEG + size\n", va);
+ if (FullSystem) {
+ Addr last_va;
+
+ va = TruncPage(va);
+ last_va = RoundPage(va + len);
+
+ do {
+ if (IsK0Seg(va)) {
+ if (va < (K0SegBase + pmem->size())) {
+ DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
+ "%#x < K0SEG + size\n", va);
+ return true;
+ } else {
+ DPRINTF(GDBAcc, "acc: Mapping invalid %#x "
+ "> K0SEG + size\n", va);
+ return false;
+ }
+ }
+
+ /**
+ * This code says that all accesses to palcode (instruction
+ * and data) are valid since there isn't a va->pa mapping
+ * because palcode is accessed physically. At some point this
+ * should probably be cleaned up but there is no easy way to
+ * do it.
+ */
+
+ if (PcPAL(va) || va < 0x10000)
return true;
- } else {
- DPRINTF(GDBAcc, "acc: Mapping invalid %#x > K0SEG + size\n",
- va);
+
+ Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
+ PageTableEntry pte =
- kernel_pte_lookup(context->getPhysPort(), ptbr, va);
++ kernel_pte_lookup(context->getPhysProxy(), ptbr, va);
+ if (!pte.valid()) {
+ DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
return false;
}
- }
-
- /**
- * This code says that all accesses to palcode (instruction
- * and data) are valid since there isn't a va->pa mapping
- * because palcode is accessed physically. At some point this
- * should probably be cleaned up but there is no easy way to
- * do it.
- */
-
- if (PcPAL(va) || va < 0x10000)
- return true;
-
- Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
- PageTableEntry pte =
- kernel_pte_lookup(context->getPhysProxy(), ptbr, va);
- if (!pte.valid()) {
- DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
- return false;
- }
- va += PageBytes;
- } while (va < last_va);
+ va += PageBytes;
+ } while (va < last_va);
- DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
- return true;
-#endif
+ DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
+ return true;
+ } else {
+ panic("acc function needs to be rewritten for SE mode\n");
+ }
}
/*
*/
#include "arch/alpha/utility.hh"
-
-#if FULL_SYSTEM
#include "arch/alpha/vtophys.hh"
- #include "mem/vport.hh"
+ #include "mem/fs_translating_port_proxy.hh"
-#endif
+#include "sim/full_system.hh"
namespace AlphaISA {
uint64_t
getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
{
-#if FULL_SYSTEM
- const int NumArgumentRegs = 6;
- if (number < NumArgumentRegs) {
- if (fp)
- return tc->readFloatRegBits(16 + number);
- else
- return tc->readIntReg(16 + number);
+ if (FullSystem) {
+ const int NumArgumentRegs = 6;
+ if (number < NumArgumentRegs) {
+ if (fp)
+ return tc->readFloatRegBits(16 + number);
+ else
+ return tc->readIntReg(16 + number);
+ } else {
+ Addr sp = tc->readIntReg(StackPointerReg);
- VirtualPort *vp = tc->getVirtPort();
++ FSTranslatingPortProxy* vp = tc->getVirtProxy();
+ uint64_t arg = vp->read<uint64_t>(sp +
+ (number-NumArgumentRegs) * sizeof(uint64_t));
+ return arg;
+ }
} else {
- Addr sp = tc->readIntReg(StackPointerReg);
- FSTranslatingPortProxy* vp = tc->getVirtProxy();
- uint64_t arg = vp->read<uint64_t>(sp +
- (number-NumArgumentRegs) * sizeof(uint64_t));
- return arg;
+ panic("getArgument() is Full system only\n");
+ M5_DUMMY_RETURN;
}
-#else
- panic("getArgument() is Full system only\n");
- M5_DUMMY_RETURN;
-#endif
}
void
#include "arch/arm/faults.hh"
#include "arch/arm/isa_traits.hh"
+#include "arch/arm/tlb.hh"
#include "arch/arm/utility.hh"
-#include "cpu/thread_context.hh"
-
-#if FULL_SYSTEM
#include "arch/arm/vtophys.hh"
- #include "mem/vport.hh"
+#include "cpu/thread_context.hh"
-#endif
-
-#include "arch/arm/tlb.hh"
+ #include "mem/fs_translating_port_proxy.hh"
+#include "sim/full_system.hh"
namespace ArmISA {
uint64_t
getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
{
-#if FULL_SYSTEM
- if (size == (uint16_t)(-1))
- size = ArmISA::MachineBytes;
- if (fp)
- panic("getArgument(): Floating point arguments not implemented\n");
+ if (FullSystem) {
+ if (size == (uint16_t)(-1))
+ size = ArmISA::MachineBytes;
+ if (fp)
+ panic("getArgument(): Floating point arguments not implemented\n");
- if (number < NumArgumentRegs) {
- // If the argument is 64 bits, it must be in an even regiser number
- // Increment the number here if it isn't even
- if (size == sizeof(uint64_t)) {
- if ((number % 2) != 0)
- number++;
- // Read the two halves of the data
- // number is inc here to get the second half of the 64 bit reg
- uint64_t tmp;
- tmp = tc->readIntReg(number++);
- tmp |= tc->readIntReg(number) << 32;
- return tmp;
+ if (number < NumArgumentRegs) {
+ // If the argument is 64 bits, it must be in an even regiser
+ // number. Increment the number here if it isn't even.
+ if (size == sizeof(uint64_t)) {
+ if ((number % 2) != 0)
+ number++;
+ // Read the two halves of the data. Number is inc here to
+ // get the second half of the 64 bit reg.
+ uint64_t tmp;
+ tmp = tc->readIntReg(number++);
+ tmp |= tc->readIntReg(number) << 32;
+ return tmp;
+ } else {
+ return tc->readIntReg(number);
+ }
} else {
- return tc->readIntReg(number);
- }
- } else {
- Addr sp = tc->readIntReg(StackPointerReg);
- FSTranslatingPortProxy* vp = tc->getVirtProxy();
- uint64_t arg;
- if (size == sizeof(uint64_t)) {
- // If the argument is even it must be aligned
- if ((number % 2) != 0)
+ Addr sp = tc->readIntReg(StackPointerReg);
- VirtualPort *vp = tc->getVirtPort();
++ FSTranslatingPortProxy* vp = tc->getVirtProxy();
+ uint64_t arg;
+ if (size == sizeof(uint64_t)) {
+ // If the argument is even it must be aligned
+ if ((number % 2) != 0)
+ number++;
+ arg = vp->read<uint64_t>(sp +
+ (number-NumArgumentRegs) * sizeof(uint32_t));
+ // since two 32 bit args == 1 64 bit arg, increment number
number++;
- arg = vp->read<uint64_t>(sp +
- (number-NumArgumentRegs) * sizeof(uint32_t));
- // since two 32 bit args == 1 64 bit arg, increment number
- number++;
- } else {
- arg = vp->read<uint32_t>(sp +
- (number-NumArgumentRegs) * sizeof(uint32_t));
+ } else {
+ arg = vp->read<uint32_t>(sp +
+ (number-NumArgumentRegs) * sizeof(uint32_t));
+ }
+ return arg;
}
- return arg;
+ } else {
+ panic("getArgument() only implemented for full system mode.\n");
+ M5_DUMMY_RETURN
}
-#else
- panic("getArgument() only implemented for FULL_SYSTEM\n");
- M5_DUMMY_RETURN
-#endif
}
void
LinuxMipsSystem::LinuxMipsSystem(Params *p)
: MipsSystem(p)
{
-- Addr addr = 0;
--
-- /**
-- * The symbol swapper_pg_dir marks the beginning of the kernel and
-- * the location of bootloader passed arguments
-- */
-- if (!kernelSymtab->findAddress("swapper_pg_dir", KernelStart)) {
-- panic("Could not determine start location of kernel");
-- }
--
-- /**
-- * Since we aren't using a bootloader, we have to copy the
-- * kernel arguments directly into the kernel's memory.
-- */
- virtPort->writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(),
- virtPort.writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(),
-- params()->boot_osflags.length()+1);
--
-- /**
-- * find the address of the est_cycle_freq variable and insert it
-- * so we don't through the lengthly process of trying to
-- * calculated it by using the PIT, RTC, etc.
-- */
-- if (kernelSymtab->findAddress("est_cycle_freq", addr))
- virtPort->write(addr, (uint64_t)(SimClock::Frequency /
- virtPort.write(addr, (uint64_t)(SimClock::Frequency /
-- p->boot_cpu_frequency));
--
-- /**
-- * EV5 only supports 127 ASNs so we are going to tell the kernel that the
-- * paritiuclar EV6 we have only supports 127 asns.
-- * @todo At some point we should change ev5.hh and the palcode to support
-- * 255 ASNs.
-- */
-- if (kernelSymtab->findAddress("dp264_mv", addr))
- virtPort->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
- virtPort.write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
-- else
-- panic("could not find dp264_mv\n");
--
--#ifndef NDEBUG
-- kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
-- if (!kernelPanicEvent)
-- panic("could not find kernel symbol \'panic\'");
--
--#endif
--
-- /**
-- * Any time ide_delay_50ms, calibarte_delay or
-- * determine_cpu_caches is called just skip the
-- * function. Currently determine_cpu_caches only is used put
-- * information in proc, however if that changes in the future we
-- * will have to fill in the cache size variables appropriately.
-- */
--
-- skipIdeDelay50msEvent =
-- addKernelFuncEvent<SkipFuncEvent>("ide_delay_50ms");
-- skipDelayLoopEvent =
-- addKernelFuncEvent<SkipDelayLoopEvent>("calibrate_delay");
-- skipCacheProbeEvent =
-- addKernelFuncEvent<SkipFuncEvent>("determine_cpu_caches");
-- debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
-- idleStartEvent = addKernelFuncEvent<IdleStartEvent>("cpu_idle");
--
-- // Disable for now as it runs into panic() calls in VPTr methods
-- // (see sim/vptr.hh). Once those bugs are fixed, we can
-- // re-enable, but we should find a better way to turn it on than
-- // using DTRACE(Thread), since looking at a trace flag at tick 0
-- // leads to non-intuitive behavior with --trace-start.
-- if (false && kernelSymtab->findAddress("mips_switch_to", addr)) {
-- printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo",
-- addr + sizeof(MachInst) * 6);
-- } else {
-- printThreadEvent = NULL;
-- }
}
LinuxMipsSystem::~LinuxMipsSystem()
{
--#ifndef NDEBUG
-- delete kernelPanicEvent;
--#endif
-- delete skipIdeDelay50msEvent;
-- delete skipDelayLoopEvent;
-- delete skipCacheProbeEvent;
-- delete debugPrintkEvent;
-- delete idleStartEvent;
-- delete printThreadEvent;
}
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
- #include "mem/vport.hh"
++#include "mem/fs_translating_port_proxy.hh"
#include "sim/system.hh"
using namespace std;
MipsSystem::MipsSystem(Params *p) : System(p)
{
-
-#if FULL_SYSTEM
-- if (p->bare_iron == true) {
-- hexFile = new HexFile(params()->hex_file_name);
-- if (!hexFile->loadSections(functionalPort))
-- panic("Could not load hex file\n");
-- }
--
-- Addr addr = 0;
--
-- consoleSymtab = new SymbolTable;
--
--
-- /**
-- * Load the console code into memory
-- */
-- // Load Console Code
-- console = createObjectFile(params()->console);
--
-- warn("console code is located at: %s\n", params()->console);
--
-- if (console == NULL)
-- fatal("Could not load console file %s", params()->console);
-- //Load program sections into memory
-- console->loadSections(functionalPort, loadAddrMask);
--
-- //load symbols
-- if (!console->loadGlobalSymbols(consoleSymtab))
-- panic("could not load console symbols\n");
--
-- if (!console->loadGlobalSymbols(debugSymbolTable))
-- panic("could not load console symbols\n");
--
--
--#ifndef NDEBUG
-- consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic");
--#endif
--
-- /**
-- * Copy the osflags (kernel arguments) into the consoles
-- * memory. (Presently Linux does not use the console service
-- * routine to get these command line arguments, but Tru64 and
-- * others do.)
-- */
-- if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
-- warn("writing addr starting from %#x", addr);
-- virtPort->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
-- strlen(params()->boot_osflags.c_str()));
-- }
--
-- /**
-- * Set the hardware reset parameter block system type and revision
-- * information to Tsunami.
-- */
-- if (consoleSymtab->findAddress("m5_rpb", addr)) {
-- uint64_t data;
-- data = htog(params()->system_type);
-- virtPort->write(addr + 0x50, data);
-- data = htog(params()->system_rev);
-- virtPort->write(addr + 0x58, data);
-- } else {
-- panic("could not find hwrpb\n");
-- }
-#endif
}
MipsSystem::~MipsSystem()
#include <cmath>
#include "arch/mips/isa_traits.hh"
++#include "arch/mips/registers.hh"
#include "arch/mips/utility.hh"
++#include "arch/mips/vtophys.hh"
#include "base/bitfield.hh"
#include "base/misc.hh"
-#include "config/full_system.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
-#include "sim/serialize.hh"
-
-#if FULL_SYSTEM
-#include "arch/mips/registers.hh"
-#include "arch/mips/vtophys.hh"
+ #include "mem/fs_translating_port_proxy.hh"
-#endif
+#include "sim/serialize.hh"
- #include "arch/mips/registers.hh"
- #include "arch/mips/vtophys.hh"
- #include "mem/vport.hh"
-
using namespace MipsISA;
using namespace std;
#include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
-#include "mem/vport.hh"
+#include "debug/VtoPhys.hh"
- #include "mem/vport.hh"
using namespace std;
using namespace MipsISA;
#include "arch/sparc/faults.hh"
#include "arch/sparc/utility.hh"
-#if FULL_SYSTEM
#include "arch/sparc/vtophys.hh"
- #include "mem/vport.hh"
+ #include "mem/fs_translating_port_proxy.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();
++ FSTranslatingPortProxy* vp = tc->getVirtProxy();
+ uint64_t arg = vp->read<uint64_t>(sp + 92 +
+ (number-NumArgumentRegs) * sizeof(uint64_t));
+ return arg;
+ }
} else {
- Addr sp = tc->readIntReg(StackPointerReg);
- FSTranslatingPortProxy* vp = tc->getVirtProxy();
- 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/thread_context.hh"
#include "debug/GDBAll.hh"
#include "mem/port.hh"
- #include "mem/translating_port.hh"
- #include "mem/vport.hh"
++#include "mem/fs_translating_port_proxy.hh"
+ #include "mem/se_translating_port_proxy.hh"
+#include "sim/full_system.hh"
#include "sim/system.hh"
using namespace std;
DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
-#if FULL_SYSTEM
- FSTranslatingPortProxy *port = context->getVirtProxy();
-#else
- SETranslatingPortProxy *port = context->getMemProxy();
-#endif
- port->readBlob(vaddr, (uint8_t*)data, size);
+ if (FullSystem) {
- VirtualPort *port = context->getVirtPort();
++ FSTranslatingPortProxy *port = context->getVirtProxy();
+ port->readBlob(vaddr, (uint8_t*)data, size);
+ } else {
- TranslatingPort *port = context->getMemPort();
++ SETranslatingPortProxy *port = context->getMemProxy();
+ port->readBlob(vaddr, (uint8_t*)data, size);
+ }
#if TRACING_ON
if (DTRACE(GDBRead)) {
} else
DPRINTFNR("\n");
}
-#if FULL_SYSTEM
- FSTranslatingPortProxy *port = context->getVirtProxy();
-#else
- SETranslatingPortProxy *port = context->getMemProxy();
-#endif
- port->writeBlob(vaddr, (uint8_t*)data, size);
-#if !FULL_SYSTEM
- delete port;
-#endif
+ if (FullSystem) {
- VirtualPort *port = context->getVirtPort();
++ FSTranslatingPortProxy *port = context->getVirtProxy();
+ port->writeBlob(vaddr, (uint8_t*)data, size);
+ } else {
- TranslatingPort *port = context->getMemPort();
++ SETranslatingPortProxy *port = context->getMemProxy();
+ port->writeBlob(vaddr, (uint8_t*)data, size);
+ delete port;
+ }
return true;
}
tracer = Param.InstTracer(default_tracer, "Instruction tracer")
- _cached_ports = []
+ icache_port = Port("Instruction Port")
+ dcache_port = Port("Data Port")
+ _cached_ports = ['icache_port', 'dcache_port']
+
- if buildEnv['TARGET_ISA'] in ['x86', 'arm'] and buildEnv['FULL_SYSTEM']:
+ if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
- _cached_ports = ["itb.walker.port", "dtb.walker.port"]
+ _cached_ports += ["itb.walker.port", "dtb.walker.port"]
_uncached_ports = []
- if buildEnv['TARGET_ISA'] == 'x86' and buildEnv['FULL_SYSTEM']:
+ if buildEnv['TARGET_ISA'] == 'x86':
_uncached_ports = ["interrupts.pio", "interrupts.int_port"]
def connectCachedPorts(self, bus):
TheISA::Kernel::Statistics *getKernelStats()
{ return actualTC->getKernelStats(); }
- TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
+ Process *getProcessPtr() { return actualTC->getProcessPtr(); }
+
+ PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); }
- VirtualPort *getVirtPort()
- { return actualTC->getVirtPort(); }
+ FSTranslatingPortProxy* getVirtProxy()
+ { return actualTC->getVirtProxy(); }
-#else
- SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
- FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
- Process *getProcessPtr() { return actualTC->getProcessPtr(); }
-#endif
++ SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
Status status() const { return actualTC->status(); }
#include "debug/RefCount.hh"
#include "debug/SkedCache.hh"
#include "debug/Quiesce.hh"
- #include "mem/translating_port.hh"
#include "params/InOrderCPU.hh"
+#include "sim/full_system.hh"
#include "sim/process.hh"
#include "sim/stat_control.hh"
-
-#if FULL_SYSTEM
-#include "cpu/quiesce_event.hh"
#include "sim/system.hh"
-#endif
#if THE_ISA == ALPHA_ISA
#include "arch/alpha/osfpal.hh"
for (ThreadID tid = 0; tid < numThreads; ++tid)
thread[tid]->inSyscall = true;
-#if FULL_SYSTEM
- for (ThreadID tid = 0; tid < numThreads; tid++) {
- ThreadContext *src_tc = threadContexts[tid];
- TheISA::initCPU(src_tc, src_tc->contextId());
- // Initialise the ThreadContext's memory proxies
- thread[tid]->initMemProxies(thread[tid]->getTC());
+ if (FullSystem) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ ThreadContext *src_tc = threadContexts[tid];
+ TheISA::initCPU(src_tc, src_tc->contextId());
++ // Initialise the ThreadContext's memory proxies
++ thread[tid]->initMemProxies(thread[tid]->getTC());
+ }
}
-#endif
// Clear inSyscall.
for (ThreadID tid = 0; tid < numThreads; ++tid)
return interrupts->getInterrupt(threadContexts[0]);
}
--
void
InOrderCPU::processInterrupts(Fault interrupt)
{
trap(interrupt, threadContexts[0]->contextId(), dummyBufferInst);
}
- void
- InOrderCPU::updateMemPorts()
- {
- // Update all ThreadContext's memory ports (Functional/Virtual
- // Ports)
- ThreadID size = thread.size();
- for (ThreadID i = 0; i < size; ++i)
- thread[i]->connectMemPorts(thread[i]->getTC());
- }
-#endif
--
void
InOrderCPU::trapContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
{
using namespace TheISA;
- VirtualPort *
- InOrderThreadContext::getVirtPort()
-#if FULL_SYSTEM
-
+ FSTranslatingPortProxy*
+ InOrderThreadContext::getVirtProxy()
{
- return thread->getVirtPort();
+ return thread->getVirtProxy();
}
-
void
InOrderThreadContext::dumpFuncProfile()
{
{
return this->thread->quiesceEvent;
}
-#else
+
+ SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
+
/** Returns a pointer to this thread's process. */
Process *getProcessPtr() { return thread->getProcessPtr(); }
-#endif
- TranslatingPort *getMemPort() { return thread->getMemPort(); }
-
- VirtualPort *getVirtPort();
- FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
-
/** Returns this thread's status. */
Status status() const { return thread->status(); }
if (params->checker) {
BaseCPU *temp_checker = params->checker;
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
-#if FULL_SYSTEM
+ checker->setIcachePort(&icachePort);
checker->setSystem(params->system);
-#endif
} else {
checker = NULL;
}
for (ThreadID tid = 0; tid < numThreads; ++tid)
thread[tid]->inSyscall = true;
-#if FULL_SYSTEM
- for (ThreadID tid = 0; tid < numThreads; tid++) {
- ThreadContext *src_tc = threadContexts[tid];
- TheISA::initCPU(src_tc, src_tc->contextId());
- // Initialise the ThreadContext's memory proxies
- thread[tid]->initMemProxies(thread[tid]->getTC());
+ // this CPU could still be unconnected if we are restoring from a
+ // checkpoint and this CPU is to be switched in, thus we can only
+ // do this here if the instruction port is actually connected, if
+ // not we have to do it as part of takeOverFrom
+ if (icachePort.isConnected())
+ fetch.setIcache();
+
+ if (FullSystem) {
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ ThreadContext *src_tc = threadContexts[tid];
+ TheISA::initCPU(src_tc, src_tc->contextId());
++ // Initialise the ThreadContext's memory proxies
++ thread[tid]->initMemProxies(thread[tid]->getTC());
+ }
}
-#endif
// Clear inSyscall.
for (int tid = 0; tid < numThreads; ++tid)
this->trap(interrupt, 0, NULL);
}
- template <class Impl>
- void
- FullO3CPU<Impl>::updateMemPorts()
- {
- // Update all ThreadContext's memory ports (Functional/Virtual
- // Ports)
- ThreadID size = thread.size();
- for (ThreadID i = 0; i < size; ++i)
- thread[i]->connectMemPorts(thread[i]->getTC());
- }
-#endif
--
template <class Impl>
void
FullO3CPU<Impl>::trap(Fault fault, ThreadID tid, StaticInstPtr inst)
virtual TheISA::Kernel::Statistics *getKernelStats()
{ return thread->kernelStats; }
- virtual void connectMemPorts(ThreadContext *tc)
- { thread->connectMemPorts(tc); }
-
+ /** Returns a pointer to this thread's process. */
+ virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
+
- virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
+ virtual PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
+
+ virtual FSTranslatingPortProxy* getVirtProxy();
- virtual VirtualPort *getVirtPort();
+ virtual void initMemProxies(ThreadContext *tc)
+ { thread->initMemProxies(tc); }
-#else
+
- virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
+ virtual SETranslatingPortProxy* getMemProxy()
+ { return thread->getMemProxy(); }
- /** Returns a pointer to this thread's process. */
- virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
-#endif
/** Returns this thread's status. */
virtual Status status() const { return thread->status(); }
#include "cpu/quiesce_event.hh"
#include "debug/O3CPU.hh"
-#if FULL_SYSTEM
template <class Impl>
- VirtualPort *
- O3ThreadContext<Impl>::getVirtPort()
+ FSTranslatingPortProxy*
+ O3ThreadContext<Impl>::getVirtProxy()
{
- return thread->getVirtPort();
+ return thread->getVirtProxy();
}
template <class Impl>
TheISA::Kernel::Statistics *getKernelStats()
{ return thread->getKernelStats(); }
- TranslatingPort *getMemPort() { return thread->getMemPort(); }
+ Process *getProcessPtr() { return thread->getProcessPtr(); }
+
+ PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
- VirtualPort *getVirtPort()
- { return thread->getVirtPort(); }
+ FSTranslatingPortProxy* getVirtProxy()
+ { return thread->getVirtProxy(); }
-#else
- SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
- FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
- Process *getProcessPtr() { return thread->getProcessPtr(); }
-#endif
++ SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
Status status() const { return thread->status(); }
frontEnd->renameTable.copyFrom(thread.renameTable);
backEnd->renameTable.copyFrom(thread.renameTable);
- if (FullSystem) {
- Port *mem_port;
- FunctionalPort *phys_port;
- VirtualPort *virt_port;
- phys_port = new FunctionalPort(csprintf("%s-%d-funcport",
- name(), 0));
- mem_port = system->physmem->getPort("functional");
- mem_port->setPeer(phys_port);
- phys_port->setPeer(mem_port);
-
- virt_port = new VirtualPort(csprintf("%s-%d-vport",
- name(), 0));
- mem_port = system->physmem->getPort("functional");
- mem_port->setPeer(virt_port);
- virt_port->setPeer(mem_port);
-
- thread.setPhysPort(phys_port);
- thread.setVirtPort(virt_port);
- }
-#if FULL_SYSTEM
+ thread.connectMemPorts(tc);
-#endif
DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
}
AtomicSimpleCPU::init()
{
BaseCPU::init();
-#if FULL_SYSTEM
- ThreadID size = threadContexts.size();
- for (ThreadID i = 0; i < size; ++i) {
- ThreadContext *tc = threadContexts[i];
-
- // initialize CPU, including PC
- TheISA::initCPU(tc, tc->contextId());
+ if (FullSystem) {
+ ThreadID size = threadContexts.size();
+ for (ThreadID i = 0; i < size; ++i) {
+ ThreadContext *tc = threadContexts[i];
+ // initialize CPU, including PC
+ TheISA::initCPU(tc, tc->contextId());
+ }
}
-#endif
+
+ // Initialise the ThreadContext's memory proxies
+ tcBase()->initMemProxies(tcBase());
++
if (hasPhysMemPort) {
- bool snoop = false;
- AddrRangeList pmAddrList;
- physmemPort.getPeerAddressRanges(pmAddrList, snoop);
+ AddrRangeList pmAddrList = physmemPort.getPeer()->getAddrRanges();
physMemAddr = *pmAddrList.begin();
}
// Atomic doesn't do MT right now, so contextId == threadId
TimingSimpleCPU::init()
{
BaseCPU::init();
-#if FULL_SYSTEM
- for (int i = 0; i < threadContexts.size(); ++i) {
- ThreadContext *tc = threadContexts[i];
-
- // initialize CPU, including PC
- TheISA::initCPU(tc, _cpuId);
+ if (FullSystem) {
+ for (int i = 0; i < threadContexts.size(); ++i) {
+ ThreadContext *tc = threadContexts[i];
+ // initialize CPU, including PC
+ TheISA::initCPU(tc, _cpuId);
+ }
}
- }
-
- Tick
- TimingSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt)
- {
- panic("TimingSimpleCPU doesn't expect recvAtomic callback!");
- return curTick();
- }
- void
- TimingSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt)
- {
- //No internal storage to update, jusst return
- return;
+ // Initialise the ThreadContext's memory proxies
+ tcBase()->initMemProxies(tcBase());
-#endif
}
void
#include "base/cprintf.hh"
#include "base/output.hh"
#include "base/trace.hh"
+#include "config/the_isa.hh"
+#include "cpu/base.hh"
#include "cpu/profile.hh"
#include "cpu/quiesce_event.hh"
- #include "mem/translating_port.hh"
- #include "mem/vport.hh"
+#include "cpu/simple_thread.hh"
+#include "cpu/thread_context.hh"
+#include "params/BaseCPU.hh"
+ #include "mem/fs_translating_port_proxy.hh"
++#include "mem/se_translating_port_proxy.hh"
+#include "sim/full_system.hh"
+#include "sim/process.hh"
#include "sim/serialize.hh"
#include "sim/sim_exit.hh"
-#else
-#include "mem/se_translating_port_proxy.hh"
+ #include "sim/process.hh"
#include "sim/system.hh"
-#endif
using namespace std;
class FunctionProfile;
class ProfileNode;
--class FunctionalPort;
class PhysicalPort;
+class TranslatingPort;
namespace TheISA {
namespace Kernel {
System *getSystemPtr() { return system; }
- FunctionalPort *getPhysPort() { return physPort; }
-#if FULL_SYSTEM
+ PortProxy* getPhysProxy() { return physProxy; }
/** Return a virtual port. This port cannot be cached locally in an object.
* After a CPU switch it may point to the wrong memory object which could
* mean stale data.
*/
- VirtualPort *getVirtPort() { return virtPort; }
+ FSTranslatingPortProxy* getVirtProxy() { return virtProxy; }
-#endif
Status status() const { return _status; }
virtual System *getSystemPtr() = 0;
-#if FULL_SYSTEM
virtual TheISA::Kernel::Statistics *getKernelStats() = 0;
- virtual void connectMemPorts(ThreadContext *tc) = 0;
+ virtual PortProxy* getPhysProxy() = 0;
- virtual Process *getProcessPtr() = 0;
+ virtual FSTranslatingPortProxy* getVirtProxy() = 0;
- virtual TranslatingPort *getMemPort() = 0;
+ /**
+ * Initialise the physical and virtual port proxies and tie them to
+ * the data port of the CPU.
+ *
+ * tc ThreadContext for the virtual-to-physical translation
+ */
+ virtual void initMemProxies(ThreadContext *tc) = 0;
-#else
+
- virtual VirtualPort *getVirtPort() = 0;
+ virtual SETranslatingPortProxy *getMemProxy() = 0;
- virtual FunctionalPort *getPhysPort() = 0;
+ virtual Process *getProcessPtr() = 0;
-#endif
virtual Status status() const = 0;
TheISA::Kernel::Statistics *getKernelStats()
{ return actualTC->getKernelStats(); }
- void connectMemPorts(ThreadContext *tc) { actualTC->connectMemPorts(tc); }
+ PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); }
- Process *getProcessPtr() { return actualTC->getProcessPtr(); }
+ FSTranslatingPortProxy* getVirtProxy() { return actualTC->getVirtProxy(); }
- TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
+ void initMemProxies(ThreadContext *tc) { actualTC->initMemProxies(tc); }
-#else
+
- VirtualPort *getVirtPort() { return actualTC->getVirtPort(); }
+ SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
- FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
+ Process *getProcessPtr() { return actualTC->getProcessPtr(); }
-#endif
Status status() const { return actualTC->status(); }
#include "base/output.hh"
#include "cpu/base.hh"
#include "cpu/profile.hh"
+#include "cpu/quiesce_event.hh"
#include "cpu/thread_state.hh"
- #include "mem/translating_port.hh"
- #include "mem/vport.hh"
++#include "mem/fs_translating_port_proxy.hh"
+#include "mem/port.hh"
+ #include "mem/port_proxy.hh"
+ #include "mem/se_translating_port_proxy.hh"
+#include "sim/full_system.hh"
#include "sim/serialize.hh"
+ #include "sim/system.hh"
-#if FULL_SYSTEM
-#include "arch/kernel_stats.hh"
-#include "cpu/quiesce_event.hh"
-#include "mem/fs_translating_port_proxy.hh"
-#endif
-
-#if FULL_SYSTEM
-ThreadState::ThreadState(BaseCPU *cpu, ThreadID _tid)
-#else
ThreadState::ThreadState(BaseCPU *cpu, ThreadID _tid, Process *_process)
-#endif
: numInst(0), numLoad(0), _status(ThreadContext::Halted),
baseCpu(cpu), _threadId(_tid), lastActivate(0), lastSuspend(0),
-#if FULL_SYSTEM
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
- kernelStats(NULL), process(_process), port(NULL), virtPort(NULL),
- physPort(NULL), funcExeInst(0), storeCondFailures(0)
- kernelStats(NULL), physProxy(NULL), virtProxy(NULL),
-#else
- proxy(NULL), process(_process),
-#endif
- funcExeInst(0), storeCondFailures(0)
++ kernelStats(NULL), process(_process), physProxy(NULL), virtProxy(NULL),
++ proxy(NULL), funcExeInst(0), storeCondFailures(0)
{
}
ThreadState::~ThreadState()
{
- if (port) {
- delete port->getPeer();
- delete port;
- }
-#if FULL_SYSTEM
- if (physProxy != NULL) {
++ if (physProxy != NULL)
+ delete physProxy;
- }
- if (virtProxy != NULL) {
++ if (virtProxy != NULL)
+ delete virtProxy;
- }
-#else
- if (proxy != NULL) {
++ if (proxy != NULL)
+ delete proxy;
- }
-#endif
}
void
// thread_num and cpu_id are deterministic from the config
UNSERIALIZE_SCALAR(funcExeInst);
-#if FULL_SYSTEM
- Tick quiesceEndTick;
- UNSERIALIZE_SCALAR(quiesceEndTick);
- if (quiesceEndTick)
- baseCpu->schedule(quiesceEvent, quiesceEndTick);
- if (kernelStats)
- kernelStats->unserialize(cp, section);
-#endif
+ if (FullSystem) {
+ Tick quiesceEndTick;
+ UNSERIALIZE_SCALAR(quiesceEndTick);
+ if (quiesceEndTick)
+ baseCpu->schedule(quiesceEvent, quiesceEndTick);
+ if (kernelStats)
+ kernelStats->unserialize(cp, section);
+ }
}
-#if FULL_SYSTEM
void
- ThreadState::connectPhysPort()
- {
- // @todo: For now this disregards any older port that may have
- // already existed. Fix this memory leak once the bus port IDs
- // for functional ports is resolved.
- if (physPort)
- physPort->removeConn();
- else
- physPort = new FunctionalPort(csprintf("%s-%d-funcport",
- baseCpu->name(), _threadId));
- connectToMemFunc(physPort);
- }
-
- void
- ThreadState::connectVirtPort(ThreadContext *tc)
- {
- // @todo: For now this disregards any older port that may have
- // already existed. Fix this memory leak once the bus port IDs
- // for functional ports is resolved.
- if (virtPort)
- virtPort->removeConn();
- else
- virtPort = new VirtualPort(csprintf("%s-%d-vport",
- baseCpu->name(), _threadId), tc);
- connectToMemFunc(virtPort);
- }
-
- void
- ThreadState::connectMemPorts(ThreadContext *tc)
+ ThreadState::initMemProxies(ThreadContext *tc)
{
- connectPhysPort();
- connectVirtPort(tc);
+ // Note that this only refers to the port on the CPU side and can
+ // safely be done at init() time even if the CPU is not connected
+ // (i.e. due to restoring from a checkpoint and later switching
+ // in.
+ if (physProxy == NULL)
+ physProxy = new PortProxy(*baseCpu->getPort("dcache_port"));
+ if (virtProxy == NULL)
+ virtProxy = new FSTranslatingPortProxy(tc);
}
void
profile->sample(profileNode, profilePC);
}
- TranslatingPort *
- ThreadState::getMemPort()
-#else
+ SETranslatingPortProxy *
+ ThreadState::getMemProxy()
{
- if (port != NULL)
- return port;
-
- /* Use this port to for syscall emulation writes to memory. */
- port = new TranslatingPort(csprintf("%s-%d-funcport", baseCpu->name(),
- _threadId), process, TranslatingPort::NextPage);
-
- connectToMemFunc(port);
-
- return port;
- }
-
- void
- ThreadState::connectToMemFunc(Port *port)
- {
- Port *dcache_port, *func_mem_port;
-
- dcache_port = baseCpu->getPort("dcache_port");
- assert(dcache_port != NULL);
-
- MemObject *mem_object = dcache_port->getPeer()->getOwner();
- assert(mem_object != NULL);
+ if (proxy != NULL)
+ return proxy;
- func_mem_port = mem_object->getPort("functional");
- assert(func_mem_port != NULL);
+ /* Use this port proxy to for syscall emulation writes to memory. */
+ proxy = new SETranslatingPortProxy(*process->system->getSystemPort(),
+ process,
+ SETranslatingPortProxy::NextPage);
- func_mem_port->setPeer(port);
- port->setPeer(func_mem_port);
+ return proxy;
}
-#endif
class Statistics;
};
};
-#endif
class Checkpoint;
- class Port;
- class TranslatingPort;
+ class PortProxy;
+ class SETranslatingPort;
+ class FSTranslatingPort;
/**
* Struct for holding general thread state that is needed across CPU
Tick readLastSuspend() { return lastSuspend; }
- void connectPhysPort();
-
- void connectVirtPort(ThreadContext *tc);
-
- void connectMemPorts(ThreadContext *tc);
-#if FULL_SYSTEM
+ /**
+ * Initialise the physical and virtual port proxies and tie them to
+ * the data port of the CPU.
+ *
+ * tc ThreadContext for the virtual-to-physical translation
+ */
+ void initMemProxies(ThreadContext *tc);
void dumpFuncProfile();
TheISA::Kernel::Statistics *getKernelStats() { return kernelStats; }
- Process *getProcessPtr() { return process; }
-
- TranslatingPort *getMemPort();
+ PortProxy* getPhysProxy() { return physProxy; }
- void setMemPort(TranslatingPort *_port) { port = _port; }
+ FSTranslatingPortProxy* getVirtProxy() { return virtProxy; }
-#else
+
- VirtualPort *getVirtPort() { return virtPort; }
-
- FunctionalPort *getPhysPort() { return physPort; }
+ Process *getProcessPtr() { return process; }
- void setPhysPort(FunctionalPort *port) { physPort = port; }
+ SETranslatingPortProxy* getMemProxy();
-#endif
/** Reads the number of instructions functionally executed and
* committed.
EndQuiesceEvent *quiesceEvent;
TheISA::Kernel::Statistics *kernelStats;
+
protected:
- TranslatingPort *port;
-
- /** A functional port, outgoing only, for functional accesse to virtual
- * addresses. */
- VirtualPort *virtPort;
-
- /** A functional port outgoing only for functional accesses to physical
+ Process *process;
+
+ /** A port proxy outgoing only for functional accesses to physical
* addresses.*/
- FunctionalPort *physPort;
+ PortProxy *physProxy;
+
+ /** A translating port proxy, outgoing only, for functional
+ * accesse to virtual addresses. */
+ FSTranslatingPortProxy* virtProxy;
-#else
+ SETranslatingPortProxy* proxy;
- Process *process;
-#endif
-
public:
/*
* number of executed instructions, for matching with syscall trace
class PciDevice(DmaDevice):
type = 'PciDevice'
abstract = True
- config = Port(Self.pio.peerObj.port, "PCI configuration space port")
+ platform = Param.Platform(Parent.any, "Platform this device is part of.")
+ config = Port("PCI configuration space port")
pci_bus = Param.Int("PCI bus")
pci_dev = Param.Int("PCI device number")
pci_func = Param.Int("PCI function code")
Source('packet.cc')
Source('port.cc')
Source('tport.cc')
- Source('vport.cc')
-Source('mport.cc')
++Source('fs_translating_port_proxy.cc')
++Source('se_translating_port_proxy.cc')
if env['TARGET_ISA'] != 'no':
SimObject('PhysicalMemory.py')
Source('dram.cc')
- Source('physical.cc')
-
-if env['FULL_SYSTEM']:
- Source('fs_translating_port_proxy.cc')
-elif env['TARGET_ISA'] != 'no':
Source('page_table.cc')
- Source('se_translating_port_proxy.cc')
+ Source('physical.cc')
- Source('translating_port.cc')
DebugFlag('Bus')
DebugFlag('BusAddrRanges')
--- /dev/null
- Addr paddr;
+ /*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Ron Dreslinski
+ * Steve Reinhardt
+ * Andreas Hansson
+ */
+
+ #include <string>
+
++#include "arch/isa_traits.hh"
+ #include "base/chunk_generator.hh"
+ #include "config/the_isa.hh"
+ #include "mem/page_table.hh"
+ #include "mem/se_translating_port_proxy.hh"
+ #include "sim/process.hh"
+
+ using namespace TheISA;
+
+ SETranslatingPortProxy::SETranslatingPortProxy(Port& port, Process *p,
+ AllocType alloc)
+ : PortProxy(port), pTable(p->pTable), process(p),
+ allocating(alloc)
+ { }
+
+ SETranslatingPortProxy::~SETranslatingPortProxy()
+ { }
+
+ bool
+ SETranslatingPortProxy::tryReadBlob(Addr addr, uint8_t *p, int size)
+ {
-
- Addr paddr;
+ int prevSize = 0;
+
+ for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
++ Addr paddr;
+
+ if (!pTable->translate(gen.addr(),paddr))
+ return false;
+
+ PortProxy::readBlob(paddr, p + prevSize, gen.size());
+ prevSize += gen.size();
+ }
+
+ return true;
+ }
+
+ void
+ SETranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size)
+ {
+ if (!tryReadBlob(addr, p, size))
+ fatal("readBlob(0x%x, ...) failed", addr);
+ }
+
+
+ bool
+ SETranslatingPortProxy::tryWriteBlob(Addr addr, uint8_t *p, int size)
+ {
- Addr paddr;
-
+ int prevSize = 0;
+
+ for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
++ Addr paddr;
+
+ if (!pTable->translate(gen.addr(), paddr)) {
+ if (allocating == Always) {
+ process->allocateMem(roundDown(gen.addr(), VMPageSize),
+ VMPageSize);
+ } else if (allocating == NextPage) {
+ // check if we've accessed the next page on the stack
+ if (!process->fixupStackFault(gen.addr()))
+ panic("Page table fault when accessing virtual address %#x "
+ "during functional write\n", gen.addr());
+ } else {
+ return false;
+ }
+ pTable->translate(gen.addr(), paddr);
+ }
+
+ PortProxy::writeBlob(paddr, p + prevSize, gen.size());
+ prevSize += gen.size();
+ }
+
+ return true;
+ }
+
+
+ void
+ SETranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size)
+ {
+ if (!tryWriteBlob(addr, p, size))
+ fatal("writeBlob(0x%x, ...) failed", addr);
+ }
+
+ bool
+ SETranslatingPortProxy::tryMemsetBlob(Addr addr, uint8_t val, int size)
+ {
- Addr paddr,vaddr;
+ for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
++ Addr paddr;
+
+ if (!pTable->translate(gen.addr(), paddr)) {
+ if (allocating == Always) {
+ process->allocateMem(roundDown(gen.addr(), VMPageSize),
+ VMPageSize);
+ pTable->translate(gen.addr(), paddr);
+ } else {
+ return false;
+ }
+ }
+
+ PortProxy::memsetBlob(paddr, val, gen.size());
+ }
+
+ return true;
+ }
+
+ void
+ SETranslatingPortProxy::memsetBlob(Addr addr, uint8_t val, int size)
+ {
+ if (!tryMemsetBlob(addr, val, size))
+ fatal("memsetBlob(0x%x, ...) failed", addr);
+ }
+
+
+ bool
+ SETranslatingPortProxy::tryWriteString(Addr addr, const char *str)
+ {
- vaddr = addr;
+ uint8_t c;
+
- if (!pTable->translate(vaddr++,paddr))
++ Addr vaddr = addr;
+
+ do {
+ c = *str++;
- Addr paddr,vaddr;
++ Addr paddr;
++
++ if (!pTable->translate(vaddr++, paddr))
+ return false;
+
+ PortProxy::writeBlob(paddr, &c, 1);
+ } while (c);
+
+ return true;
+ }
+
+ void
+ SETranslatingPortProxy::writeString(Addr addr, const char *str)
+ {
+ if (!tryWriteString(addr, str))
+ fatal("writeString(0x%x, ...) failed", addr);
+ }
+
+ bool
+ SETranslatingPortProxy::tryReadString(std::string &str, Addr addr)
+ {
- vaddr = addr;
+ uint8_t c;
+
- if (!pTable->translate(vaddr++,paddr))
++ Addr vaddr = addr;
+
+ do {
++ Addr paddr;
++
++ if (!pTable->translate(vaddr++, paddr))
+ return false;
+
+ PortProxy::readBlob(paddr, &c, 1);
+ str += c;
+ } while (c);
+
+ return true;
+ }
+
+ void
+ SETranslatingPortProxy::readString(std::string &str, Addr addr)
+ {
+ if (!tryReadString(str, addr))
+ fatal("readString(0x%x, ...) failed", addr);
+ }
+
// add NULL terminator
data_ptr = 0;
- memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(AddrType));
+ memProxy->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(AddrType));
}
-
-#endif // !FULL_SYSTEM
-
#endif
#include "cpu/thread_context.hh"
#include "debug/SyscallVerbose.hh"
#include "mem/page_table.hh"
- #include "mem/translating_port.hh"
+ #include "mem/se_translating_port_proxy.hh"
#include "sim/byteswap.hh"
#include "sim/process.hh"
+#include "sim/syscallreturn.hh"
#include "sim/system.hh"
///
#include "cpu/thread_context.hh"
#include "debug/Loader.hh"
#include "debug/WorkItems.hh"
+#include "kern/kernel_stats.hh"
++#include "mem/fs_translating_port_proxy.hh"
#include "mem/mem_object.hh"
#include "mem/physical.hh"
- #include "mem/vport.hh"
+#include "params/System.hh"
#include "sim/byteswap.hh"
#include "sim/debug.hh"
+#include "sim/full_system.hh"
#include "sim/system.hh"
-#if FULL_SYSTEM
-#include "arch/vtophys.hh"
-#include "kern/kernel_stats.hh"
-#include "mem/fs_translating_port_proxy.hh"
-#else
-#include "params/System.hh"
-#endif
-
using namespace std;
using namespace TheISA;
int System::numSystemsRunning = 0;
System::System(Params *p)
- : SimObject(p), physmem(p->physmem), _numContexts(0), pagePtr(0),
+ : MemObject(p), _systemPort("system_port", this),
+ physmem(p->physmem),
+ _numContexts(0),
-#if FULL_SYSTEM
init_param(p->init_param),
loadAddrMask(p->load_addr_mask),
-#else
- pagePtr(0),
nextPID(0),
-#endif
memoryMode(p->mem_mode),
workItemsBegin(0),
workItemsEnd(0),
p->memories[x]->size()));
}
-#if FULL_SYSTEM
- kernelSymtab = new SymbolTable;
- if (!debugSymbolTable)
- debugSymbolTable = new SymbolTable;
+ if (FullSystem) {
+ kernelSymtab = new SymbolTable;
+ if (!debugSymbolTable)
+ debugSymbolTable = new SymbolTable;
-
- /**
- * Get a port proxy to memory
- */
- physProxy = new PortProxy(*getSystemPort());
- virtProxy = new FSTranslatingPortProxy(*getSystemPort());
-#endif
+ /**
- * Get a functional port to memory
- */
- Port *mem_port;
- functionalPort = new FunctionalPort(name() + "-fport");
- mem_port = physmem->getPort("functional");
- functionalPort->setPeer(mem_port);
- mem_port->setPeer(functionalPort);
-
- virtPort = new VirtualPort(name() + "-fport");
- mem_port = physmem->getPort("functional");
- virtPort->setPeer(mem_port);
- mem_port->setPeer(virtPort);
-
-
- /**
- * Load the kernel code into memory
++ * Get a port proxy to memory
+ */
- if (params()->kernel == "") {
- inform("No kernel set for full system simulation. "
- "Assuming you know what you're doing...\n");
- } else {
- // Load kernel code
- kernel = createObjectFile(params()->kernel);
- inform("kernel located at: %s", params()->kernel);
-
- if (kernel == NULL)
- fatal("Could not load kernel file %s", params()->kernel);
-
- // Load program sections into memory
- kernel->loadSections(functionalPort, loadAddrMask);
-
- // setup entry points
- kernelStart = kernel->textBase();
- kernelEnd = kernel->bssBase() + kernel->bssSize();
- kernelEntry = kernel->entryPoint();
-
- // load symbols
- if (!kernel->loadGlobalSymbols(kernelSymtab))
- fatal("could not load kernel symbols\n");
-
- if (!kernel->loadLocalSymbols(kernelSymtab))
- fatal("could not load kernel local symbols\n");
-
- if (!kernel->loadGlobalSymbols(debugSymbolTable))
- fatal("could not load kernel symbols\n");
-
- if (!kernel->loadLocalSymbols(debugSymbolTable))
- fatal("could not load kernel local symbols\n");
-
- DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
- DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd);
- DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
- DPRINTF(Loader, "Kernel loaded...\n");
- }
++ physProxy = new PortProxy(*getSystemPort());
++ virtProxy = new FSTranslatingPortProxy(*getSystemPort());
+ }
-
- // increment the number of running systms
- numSystemsRunning++;
-
- activeCpus.clear();
}
System::~System()
void
System::initState()
{
- // Moved from the constructor to here since it relies on the
- // address map being resolved in the interconnect
-#if FULL_SYSTEM
- /**
- * Load the kernel code into memory
- */
- if (params()->kernel == "") {
- inform("No kernel set for full system simulation. Assuming you know what"
- " you're doing...\n");
- } else {
- // Load kernel code
- kernel = createObjectFile(params()->kernel);
- inform("kernel located at: %s", params()->kernel);
-
- if (kernel == NULL)
- fatal("Could not load kernel file %s", params()->kernel);
-
- // Load program sections into memory
- kernel->loadSections(physProxy, loadAddrMask);
-
- // setup entry points
- kernelStart = kernel->textBase();
- kernelEnd = kernel->bssBase() + kernel->bssSize();
- kernelEntry = kernel->entryPoint();
-
- // load symbols
- if (!kernel->loadGlobalSymbols(kernelSymtab))
- fatal("could not load kernel symbols\n");
-
- if (!kernel->loadLocalSymbols(kernelSymtab))
- fatal("could not load kernel local symbols\n");
-
- if (!kernel->loadGlobalSymbols(debugSymbolTable))
- fatal("could not load kernel symbols\n");
-
- if (!kernel->loadLocalSymbols(debugSymbolTable))
- fatal("could not load kernel local symbols\n");
-
- DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
- DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd);
- DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
- DPRINTF(Loader, "Kernel loaded...\n");
++ if (FullSystem) {
++ int i;
++ for (i = 0; i < threadContexts.size(); i++)
++ TheISA::startupCPU(threadContexts[i], i);
++ // Moved from the constructor to here since it relies on the
++ // address map being resolved in the interconnect
++ /**
++ * Load the kernel code into memory
++ */
++ if (params()->kernel == "") {
++ inform("No kernel set for full system simulation. "
++ "Assuming you know what you're doing...\n");
++ } else {
++ // Load kernel code
++ kernel = createObjectFile(params()->kernel);
++ inform("kernel located at: %s", params()->kernel);
++
++ if (kernel == NULL)
++ fatal("Could not load kernel file %s", params()->kernel);
++
++ // Load program sections into memory
++ kernel->loadSections(physProxy, loadAddrMask);
++
++ // setup entry points
++ kernelStart = kernel->textBase();
++ kernelEnd = kernel->bssBase() + kernel->bssSize();
++ kernelEntry = kernel->entryPoint();
++
++ // load symbols
++ if (!kernel->loadGlobalSymbols(kernelSymtab))
++ fatal("could not load kernel symbols\n");
++
++ if (!kernel->loadLocalSymbols(kernelSymtab))
++ fatal("could not load kernel local symbols\n");
++
++ if (!kernel->loadGlobalSymbols(debugSymbolTable))
++ fatal("could not load kernel symbols\n");
++
++ if (!kernel->loadLocalSymbols(debugSymbolTable))
++ fatal("could not load kernel local symbols\n");
++
++ DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
++ DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd);
++ DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
++ DPRINTF(Loader, "Kernel loaded...\n");
++ }
+ }
-#endif // FULL_SYSTEM
+
+ // increment the number of running systms
+ numSystemsRunning++;
+
+ activeCpus.clear();
+
-#if FULL_SYSTEM
- int i;
- for (i = 0; i < threadContexts.size(); i++)
- TheISA::startupCPU(threadContexts[i], i);
-#endif
+ if (FullSystem) {
+ int i;
+ for (i = 0; i < threadContexts.size(); i++)
+ TheISA::startupCPU(threadContexts[i], i);
+ }
}
void
#include "base/loader/symtab.hh"
#include "base/misc.hh"
#include "base/statistics.hh"
-#include "config/full_system.hh"
#include "cpu/pc_event.hh"
#include "enums/MemoryMode.hh"
+#include "kern/system_events.hh"
+ #include "mem/mem_object.hh"
#include "mem/port.hh"
#include "params/System.hh"
- #include "sim/sim_object.hh"
-#if FULL_SYSTEM
-#include "kern/system_events.hh"
-#endif
-
class BaseCPU;
-class ThreadContext;
+class BaseRemoteGDB;
- class FunctionalPort;
++class FSTranslatingPortProxy;
+class GDBListener;
class ObjectFile;
class PhysicalMemory;
-
-#if FULL_SYSTEM
class Platform;
-class FSTranslatingPortProxy;
-#endif
-class GDBListener;
-class BaseRemoteGDB;
+ class PortProxy;
+class ThreadContext;
+class VirtualPort;
- class System : public SimObject
+ class System : public MemObject
{
+ private:
+
+ /**
+ * Private class for the system port which is only used as a
+ * master for debug access and for non-structural entities that do
+ * not have a port of their own.
+ */
+ class SystemPort : public Port
+ {
+ public:
+
+ /**
+ * Create a system port with a name and an owner.
+ */
+ SystemPort(const std::string &_name, MemObject *_owner)
+ : Port(_name, _owner)
+ { }
+ bool recvTiming(PacketPtr pkt)
+ { panic("SystemPort does not receive timing!\n"); return false; }
+ Tick recvAtomic(PacketPtr pkt)
+ { panic("SystemPort does not receive atomic!\n"); return 0; }
+ void recvFunctional(PacketPtr pkt)
+ { panic("SystemPort does not receive functional!\n"); }
+
+ /**
+ * The system port is a master port connected to a single
+ * slave and thus do not care about what ranges the slave
+ * covers (as there is nothing to choose from).
+ */
+ void recvRangeChange() { }
+
+ };
+
+ SystemPort _systemPort;
+
public:
+ /**
+ * After all objects have been created and all ports are
+ * connected, check that the system port is connected.
+ */
+ virtual void init();
+
+ /**
+ * Get a pointer to the system port that can be used by
+ * non-structural simulation objects like processes or threads, or
+ * external entities like loaders and debuggers, etc, to access
+ * the memory system.
+ *
+ * @return a pointer to the system port we own
+ */
+ Port* getSystemPort() { return &_systemPort; }
+
+ /**
+ * Additional function to return the Port of a memory object.
+ */
+ Port *getPort(const std::string &if_name, int idx = -1);
+
static const char *MemoryModeStrings[3];
Enums::MemoryMode
# Tie the cpu cache ports to the ruby cpu ports and
# physmem, respectively
#
-cpu.icache_port = system.ruby._cpu_ruby_ports[0].port
-cpu.dcache_port = system.ruby._cpu_ruby_ports[0].port
+cpu.connectAllPorts(system.ruby._cpu_ruby_ports[0])
+ # Connect the system port for loading of binaries etc
+ system.system_port = system.ruby._sys_port_proxy.port
+
# -----------------------
# run simulation
# -----------------------