X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Fthread_state.cc;h=7953b53c85e861d9fbb67ef893f01bd6463d61e5;hb=f34a8f0d6163fe82849d494bf78c0f5ec175861c;hp=93dd1e2eb0252830abd14d1a443d9d86c12c2068;hpb=d3e888ff90c91ce7f3b5b7ab0e3a314a28f3cb88;p=gem5.git diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc index 93dd1e2eb..7953b53c8 100644 --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@ -28,46 +28,37 @@ * Authors: Kevin Lim */ +#include "arch/kernel_stats.hh" #include "base/output.hh" #include "cpu/base.hh" #include "cpu/profile.hh" +#include "cpu/quiesce_event.hh" #include "cpu/thread_state.hh" +#include "mem/fs_translating_port_proxy.hh" #include "mem/port.hh" -#include "mem/translating_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/vport.hh" -#endif - -#if FULL_SYSTEM -ThreadState::ThreadState(BaseCPU *cpu, int _cpuId, int _tid) - : baseCpu(cpu), cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), +ThreadState::ThreadState(BaseCPU *cpu, ThreadID _tid, Process *_process) + : numInst(0), numOp(0), numLoad(0), _status(ThreadContext::Halted), + baseCpu(cpu), _threadId(_tid), lastActivate(0), lastSuspend(0), profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL), - physPort(NULL), virtPort(NULL), - microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0) -#else -ThreadState::ThreadState(BaseCPU *cpu, int _cpuId, int _tid, Process *_process, - short _asid) - : baseCpu(cpu), cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), - port(NULL), process(_process), asid(_asid), - microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0) -#endif + kernelStats(NULL), process(_process), physProxy(NULL), virtProxy(NULL), + proxy(NULL), funcExeInst(0), storeCondFailures(0) { - numInst = 0; - numLoad = 0; } ThreadState::~ThreadState() { -#if !FULL_SYSTEM - if (port) { - delete port->getPeer(); - delete port; - } -#endif + if (physProxy != NULL) + delete physProxy; + if (virtProxy != NULL) + delete virtProxy; + if (proxy != NULL) + delete proxy; } void @@ -76,18 +67,16 @@ ThreadState::serialize(std::ostream &os) SERIALIZE_ENUM(_status); // thread_num and cpu_id are deterministic from the config SERIALIZE_SCALAR(funcExeInst); - SERIALIZE_SCALAR(inst); - SERIALIZE_SCALAR(microPC); - SERIALIZE_SCALAR(nextMicroPC); -#if FULL_SYSTEM + if (!FullSystem) + return; + Tick quiesceEndTick = 0; if (quiesceEvent->scheduled()) quiesceEndTick = quiesceEvent->when(); SERIALIZE_SCALAR(quiesceEndTick); if (kernelStats) kernelStats->serialize(os); -#endif } void @@ -97,48 +86,65 @@ ThreadState::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_ENUM(_status); // thread_num and cpu_id are deterministic from the config UNSERIALIZE_SCALAR(funcExeInst); - UNSERIALIZE_SCALAR(inst); - UNSERIALIZE_SCALAR(microPC); - UNSERIALIZE_SCALAR(nextMicroPC); -#if FULL_SYSTEM + if (!FullSystem) + return; + Tick quiesceEndTick; UNSERIALIZE_SCALAR(quiesceEndTick); if (quiesceEndTick) - quiesceEvent->schedule(quiesceEndTick); + baseCpu->schedule(quiesceEvent, quiesceEndTick); if (kernelStats) kernelStats->unserialize(cp, section); -#endif } -#if FULL_SYSTEM void -ThreadState::connectMemPorts() +ThreadState::initMemProxies(ThreadContext *tc) { - connectPhysPort(); - connectVirtPort(); + // The port proxies only refer to the data port on the CPU side + // and can safely be done at init() time even if the CPU is not + // connected, i.e. when restoring from a checkpoint and later + // switching the CPU in. + if (FullSystem) { + assert(physProxy == NULL); + // This cannot be done in the constructor as the thread state + // itself is created in the base cpu constructor and the + // getDataPort is a virtual function + physProxy = new PortProxy(baseCpu->getDataPort(), + baseCpu->cacheLineSize()); + + assert(virtProxy == NULL); + virtProxy = new FSTranslatingPortProxy(tc); + } else { + assert(proxy == NULL); + proxy = new SETranslatingPortProxy(baseCpu->getDataPort(), + process, + SETranslatingPortProxy::NextPage); + } } -void -ThreadState::connectPhysPort() +PortProxy & +ThreadState::getPhysProxy() { - // @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. - physPort = new FunctionalPort(csprintf("%s-%d-funcport", - baseCpu->name(), tid)); - connectToMemFunc(physPort); + assert(FullSystem); + assert(physProxy != NULL); + return *physProxy; } -void -ThreadState::connectVirtPort() +FSTranslatingPortProxy & +ThreadState::getVirtProxy() +{ + assert(FullSystem); + assert(virtProxy != NULL); + return *virtProxy; +} + +SETranslatingPortProxy & +ThreadState::getMemProxy() { - // @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. - virtPort = new VirtualPort(csprintf("%s-%d-vport", - baseCpu->name(), tid)); - connectToMemFunc(virtPort); + assert(!FullSystem); + assert(proxy != NULL); + return *proxy; } void @@ -154,39 +160,3 @@ ThreadState::profileSample() if (profile) profile->sample(profileNode, profilePC); } - -#else -TranslatingPort * -ThreadState::getMemPort() -{ - if (port != NULL) - return port; - - /* Use this port to for syscall emulation writes to memory. */ - port = new TranslatingPort(csprintf("%s-%d-funcport", - baseCpu->name(), tid), - process->pTable, false); - - connectToMemFunc(port); - - return port; -} -#endif - -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); - - func_mem_port = mem_object->getPort("functional"); - assert(func_mem_port != NULL); - - func_mem_port->setPeer(port); - port->setPeer(func_mem_port); -}