summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpu/simple_cpu/simple_cpu.cc49
-rw-r--r--cpu/simple_cpu/simple_cpu.hh6
2 files changed, 42 insertions, 13 deletions
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
index d48f93663..4bd7ce638 100644
--- a/cpu/simple_cpu/simple_cpu.cc
+++ b/cpu/simple_cpu/simple_cpu.cc
@@ -103,7 +103,7 @@ SimpleCPU::CacheCompletionEvent::CacheCompletionEvent(SimpleCPU *_cpu)
void SimpleCPU::CacheCompletionEvent::process()
{
- cpu->processCacheCompletion();
+ cpu->processCacheCompletion(read);
}
const char *
@@ -414,21 +414,25 @@ template <class T>
Fault
SimpleCPU::read(Addr addr, T &data, unsigned flags)
{
- memReq->reset(addr, sizeof(T), flags);
+ Fault fault;
- // translate to physical address
- Fault fault = xc->translateDataReadReq(memReq);
-
- // do functional access
- if (fault == No_Fault)
+ if (status() == DcacheMissStall) {
+ //Just do the functional access
fault = xc->read(memReq, data);
- if (traceData) {
- traceData->setAddr(addr);
- if (fault == No_Fault)
- traceData->setData(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 = xc->translateDataReadReq(memReq);
+
// if we have a cache, do cache access too
if (fault == No_Fault && dcacheInterface) {
memReq->cmd = Read;
@@ -440,11 +444,25 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
// a miss. We really should add first-class support for this
// at some point.
if (result != MA_HIT && dcacheInterface->doEvents()) {
+ cacheCompletionEvent.read = true;
memReq->completionEvent = &cacheCompletionEvent;
+ //May later want to pass the staticinst as well, so it can call
+ //it independantly
lastDcacheStall = curTick;
unscheduleTickEvent();
_status = DcacheMissStall;
}
+ else {
+ // 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 (!dcacheInterface && (memReq->flags & UNCACHEABLE))
@@ -525,6 +543,7 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
// a miss. We really should add first-class support for this
// at some point.
if (result != MA_HIT && dcacheInterface->doEvents()) {
+ cacheCompletionEvent.read = false;
memReq->completionEvent = &cacheCompletionEvent;
lastDcacheStall = curTick;
unscheduleTickEvent();
@@ -596,7 +615,7 @@ Tick save_cycle = 0;
void
-SimpleCPU::processCacheCompletion()
+SimpleCPU::processCacheCompletion(bool read)
{
switch (status()) {
case IcacheMissStall:
@@ -606,6 +625,9 @@ SimpleCPU::processCacheCompletion()
break;
case DcacheMissStall:
dcacheStallCycles += curTick - lastDcacheStall;
+ if (read) {
+ globalsi->execute(this,traceData);
+ }
_status = Running;
scheduleTickEvent(1);
break;
@@ -729,6 +751,7 @@ SimpleCPU::tick()
// a miss. We really should add first-class support for this
// at some point.
if (result != MA_HIT && icacheInterface->doEvents()) {
+ cacheCompletionEvent.read = false;
memReq->completionEvent = &cacheCompletionEvent;
lastIcacheStall = curTick;
unscheduleTickEvent();
@@ -753,6 +776,8 @@ SimpleCPU::tick()
inst = htoa(inst);
StaticInstPtr<TheISA> si(inst);
+ globalsi = si;
+
traceData = Trace::getInstRecord(curTick, xc, this, si,
xc->regs.pc);
diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh
index 341a0da23..64e45d35e 100644
--- a/cpu/simple_cpu/simple_cpu.hh
+++ b/cpu/simple_cpu/simple_cpu.hh
@@ -184,6 +184,8 @@ class SimpleCPU : public BaseCPU
// Refcounted pointer to the one memory request.
MemReqPtr memReq;
+ StaticInstPtr<TheISA> globalsi;
+
class CacheCompletionEvent : public Event
{
private:
@@ -192,6 +194,8 @@ class SimpleCPU : public BaseCPU
public:
CacheCompletionEvent(SimpleCPU *_cpu);
+ bool read;
+
virtual void process();
virtual const char *description();
};
@@ -238,7 +242,7 @@ class SimpleCPU : public BaseCPU
Stats::Scalar<> dcacheStallCycles;
Counter lastDcacheStall;
- void processCacheCompletion();
+ void processCacheCompletion(bool read);
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);