inorder-alpha-fs: edit inorder model to compile FS mode

This commit is contained in:
Korey Sewell 2009-09-15 01:44:48 -04:00
parent 15bb248013
commit badb2382a8
10 changed files with 354 additions and 24 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 &section) InOrderThreadContext::unserialize(Checkpoint *cp, const std::string &section)
{ {
#if FULL_SYSTEM panic("unserialize unimplemented");
if (thread->kernelStats)
thread->kernelStats->unserialize(cp, section);
#endif
;
} }
TheISA::MachInst TheISA::MachInst

View file

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

View 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

View file

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