summaryrefslogtreecommitdiff
path: root/src/cpu/simple
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-08-04 20:27:23 -0700
committerGabe Black <gblack@eecs.umich.edu>2007-08-04 20:27:23 -0700
commitcae8d20633c0f43fdae23576adfb894284a7ee86 (patch)
treee9e232684d7fc024900d8a07d6b8a3add1f52e92 /src/cpu/simple
parent30e777a5d3829975266ecccac965d2297a5f4985 (diff)
parentdf015f17a45b18302565c43d3790d787e1b54c42 (diff)
downloadgem5-cae8d20633c0f43fdae23576adfb894284a7ee86.tar.xz
Merge with head.
--HG-- extra : convert_revision : 3edb9f03353b18b4c9f062bccf11e79cfb3c15f2
Diffstat (limited to 'src/cpu/simple')
-rw-r--r--src/cpu/simple/atomic.cc105
-rw-r--r--src/cpu/simple/atomic.hh10
-rw-r--r--src/cpu/simple/base.hh3
-rw-r--r--src/cpu/simple/timing.cc42
-rw-r--r--src/cpu/simple/timing.hh6
5 files changed, 76 insertions, 90 deletions
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 888ef4960..704b65f36 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -57,7 +57,7 @@ AtomicSimpleCPU::TickEvent::process()
const char *
AtomicSimpleCPU::TickEvent::description()
{
- return "AtomicSimpleCPU tick event";
+ return "AtomicSimpleCPU tick";
}
Port *
@@ -148,23 +148,9 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
icachePort.snoopRangeSent = false;
dcachePort.snoopRangeSent = false;
- ifetch_req = new Request();
- ifetch_req->setThreadContext(p->cpu_id, 0); // Add thread ID if we add MT
- ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast);
- ifetch_pkt->dataStatic(&inst);
-
- data_read_req = new Request();
- data_read_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too
- data_read_pkt = new Packet(data_read_req, MemCmd::ReadReq,
- Packet::Broadcast);
- data_read_pkt->dataStatic(&dataReg);
-
- data_write_req = new Request();
- data_write_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too
- data_write_pkt = new Packet(data_write_req, MemCmd::WriteReq,
- Packet::Broadcast);
- data_swap_pkt = new Packet(data_write_req, MemCmd::SwapReq,
- Packet::Broadcast);
+ ifetch_req.setThreadContext(p->cpu_id, 0); // Add thread ID if we add MT
+ data_read_req.setThreadContext(p->cpu_id, 0); // Add thread ID here too
+ data_write_req.setThreadContext(p->cpu_id, 0); // Add thread ID here too
}
@@ -197,6 +183,7 @@ AtomicSimpleCPU::unserialize(Checkpoint *cp, const string &section)
void
AtomicSimpleCPU::resume()
{
+ DPRINTF(SimpleCPU, "Resume\n");
if (_status != SwitchedOut && _status != Idle) {
assert(system->getMemoryMode() == Enums::atomic);
@@ -245,6 +232,8 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
void
AtomicSimpleCPU::activateContext(int thread_num, int delay)
{
+ DPRINTF(SimpleCPU, "ActivateContext %d (%d cycles)\n", thread_num, delay);
+
assert(thread_num == 0);
assert(thread);
@@ -262,6 +251,8 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay)
void
AtomicSimpleCPU::suspendContext(int thread_num)
{
+ DPRINTF(SimpleCPU, "SuspendContext %d\n", thread_num);
+
assert(thread_num == 0);
assert(thread);
@@ -282,9 +273,7 @@ Fault
AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
{
// use the CPU's statically allocated read request and packet objects
- Request *req = data_read_req;
- PacketPtr pkt = data_read_pkt;
-
+ Request *req = &data_read_req;
req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
if (traceData) {
@@ -296,19 +285,20 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
// Now do the access.
if (fault == NoFault) {
- pkt->reinitFromRequest();
+ Packet pkt =
+ Packet(req,
+ req->isLocked() ? MemCmd::LoadLockedReq : MemCmd::ReadReq,
+ Packet::Broadcast);
+ pkt.dataStatic(&data);
if (req->isMmapedIpr())
- dcache_latency = TheISA::handleIprRead(thread->getTC(),pkt);
+ dcache_latency = TheISA::handleIprRead(thread->getTC(), &pkt);
else
- dcache_latency = dcachePort.sendAtomic(pkt);
+ dcache_latency = dcachePort.sendAtomic(&pkt);
dcache_access = true;
-#if !defined(NDEBUG)
- if (pkt->result != Packet::Success)
- panic("Unable to find responder for address pa = %#X va = %#X\n",
- pkt->req->getPaddr(), pkt->req->getVaddr());
-#endif
- data = pkt->get<T>();
+ assert(!pkt.isError());
+
+ data = gtoh(data);
if (req->isLocked()) {
TheISA::handleLockedRead(thread, req);
@@ -378,16 +368,9 @@ Fault
AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
// use the CPU's statically allocated write request and packet objects
- Request *req = data_write_req;
- PacketPtr pkt;
-
+ Request *req = &data_write_req;
req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
- if (req->isSwap())
- pkt = data_swap_pkt;
- else
- pkt = data_write_pkt;
-
if (traceData) {
traceData->setAddr(addr);
}
@@ -397,40 +380,40 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
// Now do the access.
if (fault == NoFault) {
+ MemCmd cmd = MemCmd::WriteReq; // default
bool do_access = true; // flag to suppress cache access
if (req->isLocked()) {
+ cmd = MemCmd::StoreCondReq;
do_access = TheISA::handleLockedWrite(thread, req);
+ } else if (req->isSwap()) {
+ cmd = MemCmd::SwapReq;
+ if (req->isCondSwap()) {
+ assert(res);
+ req->setExtraData(*res);
+ }
}
- if (req->isCondSwap()) {
- assert(res);
- req->setExtraData(*res);
- }
-
if (do_access) {
- pkt->reinitFromRequest();
- pkt->dataStatic(&data);
+ Packet pkt = Packet(req, cmd, Packet::Broadcast);
+ pkt.dataStatic(&data);
if (req->isMmapedIpr()) {
- dcache_latency = TheISA::handleIprWrite(thread->getTC(), pkt);
+ dcache_latency = TheISA::handleIprWrite(thread->getTC(), &pkt);
} else {
data = htog(data);
- dcache_latency = dcachePort.sendAtomic(pkt);
+ dcache_latency = dcachePort.sendAtomic(&pkt);
}
dcache_access = true;
+ assert(!pkt.isError());
-#if !defined(NDEBUG)
- if (pkt->result != Packet::Success)
- panic("Unable to find responder for address pa = %#X va = %#X\n",
- pkt->req->getPaddr(), pkt->req->getVaddr());
-#endif
+ if (req->isSwap()) {
+ assert(res);
+ *res = pkt.get<T>();
+ }
}
- if (req->isSwap()) {
- assert(res);
- *res = pkt->get<T>();
- } else if (res) {
+ if (res && !req->isSwap()) {
*res = req->getExtraData();
}
}
@@ -505,6 +488,8 @@ AtomicSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
void
AtomicSimpleCPU::tick()
{
+ DPRINTF(SimpleCPU, "Tick\n");
+
Tick latency = cycles(1); // instruction takes one cycle by default
for (int i = 0; i < width; ++i) {
@@ -513,7 +498,7 @@ AtomicSimpleCPU::tick()
if (!curStaticInst || !curStaticInst->isDelayedCommit())
checkForInterrupts();
- Fault fault = setupFetchRequest(ifetch_req);
+ Fault fault = setupFetchRequest(&ifetch_req);
if (fault == NoFault) {
Tick icache_latency = 0;
@@ -524,9 +509,11 @@ AtomicSimpleCPU::tick()
//if(predecoder.needMoreBytes())
//{
icache_access = true;
- ifetch_pkt->reinitFromRequest();
+ Packet ifetch_pkt = Packet(&ifetch_req, MemCmd::ReadReq,
+ Packet::Broadcast);
+ ifetch_pkt.dataStatic(&inst);
- icache_latency = icachePort.sendAtomic(ifetch_pkt);
+ icache_latency = icachePort.sendAtomic(&ifetch_pkt);
// ifetch_req is initialized to read the instruction directly
// into the CPU object's inst field.
//}
diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index b127e3791..28e883b24 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -121,13 +121,9 @@ class AtomicSimpleCPU : public BaseSimpleCPU
};
DcachePort dcachePort;
- Request *ifetch_req;
- PacketPtr ifetch_pkt;
- Request *data_read_req;
- PacketPtr data_read_pkt;
- Request *data_write_req;
- PacketPtr data_write_pkt;
- PacketPtr data_swap_pkt;
+ Request ifetch_req;
+ Request data_read_req;
+ Request data_write_req;
bool dcache_access;
Tick dcache_latency;
diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh
index 243167db0..0550aa036 100644
--- a/src/cpu/simple/base.hh
+++ b/src/cpu/simple/base.hh
@@ -131,9 +131,6 @@ class BaseSimpleCPU : public BaseCPU
// The predecoder
TheISA::Predecoder predecoder;
- // Static data storage
- TheISA::LargestRead dataReg;
-
StaticInstPtr curStaticInst;
StaticInstPtr curMacroStaticInst;
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index 855aaab59..a70ca7c75 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -260,7 +260,10 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
// Now do the access.
if (fault == NoFault) {
PacketPtr pkt =
- new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
+ new Packet(req,
+ (req->isLocked() ?
+ MemCmd::LoadLockedReq : MemCmd::ReadReq),
+ Packet::Broadcast);
pkt->dataDynamic<T>(new T);
if (!dcachePort.sendTiming(pkt)) {
@@ -350,23 +353,26 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
// Now do the access.
if (fault == NoFault) {
- assert(dcache_pkt == NULL);
- if (req->isSwap())
- dcache_pkt = new Packet(req, MemCmd::SwapReq, Packet::Broadcast);
- else
- dcache_pkt = new Packet(req, MemCmd::WriteReq, Packet::Broadcast);
- dcache_pkt->allocate();
- dcache_pkt->set(data);
-
+ MemCmd cmd = MemCmd::WriteReq; // default
bool do_access = true; // flag to suppress cache access
if (req->isLocked()) {
+ cmd = MemCmd::StoreCondReq;
do_access = TheISA::handleLockedWrite(thread, req);
+ } else if (req->isSwap()) {
+ cmd = MemCmd::SwapReq;
+ if (req->isCondSwap()) {
+ assert(res);
+ req->setExtraData(*res);
+ }
}
- if (req->isCondSwap()) {
- assert(res);
- req->setExtraData(*res);
- }
+
+ // Note: need to allocate dcache_pkt even if do_access is
+ // false, as it's used unconditionally to call completeAcc().
+ assert(dcache_pkt == NULL);
+ dcache_pkt = new Packet(req, cmd, Packet::Broadcast);
+ dcache_pkt->allocate();
+ dcache_pkt->set(data);
if (do_access) {
if (!dcachePort.sendTiming(dcache_pkt)) {
@@ -501,7 +507,7 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt)
{
// received a response from the icache: execute the received
// instruction
- assert(pkt->result == Packet::Success);
+ assert(!pkt->isError());
assert(_status == IcacheWaitResponse);
_status = Running;
@@ -569,7 +575,7 @@ TimingSimpleCPU::IcachePort::recvTiming(PacketPtr pkt)
return true;
}
- else if (pkt->result == Packet::Nacked) {
+ else if (pkt->wasNacked()) {
assert(cpu->_status == IcacheWaitResponse);
pkt->reinitNacked();
if (!sendTiming(pkt)) {
@@ -600,7 +606,7 @@ TimingSimpleCPU::completeDataAccess(PacketPtr pkt)
{
// received a response from the dcache: complete the load or store
// instruction
- assert(pkt->result == Packet::Success);
+ assert(!pkt->isError());
assert(_status == DcacheWaitResponse);
_status = Running;
@@ -609,7 +615,7 @@ TimingSimpleCPU::completeDataAccess(PacketPtr pkt)
Fault fault = curStaticInst->completeAcc(pkt, this, traceData);
- if (pkt->isRead() && pkt->req->isLocked()) {
+ if (pkt->isRead() && pkt->isLocked()) {
TheISA::handleLockedRead(thread, pkt->req);
}
@@ -663,7 +669,7 @@ TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
return true;
}
- else if (pkt->result == Packet::Nacked) {
+ else if (pkt->wasNacked()) {
assert(cpu->_status == DcacheWaitResponse);
pkt->reinitNacked();
if (!sendTiming(pkt)) {
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index 39958bfb6..ba194b3fa 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -101,7 +101,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
TickEvent(TimingSimpleCPU *_cpu)
:Event(&mainEventQueue), cpu(_cpu) {}
- const char *description() { return "Timing CPU clock event"; }
+ const char *description() { return "Timing CPU tick"; }
void schedule(PacketPtr _pkt, Tick t);
};
@@ -127,7 +127,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
ITickEvent(TimingSimpleCPU *_cpu)
: TickEvent(_cpu) {}
void process();
- const char *description() { return "Timing CPU clock event"; }
+ const char *description() { return "Timing CPU icache tick"; }
};
ITickEvent tickEvent;
@@ -155,7 +155,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
DTickEvent(TimingSimpleCPU *_cpu)
: TickEvent(_cpu) {}
void process();
- const char *description() { return "Timing CPU clock event"; }
+ const char *description() { return "Timing CPU dcache tick"; }
};
DTickEvent tickEvent;