summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/base_cpu.cc68
-rw-r--r--cpu/base_cpu.hh38
-rw-r--r--cpu/exec_context.hh8
-rw-r--r--cpu/exetrace.cc2
-rw-r--r--cpu/full_cpu/op_class.hh1
-rw-r--r--cpu/memtest/memtest.cc49
-rw-r--r--cpu/memtest/memtest.hh17
-rw-r--r--cpu/pc_event.cc7
-rw-r--r--cpu/simple_cpu/simple_cpu.cc221
-rw-r--r--cpu/simple_cpu/simple_cpu.hh94
-rw-r--r--cpu/static_inst.cc4
-rw-r--r--cpu/static_inst.hh26
-rw-r--r--cpu/trace/opt_cpu.cc2
-rw-r--r--cpu/trace/opt_cpu.hh11
-rw-r--r--cpu/trace/trace_cpu.cc2
-rw-r--r--cpu/trace/trace_cpu.hh11
16 files changed, 276 insertions, 285 deletions
diff --git a/cpu/base_cpu.cc b/cpu/base_cpu.cc
index 7605ff3c3..181b484e7 100644
--- a/cpu/base_cpu.cc
+++ b/cpu/base_cpu.cc
@@ -26,15 +26,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <iostream>
#include <string>
#include <sstream>
-#include <iostream>
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "base/misc.hh"
+#include "base/output.hh"
#include "cpu/base_cpu.hh"
#include "cpu/exec_context.hh"
+#include "cpu/sampling_cpu/sampling_cpu.hh"
#include "sim/param.hh"
#include "sim/sim_events.hh"
@@ -48,25 +50,12 @@ vector<BaseCPU *> BaseCPU::cpuList;
int maxThreadsPerCPU = 1;
#ifdef FULL_SYSTEM
-BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
- Counter max_insts_any_thread,
- Counter max_insts_all_threads,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads,
- System *_system, Tick freq,
- bool _function_trace, Tick _function_trace_start)
- : SimObject(_name), frequency(freq), checkInterrupts(true),
- deferRegistration(_def_reg), number_of_threads(_number_of_threads),
- system(_system)
+BaseCPU::BaseCPU(Params *p)
+ : SimObject(p->name), frequency(p->freq), checkInterrupts(true),
+ params(p), number_of_threads(p->numberOfThreads), system(p->system)
#else
-BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
- Counter max_insts_any_thread,
- Counter max_insts_all_threads,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads,
- bool _function_trace, Tick _function_trace_start)
- : SimObject(_name), deferRegistration(_def_reg),
- number_of_threads(_number_of_threads)
+BaseCPU::BaseCPU(Params *p)
+ : SimObject(p->name), params(p), number_of_threads(p->numberOfThreads)
#endif
{
// add self to global list of CPUs
@@ -76,19 +65,19 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
maxThreadsPerCPU = number_of_threads;
// allocate per-thread instruction-based event queues
- comInstEventQueue = new (EventQueue *)[number_of_threads];
+ comInstEventQueue = new EventQueue *[number_of_threads];
for (int i = 0; i < number_of_threads; ++i)
comInstEventQueue[i] = new EventQueue("instruction-based event queue");
//
// set up instruction-count-based termination events, if any
//
- if (max_insts_any_thread != 0)
+ if (p->max_insts_any_thread != 0)
for (int i = 0; i < number_of_threads; ++i)
- new SimExitEvent(comInstEventQueue[i], max_insts_any_thread,
+ new SimExitEvent(comInstEventQueue[i], p->max_insts_any_thread,
"a thread reached the max instruction count");
- if (max_insts_all_threads != 0) {
+ if (p->max_insts_all_threads != 0) {
// allocate & initialize shared downcounter: each event will
// decrement this when triggered; simulation will terminate
// when counter reaches 0
@@ -97,23 +86,23 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
for (int i = 0; i < number_of_threads; ++i)
new CountedExitEvent(comInstEventQueue[i],
"all threads reached the max instruction count",
- max_insts_all_threads, *counter);
+ p->max_insts_all_threads, *counter);
}
// allocate per-thread load-based event queues
- comLoadEventQueue = new (EventQueue *)[number_of_threads];
+ comLoadEventQueue = new EventQueue *[number_of_threads];
for (int i = 0; i < number_of_threads; ++i)
comLoadEventQueue[i] = new EventQueue("load-based event queue");
//
// set up instruction-count-based termination events, if any
//
- if (max_loads_any_thread != 0)
+ if (p->max_loads_any_thread != 0)
for (int i = 0; i < number_of_threads; ++i)
- new SimExitEvent(comLoadEventQueue[i], max_loads_any_thread,
+ new SimExitEvent(comLoadEventQueue[i], p->max_loads_any_thread,
"a thread reached the max load count");
- if (max_loads_all_threads != 0) {
+ if (p->max_loads_all_threads != 0) {
// allocate & initialize shared downcounter: each event will
// decrement this when triggered; simulation will terminate
// when counter reaches 0
@@ -122,7 +111,7 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
for (int i = 0; i < number_of_threads; ++i)
new CountedExitEvent(comLoadEventQueue[i],
"all threads reached the max load count",
- max_loads_all_threads, *counter);
+ p->max_loads_all_threads, *counter);
}
#ifdef FULL_SYSTEM
@@ -131,19 +120,18 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
#endif
functionTracingEnabled = false;
- if (_function_trace) {
- std::string filename = csprintf("ftrace.%s", name());
- functionTraceStream = makeOutputStream(filename);
+ if (p->functionTrace) {
+ functionTraceStream = simout.find(csprintf("ftrace.%s", name()));
currentFunctionStart = currentFunctionEnd = 0;
- functionEntryTick = _function_trace_start;
+ functionEntryTick = p->functionTraceStart;
- if (_function_trace_start == 0) {
+ if (p->functionTraceStart == 0) {
functionTracingEnabled = true;
} else {
Event *e =
new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this,
true);
- e->schedule(_function_trace_start);
+ e->schedule(p->functionTraceStart);
}
}
}
@@ -157,15 +145,12 @@ BaseCPU::enableFunctionTrace()
BaseCPU::~BaseCPU()
{
- if (functionTracingEnabled)
- closeOutputStream(functionTraceStream);
}
-
void
BaseCPU::init()
{
- if (!deferRegistration)
+ if (!params->deferRegistration)
registerExecContexts();
}
@@ -210,9 +195,10 @@ BaseCPU::registerExecContexts()
void
-BaseCPU::switchOut()
+BaseCPU::switchOut(SamplingCPU *sampler)
{
- // default: do nothing
+ // default: do nothing, signal done
+ sampler->signalSwitched();
}
void
diff --git a/cpu/base_cpu.hh b/cpu/base_cpu.hh
index baa956aa8..f346f4ec5 100644
--- a/cpu/base_cpu.hh
+++ b/cpu/base_cpu.hh
@@ -32,6 +32,7 @@
#include <vector>
#include "base/statistics.hh"
+#include "cpu/sampling_cpu/sampling_cpu.hh"
#include "sim/eventq.hh"
#include "sim/sim_object.hh"
#include "targetarch/isa_traits.hh"
@@ -90,33 +91,36 @@ class BaseCPU : public SimObject
virtual void haltContext(int thread_num) {}
public:
-
+ struct Params
+ {
+ std::string name;
+ int numberOfThreads;
+ bool deferRegistration;
+ Counter max_insts_any_thread;
+ Counter max_insts_all_threads;
+ Counter max_loads_any_thread;
+ Counter max_loads_all_threads;
+ Tick freq;
+ bool functionTrace;
+ Tick functionTraceStart;
#ifdef FULL_SYSTEM
- BaseCPU(const std::string &_name, int _number_of_threads, bool _def_reg,
- Counter max_insts_any_thread, Counter max_insts_all_threads,
- Counter max_loads_any_thread, Counter max_loads_all_threads,
- System *_system, Tick freq,
- bool _function_trace = false, Tick _function_trace_start = 0);
-#else
- BaseCPU(const std::string &_name, int _number_of_threads, bool _def_reg,
- Counter max_insts_any_thread = 0,
- Counter max_insts_all_threads = 0,
- Counter max_loads_any_thread = 0,
- Counter max_loads_all_threads = 0,
- bool _function_trace = false, Tick _function_trace_start = 0);
+ System *system;
#endif
+ };
+
+ const Params *params;
+ BaseCPU(Params *params);
virtual ~BaseCPU();
virtual void init();
virtual void regStats();
- bool deferRegistration;
void registerExecContexts();
- /// Prepare for another CPU to take over execution. Called by
- /// takeOverFrom() on its argument.
- virtual void switchOut();
+ /// Prepare for another CPU to take over execution. When it is
+ /// is ready (drained pipe) it signals the sampler.
+ virtual void switchOut(SamplingCPU *);
/// Take over execution from the given CPU. Used for warm-up and
/// sampling.
diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh
index 8437a5585..d6140d52f 100644
--- a/cpu/exec_context.hh
+++ b/cpu/exec_context.hh
@@ -435,20 +435,20 @@ class ExecContext
regs.intRegFile[ArgumentReg0 + i] = val;
}
- void setSyscallReturn(int64_t return_value)
+ void setSyscallReturn(SyscallReturn return_value)
{
// check for error condition. Alpha syscall convention is to
// indicate success/failure in reg a3 (r19) and put the
// return value itself in the standard return value reg (v0).
const int RegA3 = 19; // only place this is used
- if (return_value >= 0) {
+ if (return_value.successful()) {
// no error
regs.intRegFile[RegA3] = 0;
- regs.intRegFile[ReturnValueReg] = return_value;
+ regs.intRegFile[ReturnValueReg] = return_value.value();
} else {
// got an error, return details
regs.intRegFile[RegA3] = (IntReg) -1;
- regs.intRegFile[ReturnValueReg] = -return_value;
+ regs.intRegFile[ReturnValueReg] = -return_value.value();
}
}
diff --git a/cpu/exetrace.cc b/cpu/exetrace.cc
index ff7e90c9e..048a7d283 100644
--- a/cpu/exetrace.cc
+++ b/cpu/exetrace.cc
@@ -154,7 +154,7 @@ class ExecutionTraceParamContext : public ParamContext
ExecutionTraceParamContext exeTraceParams("exetrace");
Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
- "capture speculative instructions", false);
+ "capture speculative instructions", true);
Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
"print cycle number", true);
diff --git a/cpu/full_cpu/op_class.hh b/cpu/full_cpu/op_class.hh
index a14ccfaed..8e85e8d8a 100644
--- a/cpu/full_cpu/op_class.hh
+++ b/cpu/full_cpu/op_class.hh
@@ -51,6 +51,7 @@ enum OpClass {
FloatSqrtOp, /* floating point square root */
MemReadOp, /* memory read port */
MemWriteOp, /* memory write port */
+ IprAccessOp, /* Internal Processor Register read/write port */
InstPrefetchOp, /* instruction prefetch port (on I-cache) */
Num_OpClasses /* total functional unit classes */
};
diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc
index e967c79da..14b119880 100644
--- a/cpu/memtest/memtest.cc
+++ b/cpu/memtest/memtest.cc
@@ -36,6 +36,7 @@
#include "base/misc.hh"
#include "base/statistics.hh"
+#include "cpu/exec_context.hh"
#include "cpu/memtest/memtest.hh"
#include "mem/cache/base_cache.hh"
#include "mem/functional_mem/main_memory.hh"
@@ -59,10 +60,8 @@ MemTest::MemTest(const string &name,
unsigned _percentSourceUnaligned,
unsigned _percentDestUnaligned,
Addr _traceAddr,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads)
- : BaseCPU(name, 1, true, 0, 0, max_loads_any_thread,
- max_loads_all_threads),
+ Counter _max_loads)
+ : SimObject(name),
tickEvent(this),
cacheInterface(_cache_interface),
mainMem(main_mem),
@@ -74,12 +73,13 @@ MemTest::MemTest(const string &name,
progressInterval(_progressInterval),
nextProgressMessage(_progressInterval),
percentSourceUnaligned(_percentSourceUnaligned),
- percentDestUnaligned(percentDestUnaligned)
+ percentDestUnaligned(percentDestUnaligned),
+ maxLoads(_max_loads)
{
vector<string> cmd;
cmd.push_back("/bin/ls");
vector<string> null_vec;
- xc = new ExecContext(this ,0,mainMem,0);
+ xc = new ExecContext(NULL, 0, mainMem, 0);
blockSize = cacheInterface->getBlockSize();
blockAddrMask = blockSize - 1;
@@ -160,7 +160,8 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
nextProgressMessage += progressInterval;
}
- comLoadEventQueue[0]->serviceEvents(numReads);
+ if (numReads >= maxLoads)
+ SimExit(curTick, "Maximum number of loads reached!");
break;
case Write:
@@ -402,8 +403,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest)
Param<unsigned> percent_source_unaligned;
Param<unsigned> percent_dest_unaligned;
Param<Addr> trace_addr;
- Param<Counter> max_loads_any_thread;
- Param<Counter> max_loads_all_threads;
+ Param<Counter> max_loads;
END_DECLARE_SIM_OBJECT_PARAMS(MemTest)
@@ -413,23 +413,17 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(MemTest)
INIT_PARAM(cache, "L1 cache"),
INIT_PARAM(main_mem, "hierarchical memory"),
INIT_PARAM(check_mem, "check memory"),
- INIT_PARAM_DFLT(memory_size, "memory size", 65536),
- INIT_PARAM_DFLT(percent_reads, "target read percentage", 65),
- INIT_PARAM_DFLT(percent_copies, "target copy percentage", 0),
- INIT_PARAM_DFLT(percent_uncacheable, "target uncacheable percentage", 10),
- INIT_PARAM_DFLT(progress_interval,
- "progress report interval (in accesses)", 1000000),
- INIT_PARAM_DFLT(percent_source_unaligned, "percent of copy source address "
- "that are unaligned", 50),
- INIT_PARAM_DFLT(percent_dest_unaligned, "percent of copy dest address "
- "that are unaligned", 50),
- INIT_PARAM_DFLT(trace_addr, "address to trace", 0),
- INIT_PARAM_DFLT(max_loads_any_thread,
- "terminate when any thread reaches this load count",
- 0),
- INIT_PARAM_DFLT(max_loads_all_threads,
- "terminate when all threads have reached this load count",
- 0)
+ INIT_PARAM(memory_size, "memory size"),
+ INIT_PARAM(percent_reads, "target read percentage"),
+ INIT_PARAM(percent_copies, "target copy percentage"),
+ INIT_PARAM(percent_uncacheable, "target uncacheable percentage"),
+ INIT_PARAM(progress_interval, "progress report interval (in accesses)"),
+ INIT_PARAM(percent_source_unaligned,
+ "percent of copy source address that are unaligned"),
+ INIT_PARAM(percent_dest_unaligned,
+ "percent of copy dest address that are unaligned"),
+ INIT_PARAM(trace_addr, "address to trace"),
+ INIT_PARAM(max_loads, "terminate when we have reached this load count")
END_INIT_SIM_OBJECT_PARAMS(MemTest)
@@ -440,8 +434,7 @@ CREATE_SIM_OBJECT(MemTest)
check_mem, memory_size, percent_reads, percent_copies,
percent_uncacheable, progress_interval,
percent_source_unaligned, percent_dest_unaligned,
- trace_addr, max_loads_any_thread,
- max_loads_all_threads);
+ trace_addr, max_loads);
}
REGISTER_SIM_OBJECT("MemTest", MemTest)
diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh
index 43b17a713..45b2d24e8 100644
--- a/cpu/memtest/memtest.hh
+++ b/cpu/memtest/memtest.hh
@@ -26,20 +26,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __MEMTEST_HH__
-#define __MEMTEST_HH__
+#ifndef __CPU_MEMTEST_MEMTEST_HH__
+#define __CPU_MEMTEST_MEMTEST_HH__
#include <set>
#include "base/statistics.hh"
-#include "cpu/base_cpu.hh"
-#include "cpu/exec_context.hh"
#include "mem/functional_mem/functional_memory.hh"
#include "mem/mem_interface.hh"
+#include "sim/eventq.hh"
+#include "sim/sim_exit.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"
-class MemTest : public BaseCPU
+class ExecContext;
+class MemTest : public SimObject
{
public:
@@ -55,8 +56,7 @@ class MemTest : public BaseCPU
unsigned _percentSourceUnaligned,
unsigned _percentDestUnaligned,
Addr _traceAddr,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads);
+ Counter _max_loads);
// register statistics
virtual void regStats();
@@ -116,6 +116,7 @@ class MemTest : public BaseCPU
Tick noResponseCycles;
uint64_t numReads;
+ uint64_t maxLoads;
Stats::Scalar<> numReadsStat;
Stats::Scalar<> numWritesStat;
Stats::Scalar<> numCopiesStat;
@@ -146,7 +147,7 @@ class MemCompleteEvent : public Event
virtual const char *description();
};
-#endif // __MEMTEST_HH__
+#endif // __CPU_MEMTEST_MEMTEST_HH__
diff --git a/cpu/pc_event.cc b/cpu/pc_event.cc
index 8f046a7a4..21eef677a 100644
--- a/cpu/pc_event.cc
+++ b/cpu/pc_event.cc
@@ -31,10 +31,11 @@
#include <string>
#include <utility>
-#include "sim/debug.hh"
+#include "base/trace.hh"
+#include "cpu/base_cpu.hh"
#include "cpu/exec_context.hh"
#include "cpu/pc_event.hh"
-#include "base/trace.hh"
+#include "sim/debug.hh"
#include "sim/universe.hh"
using namespace std;
@@ -123,6 +124,8 @@ BreakPCEvent::BreakPCEvent(PCEventQueue *q, const std::string &desc, bool del)
void
BreakPCEvent::process(ExecContext *xc)
{
+ StringWrap name(xc->cpu->name() + ".break_event");
+ DPRINTFN("break event %s triggered", descr());
debug_break();
if (remove)
delete this;
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
index d48f93663..86aeab7d7 100644
--- a/cpu/simple_cpu/simple_cpu.cc
+++ b/cpu/simple_cpu/simple_cpu.cc
@@ -47,6 +47,7 @@
#include "cpu/exec_context.hh"
#include "cpu/exetrace.hh"
#include "cpu/full_cpu/smt.hh"
+#include "cpu/sampling_cpu/sampling_cpu.hh"
#include "cpu/simple_cpu/simple_cpu.hh"
#include "cpu/static_inst.hh"
#include "mem/base_mem.hh"
@@ -74,15 +75,16 @@
using namespace std;
-SimpleCPU::TickEvent::TickEvent(SimpleCPU *c)
- : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c), multiplier(1)
+
+SimpleCPU::TickEvent::TickEvent(SimpleCPU *c, int w)
+ : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c), width(w)
{
}
void
SimpleCPU::TickEvent::process()
{
- int count = multiplier;
+ int count = width;
do {
cpu->tick();
} while (--count > 0 && cpu->status() == Running);
@@ -96,8 +98,7 @@ SimpleCPU::TickEvent::description()
SimpleCPU::CacheCompletionEvent::CacheCompletionEvent(SimpleCPU *_cpu)
- : Event(&mainEventQueue),
- cpu(_cpu)
+ : Event(&mainEventQueue), cpu(_cpu)
{
}
@@ -112,52 +113,22 @@ SimpleCPU::CacheCompletionEvent::description()
return "SimpleCPU cache completion event";
}
-#ifdef FULL_SYSTEM
-SimpleCPU::SimpleCPU(const string &_name,
- System *_system,
- Counter max_insts_any_thread,
- Counter max_insts_all_threads,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads,
- AlphaITB *itb, AlphaDTB *dtb,
- FunctionalMemory *mem,
- MemInterface *icache_interface,
- MemInterface *dcache_interface,
- bool _def_reg, Tick freq,
- bool _function_trace, Tick _function_trace_start)
- : BaseCPU(_name, /* number_of_threads */ 1, _def_reg,
- max_insts_any_thread, max_insts_all_threads,
- max_loads_any_thread, max_loads_all_threads,
- _system, freq, _function_trace, _function_trace_start),
-#else
-SimpleCPU::SimpleCPU(const string &_name, Process *_process,
- Counter max_insts_any_thread,
- Counter max_insts_all_threads,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads,
- MemInterface *icache_interface,
- MemInterface *dcache_interface,
- bool _def_reg,
- bool _function_trace, Tick _function_trace_start)
- : BaseCPU(_name, /* number_of_threads */ 1, _def_reg,
- max_insts_any_thread, max_insts_all_threads,
- max_loads_any_thread, max_loads_all_threads,
- _function_trace, _function_trace_start),
-#endif
- tickEvent(this), xc(NULL), cacheCompletionEvent(this)
+SimpleCPU::SimpleCPU(Params *p)
+ : BaseCPU(p), tickEvent(this, p->width), xc(NULL),
+ cacheCompletionEvent(this)
{
_status = Idle;
#ifdef FULL_SYSTEM
- xc = new ExecContext(this, 0, system, itb, dtb, mem);
+ xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
// initialize CPU, including PC
TheISA::initCPU(&xc->regs);
#else
- xc = new ExecContext(this, /* thread_num */ 0, _process, /* asid */ 0);
+ xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0);
#endif // !FULL_SYSTEM
- icacheInterface = icache_interface;
- dcacheInterface = dcache_interface;
+ icacheInterface = p->icache_interface;
+ dcacheInterface = p->dcache_interface;
memReq = new MemReq();
memReq->xc = xc;
@@ -179,11 +150,21 @@ SimpleCPU::~SimpleCPU()
}
void
-SimpleCPU::switchOut()
+SimpleCPU::switchOut(SamplingCPU *s)
{
- _status = SwitchedOut;
- if (tickEvent.scheduled())
- tickEvent.squash();
+ sampler = s;
+ if (status() == DcacheMissStall) {
+ DPRINTF(Sampler,"Outstanding dcache access, waiting for completion\n");
+ _status = DcacheMissSwitch;
+ }
+ else {
+ _status = SwitchedOut;
+
+ if (tickEvent.scheduled())
+ tickEvent.squash();
+
+ sampler->signalSwitched();
+ }
}
@@ -203,8 +184,6 @@ SimpleCPU::takeOverFrom(BaseCPU *oldCPU)
tickEvent.schedule(curTick);
}
}
-
- oldCPU->switchOut();
}
@@ -414,21 +393,22 @@ template <class T>
Fault
SimpleCPU::read(Addr addr, T &data, unsigned flags)
{
+ if (status() == DcacheMissStall) {
+ Fault fault = xc->read(memReq,data);
+
+ if (traceData) {
+ traceData->setAddr(addr);
+ if (fault == No_Fault)
+ traceData->setData(data);
+ }
+ return fault;
+ }
+
memReq->reset(addr, sizeof(T), flags);
// translate to physical address
Fault fault = xc->translateDataReadReq(memReq);
- // do functional access
- if (fault == No_Fault)
- fault = xc->read(memReq, data);
-
- if (traceData) {
- traceData->setAddr(addr);
- if (fault == No_Fault)
- traceData->setData(data);
- }
-
// if we have a cache, do cache access too
if (fault == No_Fault && dcacheInterface) {
memReq->cmd = Read;
@@ -444,6 +424,24 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
lastDcacheStall = curTick;
unscheduleTickEvent();
_status = DcacheMissStall;
+ } else {
+ // do functional access
+ fault = xc->read(memReq, data);
+
+ if (traceData) {
+ traceData->setAddr(addr);
+ if (fault == No_Fault)
+ traceData->setData(data);
+ }
+ }
+ } else if(fault == No_Fault) {
+ // do functional access
+ fault = xc->read(memReq, data);
+
+ if (traceData) {
+ traceData->setAddr(addr);
+ if (fault == No_Fault)
+ traceData->setData(data);
}
}
@@ -605,10 +603,19 @@ SimpleCPU::processCacheCompletion()
scheduleTickEvent(1);
break;
case DcacheMissStall:
+ if (memReq->cmd.isRead()) {
+ curStaticInst->execute(this,traceData);
+ }
dcacheStallCycles += curTick - lastDcacheStall;
_status = Running;
scheduleTickEvent(1);
break;
+ case DcacheMissSwitch:
+ if (memReq->cmd.isRead()) {
+ curStaticInst->execute(this,traceData);
+ }
+ _status = SwitchedOut;
+ sampler->signalSwitched();
case SwitchedOut:
// If this CPU has been switched out due to sampling/warm-up,
// ignore any further status changes (e.g., due to cache
@@ -750,10 +757,10 @@ SimpleCPU::tick()
comInstEventQueue[0]->serviceEvents(numInst);
// decode the instruction
- inst = htoa(inst);
- StaticInstPtr<TheISA> si(inst);
+ inst = htoa(inst);
+ curStaticInst = StaticInst<TheISA>::decode(inst);
- traceData = Trace::getInstRecord(curTick, xc, this, si,
+ traceData = Trace::getInstRecord(curTick, xc, this, curStaticInst,
xc->regs.pc);
#ifdef FULL_SYSTEM
@@ -762,18 +769,18 @@ SimpleCPU::tick()
xc->func_exe_inst++;
- fault = si->execute(this, traceData);
+ fault = curStaticInst->execute(this, traceData);
#ifdef FULL_SYSTEM
if (xc->fnbin)
- xc->execute(si.get());
+ xc->execute(curStaticInst.get());
#endif
- if (si->isMemRef()) {
+ if (curStaticInst->isMemRef()) {
numMemRefs++;
}
- if (si->isLoad()) {
+ if (curStaticInst->isLoad()) {
++numLoad;
comLoadEventQueue[0]->serviceEvents(numLoad);
}
@@ -840,7 +847,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
SimObjectParam<BaseMem *> dcache;
Param<bool> defer_registration;
- Param<int> multiplier;
+ Param<int> width;
Param<bool> function_trace;
Param<Tick> function_trace_start;
@@ -848,71 +855,67 @@ END_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
- INIT_PARAM_DFLT(max_insts_any_thread,
- "terminate when any thread reaches this inst count",
- 0),
- INIT_PARAM_DFLT(max_insts_all_threads,
- "terminate when all threads have reached this inst count",
- 0),
- INIT_PARAM_DFLT(max_loads_any_thread,
- "terminate when any thread reaches this load count",
- 0),
- INIT_PARAM_DFLT(max_loads_all_threads,
- "terminate when all threads have reached this load count",
- 0),
+ INIT_PARAM(max_insts_any_thread,
+ "terminate when any thread reaches this inst count"),
+ INIT_PARAM(max_insts_all_threads,
+ "terminate when all threads have reached this inst count"),
+ INIT_PARAM(max_loads_any_thread,
+ "terminate when any thread reaches this load count"),
+ INIT_PARAM(max_loads_all_threads,
+ "terminate when all threads have reached this load count"),
#ifdef FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
INIT_PARAM(dtb, "Data TLB"),
INIT_PARAM(mem, "memory"),
INIT_PARAM(system, "system object"),
- INIT_PARAM_DFLT(mult, "system clock multiplier", 1),
+ INIT_PARAM(mult, "system clock multiplier"),
#else
INIT_PARAM(workload, "processes to run"),
#endif // FULL_SYSTEM
- INIT_PARAM_DFLT(icache, "L1 instruction cache object", NULL),
- INIT_PARAM_DFLT(dcache, "L1 data cache object", NULL),
- INIT_PARAM_DFLT(defer_registration, "defer registration with system "
- "(for sampling)", false),
-
- INIT_PARAM_DFLT(multiplier, "clock multiplier", 1),
- INIT_PARAM_DFLT(function_trace, "Enable function trace", false),
- INIT_PARAM_DFLT(function_trace_start, "Cycle to start function trace", 0)
+ INIT_PARAM(icache, "L1 instruction cache object"),
+ INIT_PARAM(dcache, "L1 data cache object"),
+ INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
+ INIT_PARAM(width, "cpu width"),
+ INIT_PARAM(function_trace, "Enable function trace"),
+ INIT_PARAM(function_trace_start, "Cycle to start function trace")
END_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
CREATE_SIM_OBJECT(SimpleCPU)
{
- SimpleCPU *cpu;
#ifdef FULL_SYSTEM
if (mult != 1)
panic("processor clock multiplier must be 1\n");
+#endif
- cpu = new SimpleCPU(getInstanceName(), system,
- max_insts_any_thread, max_insts_all_threads,
- max_loads_any_thread, max_loads_all_threads,
- itb, dtb, mem,
- (icache) ? icache->getInterface() : NULL,
- (dcache) ? dcache->getInterface() : NULL,
- defer_registration,
- ticksPerSecond * mult,
- function_trace, function_trace_start);
-#else
-
- cpu = new SimpleCPU(getInstanceName(), workload,
- max_insts_any_thread, max_insts_all_threads,
- max_loads_any_thread, max_loads_all_threads,
- (icache) ? icache->getInterface() : NULL,
- (dcache) ? dcache->getInterface() : NULL,
- defer_registration,
- function_trace, function_trace_start);
+ SimpleCPU::Params *params = new SimpleCPU::Params();
+ params->name = getInstanceName();
+ params->numberOfThreads = 1;
+ params->max_insts_any_thread = max_insts_any_thread;
+ params->max_insts_all_threads = max_insts_all_threads;
+ params->max_loads_any_thread = max_loads_any_thread;
+ params->max_loads_all_threads = max_loads_all_threads;
+ params->deferRegistration = defer_registration;
+ params->freq = ticksPerSecond;
+ params->functionTrace = function_trace;
+ params->functionTraceStart = function_trace_start;
+ params->icache_interface = (icache) ? icache->getInterface() : NULL;
+ params->dcache_interface = (dcache) ? dcache->getInterface() : NULL;
+ params->width = width;
-#endif // FULL_SYSTEM
-
- cpu->setTickMultiplier(multiplier);
+#ifdef FULL_SYSTEM
+ params->itb = itb;
+ params->dtb = dtb;
+ params->mem = mem;
+ params->system = system;
+#else
+ params->process = workload;
+#endif
+ SimpleCPU *cpu = new SimpleCPU(params);
return cpu;
}
diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh
index 341a0da23..f245a7bba 100644
--- a/cpu/simple_cpu/simple_cpu.hh
+++ b/cpu/simple_cpu/simple_cpu.hh
@@ -26,15 +26,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __SIMPLE_CPU_HH__
-#define __SIMPLE_CPU_HH__
+#ifndef __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__
+#define __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__
-#include "cpu/base_cpu.hh"
-#include "sim/eventq.hh"
-#include "cpu/pc_event.hh"
#include "base/statistics.hh"
+#include "cpu/base_cpu.hh"
#include "cpu/exec_context.hh"
+#include "cpu/pc_event.hh"
+#include "cpu/sampling_cpu/sampling_cpu.hh"
#include "cpu/static_inst.hh"
+#include "sim/eventq.hh"
// forward declarations
#ifdef FULL_SYSTEM
@@ -69,9 +70,9 @@ class SimpleCPU : public BaseCPU
struct TickEvent : public Event
{
SimpleCPU *cpu;
- int multiplier;
+ int width;
- TickEvent(SimpleCPU *c);
+ TickEvent(SimpleCPU *c, int w);
void process();
const char *description();
};
@@ -94,20 +95,8 @@ class SimpleCPU : public BaseCPU
tickEvent.squash();
}
- public:
- void setTickMultiplier(int multiplier)
- {
- tickEvent.multiplier = multiplier;
- }
-
private:
Trace::InstRecord *traceData;
- template<typename T>
- void trace_data(T data) {
- if (traceData) {
- traceData->setData(data);
- }
- };
public:
//
@@ -117,6 +106,7 @@ class SimpleCPU : public BaseCPU
IcacheMissStall,
IcacheMissComplete,
DcacheMissStall,
+ DcacheMissSwitch,
SwitchedOut
};
@@ -134,36 +124,28 @@ class SimpleCPU : public BaseCPU
}
};
+ public:
+ struct Params : public BaseCPU::Params
+ {
+ MemInterface *icache_interface;
+ MemInterface *dcache_interface;
+ int width;
#ifdef FULL_SYSTEM
-
- SimpleCPU(const std::string &_name,
- System *_system,
- Counter max_insts_any_thread, Counter max_insts_all_threads,
- Counter max_loads_any_thread, Counter max_loads_all_threads,
- AlphaITB *itb, AlphaDTB *dtb, FunctionalMemory *mem,
- MemInterface *icache_interface, MemInterface *dcache_interface,
- bool _def_reg, Tick freq,
- bool _function_trace, Tick _function_trace_start);
-
+ AlphaITB *itb;
+ AlphaDTB *dtb;
+ FunctionalMemory *mem;
#else
-
- SimpleCPU(const std::string &_name, Process *_process,
- Counter max_insts_any_thread,
- Counter max_insts_all_threads,
- Counter max_loads_any_thread,
- Counter max_loads_all_threads,
- MemInterface *icache_interface, MemInterface *dcache_interface,
- bool _def_reg,
- bool _function_trace, Tick _function_trace_start);
-
+ Process *process;
#endif
-
+ };
+ SimpleCPU(Params *params);
virtual ~SimpleCPU();
+ public:
// execution context
ExecContext *xc;
- void switchOut();
+ void switchOut(SamplingCPU *s);
void takeOverFrom(BaseCPU *oldCPU);
#ifdef FULL_SYSTEM
@@ -184,6 +166,13 @@ class SimpleCPU : public BaseCPU
// Refcounted pointer to the one memory request.
MemReqPtr memReq;
+ // Pointer to the sampler that is telling us to switchover.
+ // Used to signal the completion of the pipe drain and schedule
+ // the next switchover
+ SamplingCPU *sampler;
+
+ StaticInstPtr<TheISA> curStaticInst;
+
class CacheCompletionEvent : public Event
{
private:
@@ -249,6 +238,11 @@ class SimpleCPU : public BaseCPU
template <class T>
Fault write(T data, Addr addr, unsigned flags, uint64_t *res);
+ // These functions are only used in CPU models that split
+ // effective address computation from the actual memory access.
+ void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); }
+ Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); }
+
void prefetch(Addr addr, unsigned flags)
{
// need to do this...
@@ -274,47 +268,47 @@ class SimpleCPU : public BaseCPU
// storage (which is pretty hard to imagine they would have reason
// to do).
- uint64_t readIntReg(StaticInst<TheISA> *si, int idx)
+ uint64_t readIntReg(const StaticInst<TheISA> *si, int idx)
{
return xc->readIntReg(si->srcRegIdx(idx));
}
- float readFloatRegSingle(StaticInst<TheISA> *si, int idx)
+ float readFloatRegSingle(const StaticInst<TheISA> *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return xc->readFloatRegSingle(reg_idx);
}
- double readFloatRegDouble(StaticInst<TheISA> *si, int idx)
+ double readFloatRegDouble(const StaticInst<TheISA> *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return xc->readFloatRegDouble(reg_idx);
}
- uint64_t readFloatRegInt(StaticInst<TheISA> *si, int idx)
+ uint64_t readFloatRegInt(const StaticInst<TheISA> *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return xc->readFloatRegInt(reg_idx);
}
- void setIntReg(StaticInst<TheISA> *si, int idx, uint64_t val)
+ void setIntReg(const StaticInst<TheISA> *si, int idx, uint64_t val)
{
xc->setIntReg(si->destRegIdx(idx), val);
}
- void setFloatRegSingle(StaticInst<TheISA> *si, int idx, float val)
+ void setFloatRegSingle(const StaticInst<TheISA> *si, int idx, float val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
xc->setFloatRegSingle(reg_idx, val);
}
- void setFloatRegDouble(StaticInst<TheISA> *si, int idx, double val)
+ void setFloatRegDouble(const StaticInst<TheISA> *si, int idx, double val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
xc->setFloatRegDouble(reg_idx, val);
}
- void setFloatRegInt(StaticInst<TheISA> *si, int idx, uint64_t val)
+ void setFloatRegInt(const StaticInst<TheISA> *si, int idx, uint64_t val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
xc->setFloatRegInt(reg_idx, val);
@@ -346,4 +340,4 @@ class SimpleCPU : public BaseCPU
ExecContext *xcBase() { return xc; }
};
-#endif // __SIMPLE_CPU_HH__
+#endif // __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__
diff --git a/cpu/static_inst.cc b/cpu/static_inst.cc
index 4cb45a818..d522dbf5a 100644
--- a/cpu/static_inst.cc
+++ b/cpu/static_inst.cc
@@ -68,7 +68,7 @@ StaticInst<AlphaISA>::nullStaticInstPtr;
template <class ISA>
bool
-StaticInst<ISA>::hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt)
+StaticInst<ISA>::hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt) const
{
if (isDirectCtrl()) {
tgt = branchTarget(pc);
@@ -85,4 +85,4 @@ StaticInst<ISA>::hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt)
// force instantiation of template function(s) above
-template StaticInst<AlphaISA>;
+template class StaticInst<AlphaISA>;
diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh
index 46b2e4b19..75bdcc286 100644
--- a/cpu/static_inst.hh
+++ b/cpu/static_inst.hh
@@ -285,13 +285,13 @@ class StaticInst : public StaticInstBase
* String representation of disassembly (lazily evaluated via
* disassemble()).
*/
- std::string *cachedDisassembly;
+ mutable std::string *cachedDisassembly;
/**
* Internal function to generate disassembly string.
*/
- virtual std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) = 0;
+ virtual std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
/// Constructor.
StaticInst(const char *_mnemonic, MachInst _machInst, OpClass __opClass)
@@ -311,23 +311,27 @@ class StaticInst : public StaticInstBase
/**
* Execute this instruction under SimpleCPU model.
*/
- virtual Fault execute(SimpleCPU *xc, Trace::InstRecord *traceData) = 0;
+ virtual Fault execute(SimpleCPU *xc,
+ Trace::InstRecord *traceData) const = 0;
- /**
+ /**
* Execute this instruction under InorderCPU model.
*/
- virtual Fault execute(InorderCPU *xc, Trace::InstRecord *traceData) = 0;
+ virtual Fault execute(InorderCPU *xc,
+ Trace::InstRecord *traceData) const = 0;
/**
* Execute this instruction under FastCPU model.
*/
- virtual Fault execute(FastCPU *xc, Trace::InstRecord *traceData) = 0;
+ virtual Fault execute(FastCPU *xc,
+ Trace::InstRecord *traceData) const = 0;
/**
* Execute this instruction under detailed FullCPU model.
*/
- virtual Fault execute(DynInst *xc, Trace::InstRecord *traceData) = 0;
+ virtual Fault execute(DynInst *xc,
+ Trace::InstRecord *traceData) const = 0;
/**
* Return the target address for a PC-relative branch.
@@ -357,7 +361,7 @@ class StaticInst : public StaticInstBase
* Return true if the instruction is a control transfer, and if so,
* return the target address as well.
*/
- bool hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt);
+ bool hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt) const;
/**
* Return string representation of disassembled instruction.
@@ -367,7 +371,7 @@ class StaticInst : public StaticInstBase
* should not be cached, this function should be overridden directly.
*/
virtual const std::string &disassemble(Addr pc,
- const SymbolTable *symtab = 0)
+ const SymbolTable *symtab = 0) const
{
if (!cachedDisassembly)
cachedDisassembly =
@@ -456,7 +460,7 @@ class StaticInstPtr : public RefCountingPtr<StaticInst<ISA> >
/// Convert to pointer to StaticInstBase class.
operator const StaticInstBasePtr()
{
- return get();
+ return this->get();
}
};
diff --git a/cpu/trace/opt_cpu.cc b/cpu/trace/opt_cpu.cc
index 77211e382..15b53d46e 100644
--- a/cpu/trace/opt_cpu.cc
+++ b/cpu/trace/opt_cpu.cc
@@ -48,7 +48,7 @@ OptCPU::OptCPU(const string &name,
int block_size,
int cache_size,
int _assoc)
- : BaseCPU(name, 1, true), tickEvent(this), trace(_trace),
+ : SimObject(name), tickEvent(this), trace(_trace),
numBlks(cache_size/block_size), assoc(_assoc), numSets(numBlks/assoc),
setMask(numSets - 1)
{
diff --git a/cpu/trace/opt_cpu.hh b/cpu/trace/opt_cpu.hh
index 847147b3c..7f6aa3e18 100644
--- a/cpu/trace/opt_cpu.hh
+++ b/cpu/trace/opt_cpu.hh
@@ -32,14 +32,14 @@
* trace to access a fully associative cache with optimal replacement.
*/
-#ifndef __OPT_CPU_HH__
-#define __OPT_CPU_HH__
+#ifndef __CPU_TRACE_OPT_CPU_HH__
+#define __CPU_TRACE_OPT_CPU_HH__
#include <vector>
-#include "cpu/base_cpu.hh"
#include "mem/mem_req.hh" // for MemReqPtr
#include "sim/eventq.hh" // for Event
+#include "sim/sim_object.hh"
// Forward Declaration
class MemTraceReader;
@@ -47,8 +47,9 @@ class MemTraceReader;
/**
* A CPU object to simulate a fully-associative cache with optimal replacement.
*/
-class OptCPU : public BaseCPU
+class OptCPU : public SimObject
{
+ private:
typedef int RefIndex;
typedef std::vector<RefIndex> L3Table;
@@ -219,4 +220,4 @@ class OptCPU : public BaseCPU
void tick();
};
-#endif
+#endif // __CPU_TRACE_OPT_CPU_HH__
diff --git a/cpu/trace/trace_cpu.cc b/cpu/trace/trace_cpu.cc
index f1160337a..1902d0be4 100644
--- a/cpu/trace/trace_cpu.cc
+++ b/cpu/trace/trace_cpu.cc
@@ -47,7 +47,7 @@ TraceCPU::TraceCPU(const string &name,
MemInterface *icache_interface,
MemInterface *dcache_interface,
MemTraceReader *data_trace)
- : BaseCPU(name, 4, true), icacheInterface(icache_interface),
+ : SimObject(name), icacheInterface(icache_interface),
dcacheInterface(dcache_interface),
dataTrace(data_trace), outstandingRequests(0), tickEvent(this)
{
diff --git a/cpu/trace/trace_cpu.hh b/cpu/trace/trace_cpu.hh
index 1711646a8..cdac4bb4f 100644
--- a/cpu/trace/trace_cpu.hh
+++ b/cpu/trace/trace_cpu.hh
@@ -32,14 +32,14 @@
* provided memory hierarchy.
*/
-#ifndef __TRACE_CPU_HH__
-#define __TRACE_CPU_HH__
+#ifndef __CPU_TRACE_TRACE_CPU_HH__
+#define __CPU_TRACE_TRACE_CPU_HH__
#include <string>
-#include "cpu/base_cpu.hh"
#include "mem/mem_req.hh" // for MemReqPtr
#include "sim/eventq.hh" // for Event
+#include "sim/sim_object.hh"
// Forward declaration.
class MemInterface;
@@ -48,8 +48,9 @@ class MemTraceReader;
/**
* A cpu object for running memory traces through a memory hierarchy.
*/
-class TraceCPU : public BaseCPU
+class TraceCPU : public SimObject
{
+ private:
/** Interface for instruction trace requests, if any. */
MemInterface *icacheInterface;
/** Interface for data trace requests, if any. */
@@ -133,5 +134,5 @@ class TraceCompleteEvent : public Event
virtual const char *description();
};
-#endif //__TRACE_CPU_HH__
+#endif // __CPU_TRACE_TRACE_CPU_HH__