inorder-alpha-fs: edit inorder model to compile FS mode
This commit is contained in:
parent
15bb248013
commit
badb2382a8
10 changed files with 354 additions and 24 deletions
|
@ -79,6 +79,7 @@ if 'InOrderCPU' in env['CPU_MODELS']:
|
||||||
Source('resources/mult_div_unit.cc')
|
Source('resources/mult_div_unit.cc')
|
||||||
Source('resource_pool.cc')
|
Source('resource_pool.cc')
|
||||||
Source('reg_dep_map.cc')
|
Source('reg_dep_map.cc')
|
||||||
|
Source('thread_state.cc')
|
||||||
Source('thread_context.cc')
|
Source('thread_context.cc')
|
||||||
Source('cpu.cc')
|
Source('cpu.cc')
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,15 @@
|
||||||
#include "sim/process.hh"
|
#include "sim/process.hh"
|
||||||
#include "sim/stat_control.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"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace TheISA;
|
using namespace TheISA;
|
||||||
using namespace ThePipeline;
|
using namespace ThePipeline;
|
||||||
|
@ -171,11 +180,16 @@ InOrderCPU::InOrderCPU(Params *params)
|
||||||
timeBuffer(2 , 2),
|
timeBuffer(2 , 2),
|
||||||
removeInstsThisCycle(false),
|
removeInstsThisCycle(false),
|
||||||
activityRec(params->name, NumStages, 10, params->activity),
|
activityRec(params->name, NumStages, 10, params->activity),
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
system(params->system),
|
||||||
|
physmem(system->physmem),
|
||||||
|
#endif // FULL_SYSTEM
|
||||||
switchCount(0),
|
switchCount(0),
|
||||||
deferRegistration(false/*params->deferRegistration*/),
|
deferRegistration(false/*params->deferRegistration*/),
|
||||||
stageTracing(params->stageTracing),
|
stageTracing(params->stageTracing),
|
||||||
numVirtProcs(1)
|
numVirtProcs(1)
|
||||||
{
|
{
|
||||||
|
ThreadID active_threads;
|
||||||
cpu_params = params;
|
cpu_params = params;
|
||||||
|
|
||||||
resPool = new ResourcePool(this, params);
|
resPool = new ResourcePool(this, params);
|
||||||
|
@ -183,13 +197,17 @@ InOrderCPU::InOrderCPU(Params *params)
|
||||||
// Resize for Multithreading CPUs
|
// Resize for Multithreading CPUs
|
||||||
thread.resize(numThreads);
|
thread.resize(numThreads);
|
||||||
|
|
||||||
ThreadID active_threads = params->workload.size();
|
#if FULL_SYSTEM
|
||||||
|
active_threads = 1;
|
||||||
|
#else
|
||||||
|
active_threads = params->workload.size();
|
||||||
|
|
||||||
if (active_threads > MaxThreads) {
|
if (active_threads > MaxThreads) {
|
||||||
panic("Workload Size too large. Increase the 'MaxThreads'"
|
panic("Workload Size too large. Increase the 'MaxThreads'"
|
||||||
"in your InOrder implementation or "
|
"in your InOrder implementation or "
|
||||||
"edit your workload size.");
|
"edit your workload size.");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Bind the fetch & data ports from the resource pool.
|
// Bind the fetch & data ports from the resource pool.
|
||||||
fetchPortIdx = resPool->getPortIdx(params->fetchMemPort);
|
fetchPortIdx = resPool->getPortIdx(params->fetchMemPort);
|
||||||
|
@ -203,6 +221,11 @@ InOrderCPU::InOrderCPU(Params *params)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ThreadID tid = 0; tid < numThreads; ++tid) {
|
for (ThreadID tid = 0; tid < numThreads; ++tid) {
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
// SMT is not supported in FS mode yet.
|
||||||
|
assert(this->numThreads == 1);
|
||||||
|
this->thread[tid] = new Thread(this, 0);
|
||||||
|
#else
|
||||||
if (tid < (ThreadID)params->workload.size()) {
|
if (tid < (ThreadID)params->workload.size()) {
|
||||||
DPRINTF(InOrderCPU, "Workload[%i] process is %#x\n",
|
DPRINTF(InOrderCPU, "Workload[%i] process is %#x\n",
|
||||||
tid, this->thread[tid]);
|
tid, this->thread[tid]);
|
||||||
|
@ -214,6 +237,7 @@ InOrderCPU::InOrderCPU(Params *params)
|
||||||
Process* dummy_proc = params->workload[0];
|
Process* dummy_proc = params->workload[0];
|
||||||
this->thread[tid] = new Thread(this, tid, dummy_proc);
|
this->thread[tid] = new Thread(this, tid, dummy_proc);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Setup the TC that will serve as the interface to the threads/CPU.
|
// Setup the TC that will serve as the interface to the threads/CPU.
|
||||||
InOrderThreadContext *tc = new InOrderThreadContext;
|
InOrderThreadContext *tc = new InOrderThreadContext;
|
||||||
|
@ -446,13 +470,6 @@ InOrderCPU::init()
|
||||||
resPool->init();
|
resPool->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
InOrderCPU::readFunctional(Addr addr, uint32_t &buffer)
|
|
||||||
{
|
|
||||||
tcBase()->getMemPort()->readBlob(addr, (uint8_t*)&buffer, sizeof(uint32_t));
|
|
||||||
buffer = gtoh(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderCPU::reset()
|
InOrderCPU::reset()
|
||||||
{
|
{
|
||||||
|
@ -468,6 +485,61 @@ InOrderCPU::getPort(const std::string &if_name, int idx)
|
||||||
return resPool->getPort(if_name, idx);
|
return resPool->getPort(if_name, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
Fault
|
||||||
|
InOrderCPU::hwrei(ThreadID tid)
|
||||||
|
{
|
||||||
|
panic("hwrei: Unimplemented");
|
||||||
|
|
||||||
|
return NoFault;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
InOrderCPU::simPalCheck(int palFunc, ThreadID tid)
|
||||||
|
{
|
||||||
|
panic("simPalCheck: Unimplemented");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Fault
|
||||||
|
InOrderCPU::getInterrupts()
|
||||||
|
{
|
||||||
|
// Check if there are any outstanding interrupts
|
||||||
|
return this->interrupts->getInterrupt(this->threadContexts[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InOrderCPU::processInterrupts(Fault interrupt)
|
||||||
|
{
|
||||||
|
// Check for interrupts here. For now can copy the code that
|
||||||
|
// exists within isa_fullsys_traits.hh. Also assume that thread 0
|
||||||
|
// is the one that handles the interrupts.
|
||||||
|
// @todo: Possibly consolidate the interrupt checking code.
|
||||||
|
// @todo: Allow other threads to handle interrupts.
|
||||||
|
|
||||||
|
assert(interrupt != NoFault);
|
||||||
|
this->interrupts->updateIntrInfo(this->threadContexts[0]);
|
||||||
|
|
||||||
|
DPRINTF(InOrderCPU, "Interrupt %s being handled\n", interrupt->name());
|
||||||
|
this->trap(interrupt, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
void
|
||||||
InOrderCPU::trap(Fault fault, ThreadID tid, int delay)
|
InOrderCPU::trap(Fault fault, ThreadID tid, int delay)
|
||||||
{
|
{
|
||||||
|
@ -1230,6 +1302,22 @@ InOrderCPU::wakeCPU()
|
||||||
mainEventQueue.schedule(&tickEvent, curTick);
|
mainEventQueue.schedule(&tickEvent, curTick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
|
||||||
|
void
|
||||||
|
InOrderCPU::wakeup()
|
||||||
|
{
|
||||||
|
if (this->thread[0]->status() != ThreadContext::Suspended)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this->wakeCPU();
|
||||||
|
|
||||||
|
DPRINTF(Quiesce, "Suspended Processor woken\n");
|
||||||
|
this->threadContexts[0]->activate();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !FULL_SYSTEM
|
||||||
void
|
void
|
||||||
InOrderCPU::syscall(int64_t callnum, ThreadID tid)
|
InOrderCPU::syscall(int64_t callnum, ThreadID tid)
|
||||||
{
|
{
|
||||||
|
@ -1251,6 +1339,7 @@ InOrderCPU::syscall(int64_t callnum, ThreadID tid)
|
||||||
// Clear Non-Speculative Block Variable
|
// Clear Non-Speculative Block Variable
|
||||||
nonSpecInstActive[tid] = false;
|
nonSpecInstActive[tid] = false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderCPU::prefetch(DynInstPtr inst)
|
InOrderCPU::prefetch(DynInstPtr inst)
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
|
|
||||||
#include "arch/isa_traits.hh"
|
#include "arch/isa_traits.hh"
|
||||||
#include "arch/types.hh"
|
#include "arch/types.hh"
|
||||||
|
#include "arch/registers.hh"
|
||||||
#include "base/statistics.hh"
|
#include "base/statistics.hh"
|
||||||
#include "base/timebuf.hh"
|
#include "base/timebuf.hh"
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
|
@ -297,6 +298,32 @@ class InOrderCPU : public BaseCPU
|
||||||
/** Get a Memory Port */
|
/** Get a Memory Port */
|
||||||
Port* getPort(const std::string &if_name, int idx = 0);
|
Port* getPort(const std::string &if_name, int idx = 0);
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
/** HW return from error interrupt. */
|
||||||
|
Fault hwrei(ThreadID tid);
|
||||||
|
|
||||||
|
bool simPalCheck(int palFunc, ThreadID tid);
|
||||||
|
|
||||||
|
/** Returns the Fault for any valid interrupt. */
|
||||||
|
Fault getInterrupts();
|
||||||
|
|
||||||
|
/** Processes any an interrupt fault. */
|
||||||
|
void processInterrupts(Fault interrupt);
|
||||||
|
|
||||||
|
/** Halts the CPU. */
|
||||||
|
void halt() { panic("Halt not implemented!\n"); }
|
||||||
|
|
||||||
|
/** Update the Virt and Phys ports of all ThreadContexts to
|
||||||
|
* reflect change in memory connections. */
|
||||||
|
void updateMemPorts();
|
||||||
|
|
||||||
|
/** Check if this address is a valid instruction address. */
|
||||||
|
bool validInstAddr(Addr addr) { return true; }
|
||||||
|
|
||||||
|
/** Check if this address is a valid data address. */
|
||||||
|
bool validDataAddr(Addr addr) { return true; }
|
||||||
|
#endif
|
||||||
|
|
||||||
/** trap() - sets up a trap event on the cpuTraps to handle given fault.
|
/** trap() - sets up a trap event on the cpuTraps to handle given fault.
|
||||||
* trapCPU() - Traps to handle given fault
|
* trapCPU() - Traps to handle given fault
|
||||||
*/
|
*/
|
||||||
|
@ -578,8 +605,6 @@ class InOrderCPU : public BaseCPU
|
||||||
ActivityRecorder activityRec;
|
ActivityRecorder activityRec;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void readFunctional(Addr addr, uint32_t &buffer);
|
|
||||||
|
|
||||||
/** Number of Active Threads in the CPU */
|
/** Number of Active Threads in the CPU */
|
||||||
ThreadID numActiveThreads() { return activeThreads.size(); }
|
ThreadID numActiveThreads() { return activeThreads.size(); }
|
||||||
|
|
||||||
|
@ -597,6 +622,10 @@ class InOrderCPU : public BaseCPU
|
||||||
/** Wakes the CPU, rescheduling the CPU if it's not already active. */
|
/** Wakes the CPU, rescheduling the CPU if it's not already active. */
|
||||||
void wakeCPU();
|
void wakeCPU();
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
virtual void wakeup();
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Gets a free thread id. Use if thread ids change across system. */
|
/** Gets a free thread id. Use if thread ids change across system. */
|
||||||
ThreadID getFreeTid();
|
ThreadID getFreeTid();
|
||||||
|
|
||||||
|
@ -622,6 +651,14 @@ class InOrderCPU : public BaseCPU
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
/** Pointer to the system. */
|
||||||
|
System *system;
|
||||||
|
|
||||||
|
/** Pointer to physical memory. */
|
||||||
|
PhysicalMemory *physmem;
|
||||||
|
#endif
|
||||||
|
|
||||||
/** The global sequence number counter. */
|
/** The global sequence number counter. */
|
||||||
InstSeqNum globalSeqNum[ThePipeline::MaxThreads];
|
InstSeqNum globalSeqNum[ThePipeline::MaxThreads];
|
||||||
|
|
||||||
|
|
|
@ -42,12 +42,17 @@
|
||||||
InOrderCPU *
|
InOrderCPU *
|
||||||
InOrderCPUParams::create()
|
InOrderCPUParams::create()
|
||||||
{
|
{
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
// Full-system only supports a single thread for the moment.
|
||||||
|
ThreadID actual_num_threads = 1;
|
||||||
|
#else
|
||||||
ThreadID actual_num_threads =
|
ThreadID actual_num_threads =
|
||||||
(numThreads >= workload.size()) ? numThreads : workload.size();
|
(numThreads >= workload.size()) ? numThreads : workload.size();
|
||||||
|
|
||||||
if (workload.size() == 0) {
|
if (workload.size() == 0) {
|
||||||
fatal("Must specify at least one workload!");
|
fatal("Must specify at least one workload!");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
numThreads = actual_num_threads;
|
numThreads = actual_num_threads;
|
||||||
|
|
||||||
|
|
|
@ -297,11 +297,39 @@ InOrderDynInst::memAccess()
|
||||||
return initiateAcc();
|
return initiateAcc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
|
||||||
|
Fault
|
||||||
|
InOrderDynInst::hwrei()
|
||||||
|
{
|
||||||
|
panic("InOrderDynInst: hwrei: unimplemented\n");
|
||||||
|
return NoFault;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InOrderDynInst::trap(Fault fault)
|
||||||
|
{
|
||||||
|
this->cpu->trap(fault, this->threadNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
InOrderDynInst::simPalCheck(int palFunc)
|
||||||
|
{
|
||||||
|
#if THE_ISA != ALPHA_ISA
|
||||||
|
panic("simPalCheck called, but PAL only exists in Alpha!\n");
|
||||||
|
#endif
|
||||||
|
return this->cpu->simPalCheck(palFunc, this->threadNumber);
|
||||||
|
}
|
||||||
|
#else
|
||||||
void
|
void
|
||||||
InOrderDynInst::syscall(int64_t callnum)
|
InOrderDynInst::syscall(int64_t callnum)
|
||||||
{
|
{
|
||||||
cpu->syscall(callnum, this->threadNumber);
|
cpu->syscall(callnum, this->threadNumber);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderDynInst::prefetch(Addr addr, unsigned flags)
|
InOrderDynInst::prefetch(Addr addr, unsigned flags)
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "arch/mt.hh"
|
#include "arch/mt.hh"
|
||||||
#include "base/fast_alloc.hh"
|
#include "base/fast_alloc.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
|
#include "base/types.hh"
|
||||||
#include "cpu/inorder/inorder_trace.hh"
|
#include "cpu/inorder/inorder_trace.hh"
|
||||||
#include "config/full_system.hh"
|
#include "config/full_system.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
|
@ -55,6 +56,11 @@
|
||||||
#include "cpu/inorder/pipeline_traits.hh"
|
#include "cpu/inorder/pipeline_traits.hh"
|
||||||
#include "mem/packet.hh"
|
#include "mem/packet.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
#include "sim/faults.hh"
|
||||||
|
|
||||||
|
#if THE_ISA==ALPHA_ISA
|
||||||
|
#include "arch/alpha/ev5.hh"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
|
@ -64,6 +70,7 @@
|
||||||
// Forward declaration.
|
// Forward declaration.
|
||||||
class StaticInstPtr;
|
class StaticInstPtr;
|
||||||
class ResourceRequest;
|
class ResourceRequest;
|
||||||
|
class Packet;
|
||||||
|
|
||||||
class InOrderDynInst : public FastAlloc, public RefCounted
|
class InOrderDynInst : public FastAlloc, public RefCounted
|
||||||
{
|
{
|
||||||
|
@ -486,7 +493,16 @@ class InOrderDynInst : public FastAlloc, public RefCounted
|
||||||
void setCurResSlot(unsigned slot_num) { curResSlot = slot_num; }
|
void setCurResSlot(unsigned slot_num) { curResSlot = slot_num; }
|
||||||
|
|
||||||
/** Calls a syscall. */
|
/** Calls a syscall. */
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
/** Calls hardware return from error interrupt. */
|
||||||
|
Fault hwrei();
|
||||||
|
/** Traps to handle specified fault. */
|
||||||
|
void trap(Fault fault);
|
||||||
|
bool simPalCheck(int palFunc);
|
||||||
|
#else
|
||||||
|
/** Calls a syscall. */
|
||||||
void syscall(int64_t callnum);
|
void syscall(int64_t callnum);
|
||||||
|
#endif
|
||||||
void prefetch(Addr addr, unsigned flags);
|
void prefetch(Addr addr, unsigned flags);
|
||||||
void writeHint(Addr addr, int size, unsigned flags);
|
void writeHint(Addr addr, int size, unsigned flags);
|
||||||
Fault copySrcTranslate(Addr src);
|
Fault copySrcTranslate(Addr src);
|
||||||
|
|
|
@ -35,18 +35,71 @@
|
||||||
|
|
||||||
using namespace TheISA;
|
using namespace TheISA;
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
|
||||||
|
VirtualPort *
|
||||||
|
InOrderThreadContext::getVirtPort()
|
||||||
|
{
|
||||||
|
return thread->getVirtPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InOrderThreadContext::dumpFuncProfile()
|
||||||
|
{
|
||||||
|
thread->dumpFuncProfile();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Tick
|
||||||
|
InOrderThreadContext::readLastActivate()
|
||||||
|
{
|
||||||
|
return thread->lastActivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Tick
|
||||||
|
InOrderThreadContext::readLastSuspend()
|
||||||
|
{
|
||||||
|
return thread->lastSuspend;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InOrderThreadContext::profileClear()
|
||||||
|
{
|
||||||
|
thread->profileClear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InOrderThreadContext::profileSample()
|
||||||
|
{
|
||||||
|
thread->profileSample();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderThreadContext::takeOverFrom(ThreadContext *old_context)
|
InOrderThreadContext::takeOverFrom(ThreadContext *old_context)
|
||||||
{
|
{
|
||||||
// some things should already be set up
|
// some things should already be set up
|
||||||
|
assert(getSystemPtr() == old_context->getSystemPtr());
|
||||||
|
#if !FULL_SYSTEM
|
||||||
assert(getProcessPtr() == old_context->getProcessPtr());
|
assert(getProcessPtr() == old_context->getProcessPtr());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// copy over functional state
|
// copy over functional state
|
||||||
setStatus(old_context->status());
|
setStatus(old_context->status());
|
||||||
copyArchRegs(old_context);
|
copyArchRegs(old_context);
|
||||||
|
|
||||||
|
#if !FULL_SYSTEM
|
||||||
thread->funcExeInst = old_context->readFuncExeInst();
|
thread->funcExeInst = old_context->readFuncExeInst();
|
||||||
|
#endif
|
||||||
|
|
||||||
old_context->setStatus(ThreadContext::Halted);
|
old_context->setStatus(ThreadContext::Halted);
|
||||||
|
|
||||||
thread->inSyscall = false;
|
thread->inSyscall = false;
|
||||||
thread->trapPending = false;
|
thread->trapPending = false;
|
||||||
}
|
}
|
||||||
|
@ -97,8 +150,8 @@ void
|
||||||
InOrderThreadContext::regStats(const std::string &name)
|
InOrderThreadContext::regStats(const std::string &name)
|
||||||
{
|
{
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
thread->kernelStats = new Kernel::Statistics(cpu->system);
|
//thread->kernelStats = new Kernel::Statistics(cpu->system);
|
||||||
thread->kernelStats->regStats(name + ".kern");
|
//thread->kernelStats->regStats(name + ".kern");
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -107,22 +160,14 @@ InOrderThreadContext::regStats(const std::string &name)
|
||||||
void
|
void
|
||||||
InOrderThreadContext::serialize(std::ostream &os)
|
InOrderThreadContext::serialize(std::ostream &os)
|
||||||
{
|
{
|
||||||
#if FULL_SYSTEM
|
panic("serialize unimplemented");
|
||||||
if (thread->kernelStats)
|
|
||||||
thread->kernelStats->serialize(os);
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderThreadContext::unserialize(Checkpoint *cp, const std::string §ion)
|
InOrderThreadContext::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
{
|
{
|
||||||
#if FULL_SYSTEM
|
panic("unserialize unimplemented");
|
||||||
if (thread->kernelStats)
|
|
||||||
thread->kernelStats->unserialize(cp, section);
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TheISA::MachInst
|
TheISA::MachInst
|
||||||
|
|
|
@ -101,10 +101,48 @@ class InOrderThreadContext : public ThreadContext
|
||||||
|
|
||||||
virtual void setNextMicroPC(uint64_t val) { };
|
virtual void setNextMicroPC(uint64_t val) { };
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
/** Returns a pointer to physical memory. */
|
||||||
|
virtual PhysicalMemory *getPhysMemPtr()
|
||||||
|
{ assert(0); return 0; /*return cpu->physmem;*/ }
|
||||||
|
|
||||||
|
/** Returns a pointer to this thread's kernel statistics. */
|
||||||
|
virtual TheISA::Kernel::Statistics *getKernelStats()
|
||||||
|
{ return thread->kernelStats; }
|
||||||
|
|
||||||
|
virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
|
||||||
|
|
||||||
|
virtual VirtualPort *getVirtPort();
|
||||||
|
|
||||||
|
virtual void connectMemPorts(ThreadContext *tc) { thread->connectMemPorts(tc); }
|
||||||
|
|
||||||
|
/** Dumps the function profiling information.
|
||||||
|
* @todo: Implement.
|
||||||
|
*/
|
||||||
|
virtual void dumpFuncProfile();
|
||||||
|
|
||||||
|
/** Reads the last tick that this thread was activated on. */
|
||||||
|
virtual Tick readLastActivate();
|
||||||
|
/** Reads the last tick that this thread was suspended on. */
|
||||||
|
virtual Tick readLastSuspend();
|
||||||
|
|
||||||
|
/** Clears the function profiling information. */
|
||||||
|
virtual void profileClear();
|
||||||
|
|
||||||
|
/** Samples the function profiling information. */
|
||||||
|
virtual void profileSample();
|
||||||
|
|
||||||
|
/** Returns pointer to the quiesce event. */
|
||||||
|
virtual EndQuiesceEvent *getQuiesceEvent()
|
||||||
|
{
|
||||||
|
return this->thread->quiesceEvent;
|
||||||
|
}
|
||||||
|
#else
|
||||||
virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
|
virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
|
||||||
|
|
||||||
/** Returns a pointer to this thread's process. */
|
/** Returns a pointer to this thread's process. */
|
||||||
virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
|
virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Returns this thread's status. */
|
/** Returns this thread's status. */
|
||||||
virtual Status status() const { return thread->status(); }
|
virtual Status status() const { return thread->status(); }
|
||||||
|
@ -232,9 +270,11 @@ class InOrderThreadContext : public ThreadContext
|
||||||
* misspeculating, this is set as false. */
|
* misspeculating, this is set as false. */
|
||||||
virtual bool misspeculating() { return false; }
|
virtual bool misspeculating() { return false; }
|
||||||
|
|
||||||
|
#if !FULL_SYSTEM
|
||||||
/** Executes a syscall in SE mode. */
|
/** Executes a syscall in SE mode. */
|
||||||
virtual void syscall(int64_t callnum)
|
virtual void syscall(int64_t callnum)
|
||||||
{ return cpu->syscall(callnum, thread->readTid()); }
|
{ return cpu->syscall(callnum, thread->readTid()); }
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Reads the funcExeInst counter. */
|
/** Reads the funcExeInst counter. */
|
||||||
virtual Counter readFuncExeInst() { return thread->funcExeInst; }
|
virtual Counter readFuncExeInst() { return thread->funcExeInst; }
|
||||||
|
|
47
src/cpu/inorder/thread_state.cc
Normal file
47
src/cpu/inorder/thread_state.cc
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2007 MIPS Technologies, Inc.
|
||||||
|
* 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: Korey Sewell
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "arch/isa_traits.hh"
|
||||||
|
#include "cpu/exetrace.hh"
|
||||||
|
#include "cpu/inorder/thread_state.hh"
|
||||||
|
#include "cpu/inorder/cpu.hh"
|
||||||
|
|
||||||
|
using namespace TheISA;
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
void
|
||||||
|
InOrderThreadState::dumpFuncProfile()
|
||||||
|
{
|
||||||
|
std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
|
||||||
|
profile->dump(tc, *os);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -33,13 +33,23 @@
|
||||||
|
|
||||||
#include "arch/faults.hh"
|
#include "arch/faults.hh"
|
||||||
#include "arch/isa_traits.hh"
|
#include "arch/isa_traits.hh"
|
||||||
|
#include "base/callback.hh"
|
||||||
|
#include "base/output.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "cpu/thread_state.hh"
|
#include "cpu/thread_state.hh"
|
||||||
|
#include "sim/sim_exit.hh"
|
||||||
|
|
||||||
class Event;
|
class Event;
|
||||||
|
class InOrderCPU;
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
class EndQuiesceEvent;
|
||||||
|
class FunctionProfile;
|
||||||
|
class ProfileNode;
|
||||||
|
#else
|
||||||
class FunctionalMemory;
|
class FunctionalMemory;
|
||||||
class Process;
|
class Process;
|
||||||
class InOrderCPU;
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that has various thread state, such as the status, the
|
* Class that has various thread state, such as the status, the
|
||||||
|
@ -66,16 +76,28 @@ class InOrderThreadState : public ThreadState {
|
||||||
*/
|
*/
|
||||||
bool trapPending;
|
bool trapPending;
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num)
|
||||||
|
: ThreadState(reinterpret_cast<BaseCPU*>(_cpu), 0/*_thread_num*/),
|
||||||
|
cpu(_cpu), inSyscall(0), trapPending(0)
|
||||||
|
{ }
|
||||||
|
#else
|
||||||
InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num,
|
InOrderThreadState(InOrderCPU *_cpu, ThreadID _thread_num,
|
||||||
Process *_process)
|
Process *_process)
|
||||||
: ThreadState(reinterpret_cast<BaseCPU*>(_cpu), 0/*_thread_num*/,
|
: ThreadState(reinterpret_cast<BaseCPU*>(_cpu), 0/*_thread_num*/,
|
||||||
_process),
|
_process),
|
||||||
cpu(_cpu), inSyscall(0), trapPending(0)
|
cpu(_cpu), inSyscall(0), trapPending(0)
|
||||||
{ }
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !FULL_SYSTEM
|
||||||
/** Handles the syscall. */
|
/** Handles the syscall. */
|
||||||
void syscall(int64_t callnum) { process->syscall(callnum, tc); }
|
void syscall(int64_t callnum) { process->syscall(callnum, tc); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
void dumpFuncProfile();
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Pointer to the ThreadContext of this thread. */
|
/** Pointer to the ThreadContext of this thread. */
|
||||||
ThreadContext *tc;
|
ThreadContext *tc;
|
||||||
|
|
Loading…
Reference in a new issue