summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/base.cc2
-rw-r--r--src/cpu/base.hh2
-rw-r--r--src/cpu/ozone/cpu.hh3
-rw-r--r--src/cpu/ozone/cpu_impl.hh30
-rw-r--r--src/cpu/ozone/front_end.hh9
-rw-r--r--src/cpu/ozone/front_end_impl.hh26
-rw-r--r--src/cpu/ozone/lw_back_end_impl.hh3
-rw-r--r--src/cpu/ozone/lw_lsq.hh4
-rw-r--r--src/cpu/ozone/lw_lsq_impl.hh6
-rw-r--r--src/cpu/simple/atomic.cc15
-rw-r--r--src/cpu/simple/atomic.hh2
-rw-r--r--src/cpu/simple/timing.cc67
-rw-r--r--src/cpu/simple/timing.hh10
13 files changed, 149 insertions, 30 deletions
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 55c04c498..40cec416b 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -237,7 +237,7 @@ BaseCPU::registerThreadContexts()
void
-BaseCPU::switchOut(Sampler *sampler)
+BaseCPU::switchOut()
{
panic("This CPU doesn't support sampling!");
}
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 43122f238..51f3bb905 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -148,7 +148,7 @@ class BaseCPU : public SimObject
/// Prepare for another CPU to take over execution. When it is
/// is ready (drained pipe) it signals the sampler.
- virtual void switchOut(Sampler *);
+ virtual void switchOut();
/// Take over execution from the given CPU. Used for warm-up and
/// sampling.
diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh
index cacc84786..f726ac99b 100644
--- a/src/cpu/ozone/cpu.hh
+++ b/src/cpu/ozone/cpu.hh
@@ -214,12 +214,11 @@ class OzoneCPU : public BaseCPU
uint64_t readNextNPC()
{
- panic("Alpha has no NextNPC!");
return 0;
}
void setNextNPC(uint64_t val)
- { panic("Alpha has no NextNPC!"); }
+ { }
public:
// ISA stuff:
diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh
index 2b25ad124..2cdc8a3da 100644
--- a/src/cpu/ozone/cpu_impl.hh
+++ b/src/cpu/ozone/cpu_impl.hh
@@ -201,7 +201,35 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
backEnd->renameTable.copyFrom(thread.renameTable);
#if !FULL_SYSTEM
-// pTable = p->pTable;
+ /* Use this port to for syscall emulation writes to memory. */
+ Port *mem_port;
+ TranslatingPort *trans_port;
+ trans_port = new TranslatingPort(csprintf("%s-%d-funcport",
+ name(), 0),
+ p->workload[0]->pTable,
+ false);
+ mem_port = p->mem->getPort("functional");
+ mem_port->setPeer(trans_port);
+ trans_port->setPeer(mem_port);
+ thread.setMemPort(trans_port);
+#else
+ Port *mem_port;
+ FunctionalPort *phys_port;
+ VirtualPort *virt_port;
+ phys_port = new FunctionalPort(csprintf("%s-%d-funcport",
+ name(), 0));
+ mem_port = system->physmem->getPort("functional");
+ mem_port->setPeer(phys_port);
+ phys_port->setPeer(mem_port);
+
+ virt_port = new VirtualPort(csprintf("%s-%d-vport",
+ name(), 0));
+ mem_port = system->physmem->getPort("functional");
+ mem_port->setPeer(virt_port);
+ virt_port->setPeer(mem_port);
+
+ thread.setPhysPort(phys_port);
+ thread.setVirtPort(virt_port);
#endif
lockFlag = 0;
diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh
index af310efc3..181609098 100644
--- a/src/cpu/ozone/front_end.hh
+++ b/src/cpu/ozone/front_end.hh
@@ -43,7 +43,7 @@
#include "sim/stats.hh"
class ThreadContext;
-class MemInterface;
+class MemObject;
template <class>
class OzoneThreadState;
class PageTable;
@@ -75,7 +75,7 @@ class FrontEnd
public:
/** Default constructor. */
IcachePort(FrontEnd<Impl> *_fe)
- : Port(_fe->name() + "-iport"), fe(_fe)
+ : fe(_fe)
{ }
protected:
@@ -105,8 +105,7 @@ class FrontEnd
std::string name() const;
- void setCPU(CPUType *cpu_ptr)
- { cpu = cpu_ptr; }
+ void setCPU(CPUType *cpu_ptr);
void setBackEnd(BackEnd *back_end_ptr)
{ backEnd = back_end_ptr; }
@@ -206,6 +205,8 @@ class FrontEnd
IcachePort icachePort;
+ MemObject *mem;
+
RequestPtr memReq;
/** Mask to get a cache block's address. */
diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh
index b1bc325c7..40042489d 100644
--- a/src/cpu/ozone/front_end_impl.hh
+++ b/src/cpu/ozone/front_end_impl.hh
@@ -28,6 +28,8 @@
* Authors: Kevin Lim
*/
+#include "config/use_checker.hh"
+
#include "arch/faults.hh"
#include "arch/isa_traits.hh"
#include "base/statistics.hh"
@@ -37,6 +39,10 @@
#include "mem/packet.hh"
#include "mem/request.hh"
+#if USE_CHECKER
+#include "cpu/checker/cpu.hh"
+#endif
+
using namespace TheISA;
template<class Impl>
@@ -83,6 +89,7 @@ template <class Impl>
FrontEnd<Impl>::FrontEnd(Params *params)
: branchPred(params),
icachePort(this),
+ mem(params->mem),
instBufferSize(0),
maxInstBufferSize(params->maxInstBufferSize),
width(params->frontEndWidth),
@@ -125,6 +132,25 @@ FrontEnd<Impl>::name() const
template <class Impl>
void
+FrontEnd<Impl>::setCPU(CPUType *cpu_ptr)
+{
+ cpu = cpu_ptr;
+
+ icachePort.setName(this->name() + "-iport");
+
+ Port *mem_dport = mem->getPort("");
+ icachePort.setPeer(mem_dport);
+ mem_dport->setPeer(&icachePort);
+
+#if USE_CHECKER
+ if (cpu->checker) {
+ cpu->checker->setIcachePort(&icachePort);
+ }
+#endif
+}
+
+template <class Impl>
+void
FrontEnd<Impl>::setCommBuffer(TimeBuffer<CommStruct> *_comm)
{
comm = _comm;
diff --git a/src/cpu/ozone/lw_back_end_impl.hh b/src/cpu/ozone/lw_back_end_impl.hh
index dcd7a0d7e..a73d3ee6e 100644
--- a/src/cpu/ozone/lw_back_end_impl.hh
+++ b/src/cpu/ozone/lw_back_end_impl.hh
@@ -142,7 +142,7 @@ LWBackEnd<Impl>::replayMemInst(DynInstPtr &inst)
template <class Impl>
LWBackEnd<Impl>::LWBackEnd(Params *params)
: d2i(5, 5), i2e(5, 5), e2c(5, 5), numInstsToWB(5, 5),
- trapSquash(false), tcSquash(false),
+ trapSquash(false), tcSquash(false), LSQ(params),
width(params->backEndWidth), exactFullStall(true)
{
numROBEntries = params->numROBEntries;
@@ -169,6 +169,7 @@ LWBackEnd<Impl>::LWBackEnd(Params *params)
LSQ.init(params, params->LQEntries, params->SQEntries, 0);
dispatchStatus = Running;
+ commitStatus = Running;
}
template <class Impl>
diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh
index e0c190134..c749e3aee 100644
--- a/src/cpu/ozone/lw_lsq.hh
+++ b/src/cpu/ozone/lw_lsq.hh
@@ -654,6 +654,10 @@ OzoneLWLSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
return NoFault;
}
+ if (req->getFlags() & LOCKED) {
+ cpu->lockFlag = true;
+ }
+
if (data_pkt->result != Packet::Success) {
DPRINTF(OzoneLSQ, "OzoneLSQ: D-cache miss!\n");
DPRINTF(Activity, "Activity: ld accessing mem miss [sn:%lli]\n",
diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh
index effb21728..a65a2a4d3 100644
--- a/src/cpu/ozone/lw_lsq_impl.hh
+++ b/src/cpu/ozone/lw_lsq_impl.hh
@@ -131,8 +131,8 @@ OzoneLWLSQ<Impl>::completeDataAccess(PacketPtr pkt)
template <class Impl>
OzoneLWLSQ<Impl>::OzoneLWLSQ()
- : loads(0), stores(0), storesToWB(0), stalled(false), isLoadBlocked(false),
- loadBlockedHandled(false)
+ : switchedOut(false), loads(0), stores(0), storesToWB(0), stalled(false),
+ isStoreBlocked(false), isLoadBlocked(false), loadBlockedHandled(false)
{
}
@@ -153,6 +153,8 @@ OzoneLWLSQ<Impl>::init(Params *params, unsigned maxLQEntries,
SQIndices.push(i);
}
+ mem = params->mem;
+
usedPorts = 0;
cachePorts = params->cachePorts;
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index ce28ba9c8..be6f421b3 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -145,8 +145,8 @@ AtomicSimpleCPU::~AtomicSimpleCPU()
void
AtomicSimpleCPU::serialize(ostream &os)
{
- BaseSimpleCPU::serialize(os);
SERIALIZE_ENUM(_status);
+ BaseSimpleCPU::serialize(os);
nameOut(os, csprintf("%s.tickEvent", name()));
tickEvent.serialize(os);
}
@@ -154,21 +154,18 @@ AtomicSimpleCPU::serialize(ostream &os)
void
AtomicSimpleCPU::unserialize(Checkpoint *cp, const string &section)
{
- BaseSimpleCPU::unserialize(cp, section);
UNSERIALIZE_ENUM(_status);
+ BaseSimpleCPU::unserialize(cp, section);
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
}
void
-AtomicSimpleCPU::switchOut(Sampler *s)
+AtomicSimpleCPU::switchOut()
{
- sampler = s;
- if (status() == Running) {
- _status = SwitchedOut;
+ assert(status() == Running || status() == Idle);
+ _status = SwitchedOut;
- tickEvent.squash();
- }
- sampler->signalSwitched();
+ tickEvent.squash();
}
diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index 7f4956da9..951a8da06 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -125,7 +125,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
- void switchOut(Sampler *s);
+ void switchOut();
void takeOverFrom(BaseCPU *oldCPU);
virtual void activateContext(int thread_num, int delay);
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index c99db8fbf..0729f9489 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -88,6 +88,8 @@ TimingSimpleCPU::TimingSimpleCPU(Params *p)
{
_status = Idle;
ifetch_pkt = dcache_pkt = NULL;
+ quiesceEvent = NULL;
+ state = SimObject::Timing;
}
@@ -98,25 +100,54 @@ TimingSimpleCPU::~TimingSimpleCPU()
void
TimingSimpleCPU::serialize(ostream &os)
{
- BaseSimpleCPU::serialize(os);
SERIALIZE_ENUM(_status);
+ BaseSimpleCPU::serialize(os);
}
void
TimingSimpleCPU::unserialize(Checkpoint *cp, const string &section)
{
- BaseSimpleCPU::unserialize(cp, section);
UNSERIALIZE_ENUM(_status);
+ BaseSimpleCPU::unserialize(cp, section);
+}
+
+bool
+TimingSimpleCPU::quiesce(Event *quiesce_event)
+{
+ // TimingSimpleCPU is ready to quiesce if it's not waiting for
+ // an access to complete.
+ if (status() == Idle || status() == Running || status() == SwitchedOut) {
+ DPRINTF(Config, "Ready to quiesce\n");
+ return false;
+ } else {
+ DPRINTF(Config, "Waiting to quiesce\n");
+ changeState(SimObject::Quiescing);
+ quiesceEvent = quiesce_event;
+ return true;
+ }
}
void
-TimingSimpleCPU::switchOut(Sampler *s)
+TimingSimpleCPU::resume()
{
- sampler = s;
- if (status() == Running) {
- _status = SwitchedOut;
+ if (_status != SwitchedOut && _status != Idle) {
+ Event *e =
+ new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, true);
+ e->schedule(curTick);
}
- sampler->signalSwitched();
+}
+
+void
+TimingSimpleCPU::setMemoryMode(State new_mode)
+{
+ assert(new_mode == SimObject::Timing);
+}
+
+void
+TimingSimpleCPU::switchOut()
+{
+ assert(status() == Running || status() == Idle);
+ _status = SwitchedOut;
}
@@ -383,11 +414,17 @@ TimingSimpleCPU::completeIfetch(Packet *pkt)
// instruction
assert(pkt->result == Packet::Success);
assert(_status == IcacheWaitResponse);
+
_status = Running;
delete pkt->req;
delete pkt;
+ if (getState() == SimObject::Quiescing) {
+ completeQuiesce();
+ return;
+ }
+
preExecute();
if (curStaticInst->isMemRef() && !curStaticInst->isDataPrefetch()) {
// load or store: just send to dcache
@@ -440,6 +477,15 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt)
assert(_status == DcacheWaitResponse);
_status = Running;
+ if (getState() == SimObject::Quiescing) {
+ completeQuiesce();
+
+ delete pkt->req;
+ delete pkt;
+
+ return;
+ }
+
Fault fault = curStaticInst->completeAcc(pkt, this, traceData);
delete pkt->req;
@@ -450,6 +496,13 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt)
}
+void
+TimingSimpleCPU::completeQuiesce()
+{
+ DPRINTF(Config, "Done quiescing\n");
+ changeState(SimObject::QuiescedTiming);
+ quiesceEvent->process();
+}
bool
TimingSimpleCPU::DcachePort::recvTiming(Packet *pkt)
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index ab0b2d2ca..d91144e4a 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -64,6 +64,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
Status status() const { return _status; }
+ Event *quiesceEvent;
+
private:
class CpuPort : public Port
@@ -131,7 +133,11 @@ class TimingSimpleCPU : public BaseSimpleCPU
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
- void switchOut(Sampler *s);
+ virtual bool quiesce(Event *quiesce_event);
+ virtual void resume();
+ virtual void setMemoryMode(State new_mode);
+
+ void switchOut();
void takeOverFrom(BaseCPU *oldCPU);
virtual void activateContext(int thread_num, int delay);
@@ -147,6 +153,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
void completeIfetch(Packet *);
void completeDataAccess(Packet *);
void advanceInst(Fault fault);
+ private:
+ void completeQuiesce();
};
#endif // __CPU_SIMPLE_TIMING_HH__