summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2006-10-09 22:59:56 -0400
committerKevin Lim <ktlim@umich.edu>2006-10-09 22:59:56 -0400
commitbdde892d668e17fb5a67de0e560a85b9092adf9e (patch)
tree3876a98dcd7f80aca7bf7e2153dbaa32c83a15b5 /src/cpu
parenta9ae6c8656dc233996c81cdeb6f5c8539442af95 (diff)
parent5448517da4cd13e3c8438850f04367d9614d686b (diff)
downloadgem5-bdde892d668e17fb5a67de0e560a85b9092adf9e.tar.xz
Merge ktlim@zizzer:/bk/newmem
into zamp.eecs.umich.edu:/z/ktlim2/clean/o3-merge/newmem src/cpu/memtest/memtest.cc: src/cpu/memtest/memtest.hh: src/cpu/simple/timing.hh: tests/configs/o3-timing-mp.py: Hand merge. --HG-- extra : convert_revision : a58cc439eb5e8f900d175ed8b5a85b6c8723e558
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/SConscript1
-rw-r--r--src/cpu/base.hh2
-rw-r--r--src/cpu/base_dyn_inst_impl.hh2
-rw-r--r--src/cpu/checker/cpu.cc8
-rw-r--r--src/cpu/memtest/memtest.cc115
-rw-r--r--src/cpu/memtest/memtest.hh18
-rw-r--r--src/cpu/o3/fetch.hh2
-rw-r--r--src/cpu/o3/fetch_impl.hh4
-rw-r--r--src/cpu/o3/lsq.hh2
-rw-r--r--src/cpu/o3/lsq_impl.hh2
-rw-r--r--src/cpu/o3/lsq_unit.hh4
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh6
-rw-r--r--src/cpu/ozone/back_end.hh4
-rw-r--r--src/cpu/ozone/back_end_impl.hh2
-rw-r--r--src/cpu/ozone/cpu.hh12
-rw-r--r--src/cpu/ozone/front_end.hh2
-rw-r--r--src/cpu/ozone/front_end_impl.hh4
-rw-r--r--src/cpu/ozone/inorder_back_end.hh18
-rw-r--r--src/cpu/ozone/lsq_unit.hh2
-rw-r--r--src/cpu/ozone/lsq_unit_impl.hh6
-rw-r--r--src/cpu/ozone/lw_lsq.hh6
-rw-r--r--src/cpu/ozone/lw_lsq_impl.hh12
-rw-r--r--src/cpu/simple/atomic.cc84
-rw-r--r--src/cpu/simple/atomic.hh4
-rw-r--r--src/cpu/simple/timing.cc107
-rw-r--r--src/cpu/simple/timing.hh3
-rw-r--r--src/cpu/simple_thread.hh6
27 files changed, 239 insertions, 199 deletions
diff --git a/src/cpu/SConscript b/src/cpu/SConscript
index 2bb9a2399..5771a7904 100644
--- a/src/cpu/SConscript
+++ b/src/cpu/SConscript
@@ -158,6 +158,7 @@ if 'O3CPU' in env['CPU_MODELS']:
o3/scoreboard.cc
o3/store_set.cc
''')
+ sources += Split('memtest/memtest.cc')
if env['USE_CHECKER']:
sources += Split('o3/checker_builder.cc')
else:
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index e02527371..75e0d86af 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -140,8 +140,8 @@ class BaseCPU : public MemObject
bool functionTrace;
Tick functionTraceStart;
System *system;
-#if FULL_SYSTEM
int cpu_id;
+#if FULL_SYSTEM
Tick profile;
#endif
Tick progress_interval;
diff --git a/src/cpu/base_dyn_inst_impl.hh b/src/cpu/base_dyn_inst_impl.hh
index f2109e88d..d6cdff5c5 100644
--- a/src/cpu/base_dyn_inst_impl.hh
+++ b/src/cpu/base_dyn_inst_impl.hh
@@ -193,7 +193,7 @@ BaseDynInst<Impl>::prefetch(Addr addr, unsigned flags)
// note this is a local, not BaseDynInst::fault
Fault trans_fault = cpu->translateDataReadReq(req);
- if (trans_fault == NoFault && !(req->flags & UNCACHEABLE)) {
+ if (trans_fault == NoFault && !(req->isUncacheable())) {
// It's a valid address to cacheable space. Record key MemReq
// parameters so we can generate another one just like it for
// the timing access without calling translate() again (which
diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc
index 1540a6b94..f6d56eef6 100644
--- a/src/cpu/checker/cpu.cc
+++ b/src/cpu/checker/cpu.cc
@@ -175,7 +175,7 @@ CheckerCPU::read(Addr addr, T &data, unsigned flags)
pkt->dataStatic(&data);
- if (!(memReq->getFlags() & UNCACHEABLE)) {
+ if (!(memReq->isUncacheable())) {
// Access memory to see if we have the same data
dcachePort->sendFunctional(pkt);
} else {
@@ -251,9 +251,9 @@ CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
// This is because the LSQ would have to be snooped in the CPU to
// verify this data.
if (unverifiedReq &&
- !(unverifiedReq->getFlags() & UNCACHEABLE) &&
- (!(unverifiedReq->getFlags() & LOCKED) ||
- ((unverifiedReq->getFlags() & LOCKED) &&
+ !(unverifiedReq->isUncacheable()) &&
+ (!(unverifiedReq->isLocked()) ||
+ ((unverifiedReq->isLocked()) &&
unverifiedReq->getScResult() == 1))) {
T inst_data;
/*
diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc
index e3a47f10a..127cad414 100644
--- a/src/cpu/memtest/memtest.cc
+++ b/src/cpu/memtest/memtest.cc
@@ -38,16 +38,19 @@
#include "base/misc.hh"
#include "base/statistics.hh"
-#include "cpu/simple_thread.hh"
+//#include "cpu/simple_thread.hh"
#include "cpu/memtest/memtest.hh"
//#include "mem/cache/base_cache.hh"
-#include "mem/physical.hh"
+//#include "mem/physical.hh"
#include "sim/builder.hh"
#include "sim/sim_events.hh"
#include "sim/stats.hh"
+#include "mem/packet.hh"
+#include "mem/request.hh"
+#include "mem/port.hh"
+#include "mem/mem_object.hh"
using namespace std;
-using namespace TheISA;
int TESTER_ALLOCATOR=0;
@@ -68,7 +71,8 @@ MemTest::CpuPort::recvAtomic(Packet *pkt)
void
MemTest::CpuPort::recvFunctional(Packet *pkt)
{
- memtest->completeRequest(pkt);
+ //Do nothing if we see one come through
+ return;
}
void
@@ -86,11 +90,10 @@ MemTest::CpuPort::recvRetry()
memtest->doRetry();
}
-
MemTest::MemTest(const string &name,
// MemInterface *_cache_interface,
- PhysicalMemory *main_mem,
- PhysicalMemory *check_mem,
+// PhysicalMemory *main_mem,
+// PhysicalMemory *check_mem,
unsigned _memorySize,
unsigned _percentReads,
// unsigned _percentCopies,
@@ -102,10 +105,11 @@ MemTest::MemTest(const string &name,
Counter _max_loads)
: MemObject(name),
tickEvent(this),
- cachePort("dcache", this),
+ cachePort("test", this),
+ funcPort("functional", this),
retryPkt(NULL),
- mainMem(main_mem),
- checkMem(check_mem),
+// mainMem(main_mem),
+// checkMem(check_mem),
size(_memorySize),
percentReads(_percentReads),
// percentCopies(_percentCopies),
@@ -119,7 +123,7 @@ MemTest::MemTest(const string &name,
vector<string> cmd;
cmd.push_back("/bin/ls");
vector<string> null_vec;
- thread = new SimpleThread(NULL, 0, NULL, 0, mainMem);
+ // thread = new SimpleThread(NULL, 0, NULL, 0, mainMem);
curTick = 0;
// Needs to be masked off once we know the block size.
@@ -134,16 +138,18 @@ MemTest::MemTest(const string &name,
tickEvent.schedule(0);
id = TESTER_ALLOCATOR++;
+ if (TESTER_ALLOCATOR > 8)
+ panic("False sharing memtester only allows up to 8 testers");
+
+ accessRetry = false;
}
Port *
MemTest::getPort(const std::string &if_name, int idx)
{
- // ***** NOTE TO RON: I'm not sure what it should do if these get ports
- // are called on it.
- if (if_name == "dcache_port")
- return &cachePort;
- else if (if_name == "icache_port")
+ if (if_name == "functional")
+ return &funcPort;
+ else if (if_name == "test")
return &cachePort;
else
panic("No Such Port\n");
@@ -157,29 +163,14 @@ MemTest::init()
blockAddrMask = blockSize - 1;
traceBlockAddr = blockAddr(traceBlockAddr);
- //setup data storage with interesting values
- uint8_t *data1 = new uint8_t[size];
- uint8_t *data2 = new uint8_t[size];
- uint8_t *data3 = new uint8_t[size];
- memset(data1, 1, size);
- memset(data2, 2, size);
- memset(data3, 3, size);
-
// set up intial memory contents here
- // ***** NOTE FOR RON: I'm not sure how to setup initial memory
- // contents. - Kevin
-/*
- mainMem->prot_write(baseAddr1, data1, size);
- checkMem->prot_write(baseAddr1, data1, size);
- mainMem->prot_write(baseAddr2, data2, size);
- checkMem->prot_write(baseAddr2, data2, size);
- mainMem->prot_write(uncacheAddr, data3, size);
- checkMem->prot_write(uncacheAddr, data3, size);
-*/
- delete [] data1;
- delete [] data2;
- delete [] data3;
+ cachePort.memsetBlob(baseAddr1, 1, size);
+ funcPort.memsetBlob(baseAddr1, 1, size);
+ cachePort.memsetBlob(baseAddr2, 2, size);
+ funcPort.memsetBlob(baseAddr2, 2, size);
+ cachePort.memsetBlob(uncacheAddr, 3, size);
+ funcPort.memsetBlob(uncacheAddr, 3, size);
}
static void
@@ -209,7 +200,7 @@ MemTest::completeRequest(Packet *pkt)
outstandingAddrs.erase(removeAddr);
switch (pkt->cmd) {
- case Packet::ReadReq:
+ case Packet::ReadResp:
if (memcmp(pkt_data, data, pkt->getSize()) != 0) {
cerr << name() << ": on read of 0x" << hex << req->getPaddr()
@@ -236,7 +227,7 @@ MemTest::completeRequest(Packet *pkt)
exitSimLoop("Maximum number of loads reached!");
break;
- case Packet::WriteReq:
+ case Packet::WriteResp:
numWritesStat++;
break;
/*
@@ -319,20 +310,14 @@ MemTest::tick()
//If we aren't doing copies, use id as offset, and do a false sharing
//mem tester
- // ***** NOTE FOR RON: We're not doing copies, but I'm not sure if this
- // code should be used.
-/*
- if (percentCopies == 0) {
- //We can eliminate the lower bits of the offset, and then use the id
- //to offset within the blks
- offset &= ~63; //Not the low order bits
- offset += id;
- access_size = 0;
- }
-*/
+ //We can eliminate the lower bits of the offset, and then use the id
+ //to offset within the blks
+ offset &= ~63; //Not the low order bits
+ offset += id;
+ access_size = 0;
Request *req = new Request();
- uint32_t flags = req->getFlags();
+ uint32_t flags = 0;
Addr paddr;
if (cacheable < percentUncacheable) {
@@ -341,11 +326,12 @@ MemTest::tick()
} else {
paddr = ((base) ? baseAddr1 : baseAddr2) + offset;
}
- // bool probe = (random() % 2 == 1) && !req->isUncacheable();
+ //bool probe = (random() % 2 == 1) && !req->isUncacheable();
bool probe = false;
paddr &= ~((1 << access_size) - 1);
req->setPhys(paddr, 1 << access_size, flags);
+ req->setThreadContext(id,0);
uint8_t *result = new uint8_t[8];
@@ -359,7 +345,8 @@ MemTest::tick()
else outstandingAddrs.insert(paddr);
// ***** NOTE FOR RON: I'm not sure how to access checkMem. - Kevin
-// checkMem->access(Read, req->getPaddr(), result, req->size);
+ funcPort.readBlob(req->getPaddr(), result, req->getSize());
+
if (blockAddr(paddr) == traceBlockAddr) {
cerr << name()
<< ": initiating read "
@@ -377,10 +364,8 @@ MemTest::tick()
pkt->senderState = state;
if (probe) {
- // ***** NOTE FOR RON: Send functional access? It used to
- // be a probeAndUpdate access. - Kevin
cachePort.sendFunctional(pkt);
-// completeRequest(pkt, result);
+ completeRequest(pkt);
} else {
// req->completionEvent = new MemCompleteEvent(req, result, this);
if (!cachePort.sendTiming(pkt)) {
@@ -397,8 +382,6 @@ MemTest::tick()
if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) return;
else outstandingAddrs.insert(paddr);
- // ***** NOTE FOR RON: Not sure how to access memory.
-// checkMem->access(Write, req->paddr, req->data, req->size);
/*
if (blockAddr(req->getPaddr()) == traceBlockAddr) {
cerr << name() << ": initiating write "
@@ -419,9 +402,9 @@ MemTest::tick()
MemTestSenderState *state = new MemTestSenderState(result);
pkt->senderState = state;
+ funcPort.writeBlob(req->getPaddr(), pkt_data, req->getSize());
+
if (probe) {
- // ***** NOTE FOR RON: Send functional access? It used to
- // be a probe access. - Kevin
cachePort.sendFunctional(pkt);
// completeRequest(req, NULL);
} else {
@@ -490,8 +473,8 @@ MemTest::doRetry()
BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest)
// SimObjectParam<BaseCache *> cache;
- SimObjectParam<PhysicalMemory *> main_mem;
- SimObjectParam<PhysicalMemory *> check_mem;
+// SimObjectParam<PhysicalMemory *> main_mem;
+// SimObjectParam<PhysicalMemory *> check_mem;
Param<unsigned> memory_size;
Param<unsigned> percent_reads;
// Param<unsigned> percent_copies;
@@ -508,8 +491,8 @@ END_DECLARE_SIM_OBJECT_PARAMS(MemTest)
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(main_mem, "hierarchical memory"),
+// INIT_PARAM(check_mem, "check memory"),
INIT_PARAM(memory_size, "memory size"),
INIT_PARAM(percent_reads, "target read percentage"),
// INIT_PARAM(percent_copies, "target copy percentage"),
@@ -527,8 +510,8 @@ END_INIT_SIM_OBJECT_PARAMS(MemTest)
CREATE_SIM_OBJECT(MemTest)
{
- return new MemTest(getInstanceName(), /*cache->getInterface(),*/ main_mem,
- check_mem, memory_size, percent_reads, /*percent_copies,*/
+ return new MemTest(getInstanceName(), /*cache->getInterface(),*/ /*main_mem,*/
+ /*check_mem,*/ memory_size, percent_reads, /*percent_copies,*/
percent_uncacheable, progress_interval,
percent_source_unaligned, percent_dest_unaligned,
trace_addr, max_loads);
diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh
index a0e58126b..87ecc6de3 100644
--- a/src/cpu/memtest/memtest.hh
+++ b/src/cpu/memtest/memtest.hh
@@ -41,17 +41,18 @@
#include "sim/sim_exit.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"
+#include "mem/mem_object.hh"
+#include "mem/port.hh"
-class PhysicalMemory;
-class ThreadContext;
+class Packet;
class MemTest : public MemObject
{
public:
MemTest(const std::string &name,
// MemInterface *_cache_interface,
- PhysicalMemory *main_mem,
- PhysicalMemory *check_mem,
+// PhysicalMemory *main_mem,
+// PhysicalMemory *check_mem,
unsigned _memorySize,
unsigned _percentReads,
// unsigned _percentCopies,
@@ -112,10 +113,11 @@ class MemTest : public MemObject
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); }
+ { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); }
};
CpuPort cachePort;
+ CpuPort funcPort;
class MemTestSenderState : public Packet::SenderState
{
@@ -132,9 +134,9 @@ class MemTest : public MemObject
// Request *dataReq;
Packet *retryPkt;
// MemInterface *cacheInterface;
- PhysicalMemory *mainMem;
- PhysicalMemory *checkMem;
- SimpleThread *thread;
+// PhysicalMemory *mainMem;
+// PhysicalMemory *checkMem;
+// SimpleThread *thread;
bool accessRetry;
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index 1a2ca32a4..280bf0e71 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -96,7 +96,7 @@ class DefaultFetch
/** Returns the address ranges of this device. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); }
+ { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); }
/** Timing version of receive. Handles setting fetch to the
* proper status to start fetching. */
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index a01784f8f..32210f1cd 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -63,7 +63,7 @@ template<class Impl>
void
DefaultFetch<Impl>::IcachePort::recvFunctional(PacketPtr pkt)
{
- panic("DefaultFetch doesn't expect recvFunctional callback!");
+ warn("Default fetch doesn't update it's state from a functional call.");
}
template<class Impl>
@@ -599,7 +599,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
if (fault == NoFault) {
#if 0
if (cpu->system->memctrl->badaddr(memReq[tid]->paddr) ||
- memReq[tid]->flags & UNCACHEABLE) {
+ memReq[tid]->isUncacheable()) {
DPRINTF(Fetch, "Fetch: Bad address %#x (hopefully on a "
"misspeculating path)!",
memReq[tid]->paddr);
diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh
index 190734dc2..6b12d75b4 100644
--- a/src/cpu/o3/lsq.hh
+++ b/src/cpu/o3/lsq.hh
@@ -311,7 +311,7 @@ class LSQ {
/** Returns the address ranges of this device. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); }
+ { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); }
/** Timing version of receive. Handles writing back and
* completing the load or store that has returned from
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index 2bbab71f0..7b7d1eb8e 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -46,7 +46,7 @@ template <class Impl>
void
LSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
{
- panic("O3CPU doesn't expect recvFunctional callback!");
+ warn("O3CPU doesn't update things on a recvFunctional.");
}
template <class Impl>
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index 7b65ef556..11a02e7c7 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -492,7 +492,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
// A bit of a hackish way to get uncached accesses to work only if they're
// at the head of the LSQ and are ready to commit (at the head of the ROB
// too).
- if (req->getFlags() & UNCACHEABLE &&
+ if (req->isUncacheable() &&
(load_idx != loadHead || !load_inst->isAtCommit())) {
iewStage->rescheduleMemInst(load_inst);
++lsqRescheduledLoads;
@@ -509,7 +509,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
load_idx, store_idx, storeHead, req->getPaddr());
#if FULL_SYSTEM
- if (req->getFlags() & LOCKED) {
+ if (req->isLocked()) {
cpu->lockAddr = req->getPaddr();
cpu->lockFlag = true;
}
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index dc1a99d87..3f9db912f 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -416,7 +416,7 @@ LSQUnit<Impl>::executeLoad(DynInstPtr &inst)
// realizes there is activity.
// Mark it as executed unless it is an uncached load that
// needs to hit the head of commit.
- if (!(inst->req->getFlags() & UNCACHEABLE) || inst->isAtCommit()) {
+ if (!(inst->req->isUncacheable()) || inst->isAtCommit()) {
inst->setExecuted();
}
iewStage->instToCommit(inst);
@@ -613,8 +613,8 @@ LSQUnit<Impl>::writebackStores()
inst->seqNum);
// @todo: Remove this SC hack once the memory system handles it.
- if (req->getFlags() & LOCKED) {
- if (req->getFlags() & UNCACHEABLE) {
+ if (req->isLocked()) {
+ if (req->isUncacheable()) {
req->setScResult(2);
} else {
if (cpu->lockFlag) {
diff --git a/src/cpu/ozone/back_end.hh b/src/cpu/ozone/back_end.hh
index 9bab6a964..8debd277d 100644
--- a/src/cpu/ozone/back_end.hh
+++ b/src/cpu/ozone/back_end.hh
@@ -493,7 +493,7 @@ BackEnd<Impl>::read(RequestPtr req, T &data, int load_idx)
}
*/
/*
- if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
+ if (!dcacheInterface && (memReq->isUncacheable()))
recordEvent("Uncached Read");
*/
return LSQ.read(req, data, load_idx);
@@ -534,7 +534,7 @@ BackEnd<Impl>::write(RequestPtr req, T &data, int store_idx)
*res = memReq->result;
*/
/*
- if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
+ if (!dcacheInterface && (memReq->isUncacheable()))
recordEvent("Uncached Write");
*/
return LSQ.write(req, data, store_idx);
diff --git a/src/cpu/ozone/back_end_impl.hh b/src/cpu/ozone/back_end_impl.hh
index ac3218c02..4078699fe 100644
--- a/src/cpu/ozone/back_end_impl.hh
+++ b/src/cpu/ozone/back_end_impl.hh
@@ -1256,7 +1256,7 @@ BackEnd<Impl>::executeInsts()
// ++iewExecStoreInsts;
- if (!(inst->req->flags & LOCKED)) {
+ if (!(inst->req->isLocked())) {
inst->setExecuted();
instToCommit(inst);
diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh
index 8c5be9424..70ec1d101 100644
--- a/src/cpu/ozone/cpu.hh
+++ b/src/cpu/ozone/cpu.hh
@@ -455,12 +455,12 @@ class OzoneCPU : public BaseCPU
{
#if 0
#if FULL_SYSTEM && defined(TARGET_ALPHA)
- if (req->flags & LOCKED) {
+ if (req->isLocked()) {
req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
}
#endif
- if (req->flags & LOCKED) {
+ if (req->isLocked()) {
lockAddrList.insert(req->paddr);
lockFlag = true;
}
@@ -489,10 +489,10 @@ class OzoneCPU : public BaseCPU
ExecContext *xc;
// If this is a store conditional, act appropriately
- if (req->flags & LOCKED) {
+ if (req->isLocked()) {
xc = req->xc;
- if (req->flags & UNCACHEABLE) {
+ if (req->isUncacheable()) {
// Don't update result register (see stq_c in isa_desc)
req->result = 2;
xc->setStCondFailures(0);//Needed? [RGD]
@@ -532,8 +532,8 @@ class OzoneCPU : public BaseCPU
#endif
- if (req->flags & LOCKED) {
- if (req->flags & UNCACHEABLE) {
+ if (req->isLocked()) {
+ if (req->isUncacheable()) {
req->result = 2;
} else {
if (this->lockFlag) {
diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh
index 5ffd3666e..59cf9785c 100644
--- a/src/cpu/ozone/front_end.hh
+++ b/src/cpu/ozone/front_end.hh
@@ -92,7 +92,7 @@ class FrontEnd
/** Returns the address ranges of this device. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); }
+ { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); }
/** Timing version of receive. Handles setting fetch to the
* proper status to start fetching. */
diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh
index d34716de6..c814ff9c7 100644
--- a/src/cpu/ozone/front_end_impl.hh
+++ b/src/cpu/ozone/front_end_impl.hh
@@ -59,7 +59,7 @@ template<class Impl>
void
FrontEnd<Impl>::IcachePort::recvFunctional(PacketPtr pkt)
{
- panic("FrontEnd doesn't expect recvFunctional callback!");
+ warn("FrontEnd doesn't update state from functional calls");
}
template<class Impl>
@@ -493,7 +493,7 @@ FrontEnd<Impl>::fetchCacheLine()
if (fault == NoFault) {
#if 0
if (cpu->system->memctrl->badaddr(memReq->paddr) ||
- memReq->flags & UNCACHEABLE) {
+ memReq->isUncacheable()) {
DPRINTF(FE, "Fetch: Bad address %#x (hopefully on a "
"misspeculating path!",
memReq->paddr);
diff --git a/src/cpu/ozone/inorder_back_end.hh b/src/cpu/ozone/inorder_back_end.hh
index ffdba2f6c..76eef6fad 100644
--- a/src/cpu/ozone/inorder_back_end.hh
+++ b/src/cpu/ozone/inorder_back_end.hh
@@ -231,7 +231,7 @@ InorderBackEnd<Impl>::read(Addr addr, T &data, unsigned flags)
}
}
/*
- if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
+ if (!dcacheInterface && (memReq->isUncacheable()))
recordEvent("Uncached Read");
*/
return fault;
@@ -243,7 +243,7 @@ Fault
InorderBackEnd<Impl>::read(MemReqPtr &req, T &data)
{
#if FULL_SYSTEM && defined(TARGET_ALPHA)
- if (req->flags & LOCKED) {
+ if (req->isLocked()) {
req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
}
@@ -291,7 +291,7 @@ InorderBackEnd<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res)
if (res && (fault == NoFault))
*res = memReq->result;
/*
- if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
+ if (!dcacheInterface && (memReq->isUncacheable()))
recordEvent("Uncached Write");
*/
return fault;
@@ -306,10 +306,10 @@ InorderBackEnd<Impl>::write(MemReqPtr &req, T &data)
ExecContext *xc;
// If this is a store conditional, act appropriately
- if (req->flags & LOCKED) {
+ if (req->isLocked()) {
xc = req->xc;
- if (req->flags & UNCACHEABLE) {
+ if (req->isUncacheable()) {
// Don't update result register (see stq_c in isa_desc)
req->result = 2;
xc->setStCondFailures(0);//Needed? [RGD]
@@ -391,7 +391,7 @@ InorderBackEnd<Impl>::read(MemReqPtr &req, T &data, int load_idx)
}
/*
- if (!dcacheInterface && (req->flags & UNCACHEABLE))
+ if (!dcacheInterface && (req->isUncacheable()))
recordEvent("Uncached Read");
*/
return NoFault;
@@ -455,8 +455,8 @@ InorderBackEnd<Impl>::write(MemReqPtr &req, T &data, int store_idx)
}
}
/*
- if (req->flags & LOCKED) {
- if (req->flags & UNCACHEABLE) {
+ if (req->isLocked()) {
+ if (req->isUncacheable()) {
// Don't update result register (see stq_c in isa_desc)
req->result = 2;
} else {
@@ -469,7 +469,7 @@ InorderBackEnd<Impl>::write(MemReqPtr &req, T &data, int store_idx)
*res = req->result;
*/
/*
- if (!dcacheInterface && (req->flags & UNCACHEABLE))
+ if (!dcacheInterface && (req->isUncacheable()))
recordEvent("Uncached Write");
*/
return NoFault;
diff --git a/src/cpu/ozone/lsq_unit.hh b/src/cpu/ozone/lsq_unit.hh
index 38c1c09a2..056c79521 100644
--- a/src/cpu/ozone/lsq_unit.hh
+++ b/src/cpu/ozone/lsq_unit.hh
@@ -426,7 +426,7 @@ OzoneLSQ<Impl>::read(MemReqPtr &req, T &data, int load_idx)
// at the head of the LSQ and are ready to commit (at the head of the ROB
// too).
// @todo: Fix uncached accesses.
- if (req->flags & UNCACHEABLE &&
+ if (req->isUncacheable() &&
(load_idx != loadHead || !loadQueue[load_idx]->readyToCommit())) {
return TheISA::genMachineCheckFault();
diff --git a/src/cpu/ozone/lsq_unit_impl.hh b/src/cpu/ozone/lsq_unit_impl.hh
index ee0804036..c46eb90be 100644
--- a/src/cpu/ozone/lsq_unit_impl.hh
+++ b/src/cpu/ozone/lsq_unit_impl.hh
@@ -577,7 +577,7 @@ OzoneLSQ<Impl>::writebackStores()
MemAccessResult result = dcacheInterface->access(req);
//@todo temp fix for LL/SC (works fine for 1 CPU)
- if (req->flags & LOCKED) {
+ if (req->isLocked()) {
req->result=1;
panic("LL/SC! oh no no support!!!");
}
@@ -596,7 +596,7 @@ OzoneLSQ<Impl>::writebackStores()
Event *wb = NULL;
/*
typename IEW::LdWritebackEvent *wb = NULL;
- if (req->flags & LOCKED) {
+ if (req->isLocked()) {
// Stx_C does not generate a system port transaction.
req->result=0;
wb = new typename IEW::LdWritebackEvent(storeQueue[storeWBIdx].inst,
@@ -630,7 +630,7 @@ OzoneLSQ<Impl>::writebackStores()
// DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n",
// storeQueue[storeWBIdx].inst->seqNum);
- if (req->flags & LOCKED) {
+ if (req->isLocked()) {
// Stx_C does not generate a system port transaction.
req->result=1;
typename BackEnd::LdWritebackEvent *wb =
diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh
index 6640a9f34..9b93ce74f 100644
--- a/src/cpu/ozone/lw_lsq.hh
+++ b/src/cpu/ozone/lw_lsq.hh
@@ -260,7 +260,7 @@ class OzoneLWLSQ {
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); }
+ { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1); }
virtual bool recvTiming(PacketPtr pkt);
@@ -507,7 +507,7 @@ OzoneLWLSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
// at the head of the LSQ and are ready to commit (at the head of the ROB
// too).
// @todo: Fix uncached accesses.
- if (req->getFlags() & UNCACHEABLE &&
+ if (req->isUncacheable() &&
(inst != loadQueue.back() || !inst->isAtCommit())) {
DPRINTF(OzoneLSQ, "[sn:%lli] Uncached load and not head of "
"commit/LSQ!\n",
@@ -659,7 +659,7 @@ OzoneLWLSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
return NoFault;
}
- if (req->getFlags() & LOCKED) {
+ if (req->isLocked()) {
cpu->lockFlag = true;
}
diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh
index 4c96ad149..e523712da 100644
--- a/src/cpu/ozone/lw_lsq_impl.hh
+++ b/src/cpu/ozone/lw_lsq_impl.hh
@@ -72,7 +72,7 @@ template <class Impl>
void
OzoneLWLSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
{
- panic("O3CPU doesn't expect recvFunctional callback!");
+ warn("O3CPU doesn't update things on a recvFunctional");
}
template <class Impl>
@@ -394,7 +394,7 @@ OzoneLWLSQ<Impl>::executeLoad(DynInstPtr &inst)
// Actually probably want the oldest faulting load
if (load_fault != NoFault) {
DPRINTF(OzoneLSQ, "Load [sn:%lli] has a fault\n", inst->seqNum);
- if (!(inst->req->getFlags() & UNCACHEABLE && !inst->isAtCommit())) {
+ if (!(inst->req->isUncacheable() && !inst->isAtCommit())) {
inst->setExecuted();
}
// Maybe just set it as can commit here, although that might cause
@@ -605,8 +605,8 @@ OzoneLWLSQ<Impl>::writebackStores()
inst->seqNum);
// @todo: Remove this SC hack once the memory system handles it.
- if (req->getFlags() & LOCKED) {
- if (req->getFlags() & UNCACHEABLE) {
+ if (req->isLocked()) {
+ if (req->isUncacheable()) {
req->setScResult(2);
} else {
if (cpu->lockFlag) {
@@ -663,7 +663,7 @@ OzoneLWLSQ<Impl>::writebackStores()
if (result != MA_HIT && dcacheInterface->doEvents()) {
store_event->miss = true;
typename BackEnd::LdWritebackEvent *wb = NULL;
- if (req->flags & LOCKED) {
+ if (req->isLocked()) {
wb = new typename BackEnd::LdWritebackEvent(inst,
be);
store_event->wbEvent = wb;
@@ -690,7 +690,7 @@ OzoneLWLSQ<Impl>::writebackStores()
// DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n",
// inst->seqNum);
- if (req->flags & LOCKED) {
+ if (req->isLocked()) {
// Stx_C does not generate a system port
// transaction in the 21264, but that might be
// hard to accomplish in this model.
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 88698bfee..490be20ae 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -28,6 +28,7 @@
* Authors: Steve Reinhardt
*/
+#include "arch/locked_mem.hh"
#include "arch/utility.hh"
#include "cpu/exetrace.hh"
#include "cpu/simple/atomic.hh"
@@ -93,7 +94,7 @@ AtomicSimpleCPU::init()
bool
AtomicSimpleCPU::CpuPort::recvTiming(Packet *pkt)
{
- panic("AtomicSimpleCPU doesn't expect recvAtomic callback!");
+ panic("AtomicSimpleCPU doesn't expect recvTiming callback!");
return true;
}
@@ -107,7 +108,8 @@ AtomicSimpleCPU::CpuPort::recvAtomic(Packet *pkt)
void
AtomicSimpleCPU::CpuPort::recvFunctional(Packet *pkt)
{
- panic("AtomicSimpleCPU doesn't expect recvFunctional callback!");
+ //No internal storage to update, just return
+ return;
}
void
@@ -133,20 +135,19 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
{
_status = Idle;
- // @todo fix me and get the real cpu id & thread number!!!
ifetch_req = new Request();
- ifetch_req->setThreadContext(0,0); //Need CPU/Thread IDS HERE
+ ifetch_req->setThreadContext(p->cpu_id, 0); // Add thread ID if we add MT
ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
ifetch_pkt->dataStatic(&inst);
data_read_req = new Request();
- data_read_req->setThreadContext(0,0); //Need CPU/Thread IDS HERE
+ data_read_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too
data_read_pkt = new Packet(data_read_req, Packet::ReadReq,
Packet::Broadcast);
data_read_pkt->dataStatic(&dataReg);
data_write_req = new Request();
- data_write_req->setThreadContext(0,0); //Need CPU/Thread IDS HERE
+ data_write_req->setThreadContext(p->cpu_id, 0); // Add thread ID here too
data_write_pkt = new Packet(data_write_req, Packet::WriteReq,
Packet::Broadcast);
}
@@ -161,6 +162,8 @@ AtomicSimpleCPU::serialize(ostream &os)
{
SimObject::State so_state = SimObject::getState();
SERIALIZE_ENUM(so_state);
+ Status _status = status();
+ SERIALIZE_ENUM(_status);
BaseSimpleCPU::serialize(os);
nameOut(os, csprintf("%s.tickEvent", name()));
tickEvent.serialize(os);
@@ -171,6 +174,7 @@ AtomicSimpleCPU::unserialize(Checkpoint *cp, const string &section)
{
SimObject::State so_state;
UNSERIALIZE_ENUM(so_state);
+ UNSERIALIZE_ENUM(_status);
BaseSimpleCPU::unserialize(cp, section);
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
}
@@ -253,29 +257,36 @@ template <class T>
Fault
AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
{
- data_read_req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
+ // use the CPU's statically allocated read request and packet objects
+ Request *req = data_read_req;
+ Packet *pkt = data_read_pkt;
+
+ req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
if (traceData) {
traceData->setAddr(addr);
}
// translate to physical address
- Fault fault = thread->translateDataReadReq(data_read_req);
+ Fault fault = thread->translateDataReadReq(req);
// Now do the access.
if (fault == NoFault) {
- data_read_pkt->reinitFromRequest();
+ pkt->reinitFromRequest();
- dcache_latency = dcachePort.sendAtomic(data_read_pkt);
+ dcache_latency = dcachePort.sendAtomic(pkt);
dcache_access = true;
- assert(data_read_pkt->result == Packet::Success);
- data = data_read_pkt->get<T>();
+ assert(pkt->result == Packet::Success);
+ data = pkt->get<T>();
+ if (req->isLocked()) {
+ TheISA::handleLockedRead(thread, req);
+ }
}
// This will need a new way to tell if it has a dcache attached.
- if (data_read_req->getFlags() & UNCACHEABLE)
+ if (req->isUncacheable())
recordEvent("Uncached Read");
return fault;
@@ -328,33 +339,52 @@ template <class T>
Fault
AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
- data_write_req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
+ // use the CPU's statically allocated write request and packet objects
+ Request *req = data_write_req;
+ Packet *pkt = data_write_pkt;
+
+ req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
if (traceData) {
traceData->setAddr(addr);
}
// translate to physical address
- Fault fault = thread->translateDataWriteReq(data_write_req);
+ Fault fault = thread->translateDataWriteReq(req);
// Now do the access.
if (fault == NoFault) {
- data = htog(data);
- data_write_pkt->reinitFromRequest();
- data_write_pkt->dataStatic(&data);
+ bool do_access = true; // flag to suppress cache access
- dcache_latency = dcachePort.sendAtomic(data_write_pkt);
- dcache_access = true;
+ if (req->isLocked()) {
+ do_access = TheISA::handleLockedWrite(thread, req);
+ }
+
+ if (do_access) {
+ data = htog(data);
+ pkt->reinitFromRequest();
+ pkt->dataStatic(&data);
- assert(data_write_pkt->result == Packet::Success);
+ dcache_latency = dcachePort.sendAtomic(pkt);
+ dcache_access = true;
- if (res && data_write_req->getFlags() & LOCKED) {
- *res = data_write_req->getScResult();
+ assert(pkt->result == Packet::Success);
+ }
+
+ if (req->isLocked()) {
+ uint64_t scResult = req->getScResult();
+ if (scResult != 0) {
+ // clear failure counter
+ thread->setStCondFailures(0);
+ }
+ if (res) {
+ *res = req->getScResult();
+ }
}
}
// This will need a new way to tell if it's hooked up to a cache or not.
- if (data_write_req->getFlags() & UNCACHEABLE)
+ if (req->isUncacheable())
recordEvent("Uncached Write");
// If the write needs to have a fault on the access, consider calling
@@ -467,11 +497,11 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AtomicSimpleCPU)
Param<Tick> progress_interval;
SimObjectParam<MemObject *> mem;
SimObjectParam<System *> system;
+ Param<int> cpu_id;
#if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb;
SimObjectParam<AlphaDTB *> dtb;
- Param<int> cpu_id;
Param<Tick> profile;
#else
SimObjectParam<Process *> workload;
@@ -500,11 +530,11 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AtomicSimpleCPU)
INIT_PARAM(progress_interval, "Progress interval"),
INIT_PARAM(mem, "memory"),
INIT_PARAM(system, "system object"),
+ INIT_PARAM(cpu_id, "processor ID"),
#if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
INIT_PARAM(dtb, "Data TLB"),
- INIT_PARAM(cpu_id, "processor ID"),
INIT_PARAM(profile, ""),
#else
INIT_PARAM(workload, "processes to run"),
@@ -538,11 +568,11 @@ CREATE_SIM_OBJECT(AtomicSimpleCPU)
params->simulate_stalls = simulate_stalls;
params->mem = mem;
params->system = system;
+ params->cpu_id = cpu_id;
#if FULL_SYSTEM
params->itb = itb;
params->dtb = dtb;
- params->cpu_id = cpu_id;
params->profile = profile;
#else
params->process = workload;
diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index b602af558..52afd76ef 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -104,9 +104,9 @@ class AtomicSimpleCPU : public BaseSimpleCPU
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); }
- };
+ { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); }
+ };
CpuPort icachePort;
CpuPort dcachePort;
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index 9bed5dab1..33f673cbc 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -28,6 +28,7 @@
* Authors: Steve Reinhardt
*/
+#include "arch/locked_mem.hh"
#include "arch/utility.hh"
#include "cpu/exetrace.hh"
#include "cpu/simple/timing.hh"
@@ -73,7 +74,8 @@ TimingSimpleCPU::CpuPort::recvAtomic(Packet *pkt)
void
TimingSimpleCPU::CpuPort::recvFunctional(Packet *pkt)
{
- panic("TimingSimpleCPU doesn't expect recvFunctional callback!");
+ //No internal storage to update, jusst return
+ return;
}
void
@@ -94,7 +96,8 @@ TimingSimpleCPU::CpuPort::TickEvent::schedule(Packet *_pkt, Tick t)
}
TimingSimpleCPU::TimingSimpleCPU(Params *p)
- : BaseSimpleCPU(p), icachePort(this, p->clock), dcachePort(this, p->clock)
+ : BaseSimpleCPU(p), icachePort(this, p->clock), dcachePort(this, p->clock),
+ cpu_id(p->cpu_id)
{
_status = Idle;
ifetch_pkt = dcache_pkt = NULL;
@@ -251,35 +254,35 @@ template <class T>
Fault
TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
{
- // need to fill in CPU & thread IDs here
- Request *data_read_req = new Request();
- data_read_req->setThreadContext(0,0); //Need CPU/Thread IDS HERE
- data_read_req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
+ Request *req =
+ new Request(/* asid */ 0, addr, sizeof(T), flags, thread->readPC(),
+ cpu_id, /* thread ID */ 0);
if (traceData) {
- traceData->setAddr(data_read_req->getVaddr());
+ traceData->setAddr(req->getVaddr());
}
// translate to physical address
- Fault fault = thread->translateDataReadReq(data_read_req);
+ Fault fault = thread->translateDataReadReq(req);
// Now do the access.
if (fault == NoFault) {
- Packet *data_read_pkt =
- new Packet(data_read_req, Packet::ReadReq, Packet::Broadcast);
- data_read_pkt->dataDynamic<T>(new T);
+ Packet *pkt =
+ new Packet(req, Packet::ReadReq, Packet::Broadcast);
+ pkt->dataDynamic<T>(new T);
- if (!dcachePort.sendTiming(data_read_pkt)) {
+ if (!dcachePort.sendTiming(pkt)) {
_status = DcacheRetry;
- dcache_pkt = data_read_pkt;
+ dcache_pkt = pkt;
} else {
_status = DcacheWaitResponse;
+ // memory system takes ownership of packet
dcache_pkt = NULL;
}
}
// This will need a new way to tell if it has a dcache attached.
- if (data_read_req->getFlags() & UNCACHEABLE)
+ if (req->isUncacheable())
recordEvent("Uncached Read");
return fault;
@@ -332,31 +335,39 @@ template <class T>
Fault
TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
- // need to fill in CPU & thread IDs here
- Request *data_write_req = new Request();
- data_write_req->setThreadContext(0,0); //Need CPU/Thread IDS HERE
- data_write_req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
+ Request *req =
+ new Request(/* asid */ 0, addr, sizeof(T), flags, thread->readPC(),
+ cpu_id, /* thread ID */ 0);
// translate to physical address
- Fault fault = thread->translateDataWriteReq(data_write_req);
+ Fault fault = thread->translateDataWriteReq(req);
+
// Now do the access.
if (fault == NoFault) {
- Packet *data_write_pkt =
- new Packet(data_write_req, Packet::WriteReq, Packet::Broadcast);
- data_write_pkt->allocate();
- data_write_pkt->set(data);
+ assert(dcache_pkt == NULL);
+ dcache_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
+ dcache_pkt->allocate();
+ dcache_pkt->set(data);
- if (!dcachePort.sendTiming(data_write_pkt)) {
- _status = DcacheRetry;
- dcache_pkt = data_write_pkt;
- } else {
- _status = DcacheWaitResponse;
- dcache_pkt = NULL;
+ bool do_access = true; // flag to suppress cache access
+
+ if (req->isLocked()) {
+ do_access = TheISA::handleLockedWrite(thread, req);
+ }
+
+ if (do_access) {
+ if (!dcachePort.sendTiming(dcache_pkt)) {
+ _status = DcacheRetry;
+ } else {
+ _status = DcacheWaitResponse;
+ // memory system takes ownership of packet
+ dcache_pkt = NULL;
+ }
}
}
// This will need a new way to tell if it's hooked up to a cache or not.
- if (data_write_req->getFlags() & UNCACHEABLE)
+ if (req->isUncacheable())
recordEvent("Uncached Write");
// If the write needs to have a fault on the access, consider calling
@@ -416,9 +427,8 @@ TimingSimpleCPU::fetch()
{
checkForInterrupts();
- // need to fill in CPU & thread IDs here
Request *ifetch_req = new Request();
- ifetch_req->setThreadContext(0,0); //Need CPU/Thread IDS HERE
+ ifetch_req->setThreadContext(cpu_id, /* thread ID */ 0);
Fault fault = setupFetchRequest(ifetch_req);
ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
@@ -483,12 +493,20 @@ TimingSimpleCPU::completeIfetch(Packet *pkt)
if (curStaticInst->isMemRef() && !curStaticInst->isDataPrefetch()) {
// load or store: just send to dcache
Fault fault = curStaticInst->initiateAcc(this, traceData);
- if (fault == NoFault) {
- // successfully initiated access: instruction will
- // complete in dcache response callback
- assert(_status == DcacheWaitResponse);
+ if (_status != Running) {
+ // instruction will complete in dcache response callback
+ assert(_status == DcacheWaitResponse || _status == DcacheRetry);
+ assert(fault == NoFault);
} else {
- // fault: complete now to invoke fault handler
+ if (fault == NoFault) {
+ // early fail on store conditional: complete now
+ assert(dcache_pkt != NULL);
+ fault = curStaticInst->completeAcc(dcache_pkt, this,
+ traceData);
+ delete dcache_pkt->req;
+ delete dcache_pkt;
+ dcache_pkt = NULL;
+ }
postExecute();
advanceInst(fault);
}
@@ -509,8 +527,7 @@ TimingSimpleCPU::IcachePort::ITickEvent::process()
bool
TimingSimpleCPU::IcachePort::recvTiming(Packet *pkt)
{
- // These next few lines could be replaced with something faster
- // who knows what though
+ // delay processing of returned data until next CPU clock edge
Tick time = pkt->req->getTime();
while (time < curTick)
time += lat;
@@ -551,6 +568,10 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt)
Fault fault = curStaticInst->completeAcc(pkt, this, traceData);
+ if (pkt->isRead() && pkt->req->isLocked()) {
+ TheISA::handleLockedRead(thread, pkt->req);
+ }
+
delete pkt->req;
delete pkt;
@@ -578,6 +599,7 @@ TimingSimpleCPU::completeDrain()
bool
TimingSimpleCPU::DcachePort::recvTiming(Packet *pkt)
{
+ // delay processing of returned data until next CPU clock edge
Tick time = pkt->req->getTime();
while (time < curTick)
time += lat;
@@ -606,6 +628,7 @@ TimingSimpleCPU::DcachePort::recvRetry()
Packet *tmp = cpu->dcache_pkt;
if (sendTiming(tmp)) {
cpu->_status = DcacheWaitResponse;
+ // memory system takes ownership of packet
cpu->dcache_pkt = NULL;
}
}
@@ -624,11 +647,11 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TimingSimpleCPU)
Param<Tick> progress_interval;
SimObjectParam<MemObject *> mem;
SimObjectParam<System *> system;
+ Param<int> cpu_id;
#if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb;
SimObjectParam<AlphaDTB *> dtb;
- Param<int> cpu_id;
Param<Tick> profile;
#else
SimObjectParam<Process *> workload;
@@ -657,11 +680,11 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TimingSimpleCPU)
INIT_PARAM(progress_interval, "Progress interval"),
INIT_PARAM(mem, "memory"),
INIT_PARAM(system, "system object"),
+ INIT_PARAM(cpu_id, "processor ID"),
#if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
INIT_PARAM(dtb, "Data TLB"),
- INIT_PARAM(cpu_id, "processor ID"),
INIT_PARAM(profile, ""),
#else
INIT_PARAM(workload, "processes to run"),
@@ -693,11 +716,11 @@ CREATE_SIM_OBJECT(TimingSimpleCPU)
params->functionTraceStart = function_trace_start;
params->mem = mem;
params->system = system;
+ params->cpu_id = cpu_id;
#if FULL_SYSTEM
params->itb = itb;
params->dtb = dtb;
- params->cpu_id = cpu_id;
params->profile = profile;
#else
params->process = workload;
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index 8a20d1cfe..988ddeded 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -92,7 +92,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); }
+ { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); }
struct TickEvent : public Event
{
@@ -166,6 +166,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
Packet *ifetch_pkt;
Packet *dcache_pkt;
+ int cpu_id;
Tick previousTick;
public:
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index 242cfd0e1..6fa6500bd 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -237,7 +237,7 @@ class SimpleThread : public ThreadState
Fault read(RequestPtr &req, T &data)
{
#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
- if (req->flags & LOCKED) {
+ if (req->isLocked()) {
req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
}
@@ -256,10 +256,10 @@ class SimpleThread : public ThreadState
ExecContext *xc;
// If this is a store conditional, act appropriately
- if (req->flags & LOCKED) {
+ if (req->isLocked()) {
xc = req->xc;
- if (req->flags & UNCACHEABLE) {
+ if (req->isUncacheable()) {
// Don't update result register (see stq_c in isa_desc)
req->result = 2;
xc->setStCondFailures(0);//Needed? [RGD]