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
This commit is contained in:
Kevin Lim
2006-10-09 22:59:56 -04:00
138 changed files with 2120 additions and 1244 deletions

View File

@@ -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:

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
/*

View File

@@ -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);

View File

@@ -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;

View File

@@ -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. */

View File

@@ -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);

View File

@@ -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

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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);

View File

@@ -1256,7 +1256,7 @@ BackEnd<Impl>::executeInsts()
// ++iewExecStoreInsts;
if (!(inst->req->flags & LOCKED)) {
if (!(inst->req->isLocked())) {
inst->setExecuted();
instToCommit(inst);

View File

@@ -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) {

View File

@@ -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. */

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();

View File

@@ -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 =

View File

@@ -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;
}

View File

@@ -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.

View File

@@ -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);
}
assert(data_write_pkt->result == Packet::Success);
if (do_access) {
data = htog(data);
pkt->reinitFromRequest();
pkt->dataStatic(&data);
if (res && data_write_req->getFlags() & LOCKED) {
*res = data_write_req->getScResult();
dcache_latency = dcachePort.sendAtomic(pkt);
dcache_access = true;
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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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:

View File

@@ -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]