MEM: Separate queries for snooping and address ranges
This patch simplifies the address-range determination mechanism and also unifies the naming across ports and devices. It further splits the queries for determining if a port is snooping and what address ranges it responds to (aiming towards a separation of cache-maintenance ports and pure memory-mapped ports). Default behaviours are such that most ports do not have to define isSnooping, and master ports need not implement getAddrRanges.
This commit is contained in:
@@ -527,23 +527,6 @@ BaseCPU::CpuPort::recvFunctional(PacketPtr pkt)
|
||||
}
|
||||
|
||||
void
|
||||
BaseCPU::CpuPort::recvStatusChange(Status status)
|
||||
BaseCPU::CpuPort::recvRangeChange()
|
||||
{
|
||||
if (status == RangeChange) {
|
||||
if (!snoopRangeSent) {
|
||||
snoopRangeSent = true;
|
||||
sendStatusChange(Port::RangeChange);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
panic("BaseCPU doesn't expect recvStatusChange callback!");
|
||||
}
|
||||
|
||||
void
|
||||
BaseCPU::CpuPort::getDeviceAddressRanges(AddrRangeList& resp,
|
||||
bool& snoop)
|
||||
{
|
||||
resp.clear();
|
||||
snoop = false;
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ class BaseCPU : public MemObject
|
||||
* @param _name structural owner of this port
|
||||
*/
|
||||
CpuPort(const std::string& _name, MemObject* _owner) :
|
||||
Port(_name, _owner), snoopRangeSent(false)
|
||||
Port(_name, _owner)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
@@ -139,22 +139,7 @@ class BaseCPU : public MemObject
|
||||
|
||||
void recvFunctional(PacketPtr pkt);
|
||||
|
||||
void recvStatusChange(Status status);
|
||||
|
||||
/**
|
||||
* Add CPU ports are master ports and do not respond to any
|
||||
* address ranges. Note that the LSQ snoops for specific ISAs
|
||||
* and thus has to override this method.
|
||||
*
|
||||
* @param resp list of ranges this port responds to
|
||||
* @param snoop indicating if the port snoops or not
|
||||
*/
|
||||
virtual void getDeviceAddressRanges(AddrRangeList& resp,
|
||||
bool& snoop);
|
||||
|
||||
private:
|
||||
|
||||
bool snoopRangeSent;
|
||||
void recvRangeChange();
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -82,17 +82,8 @@ CacheUnit::CachePort::recvFunctional(PacketPtr pkt)
|
||||
}
|
||||
|
||||
void
|
||||
CacheUnit::CachePort::recvStatusChange(Status status)
|
||||
CacheUnit::CachePort::recvRangeChange()
|
||||
{
|
||||
if (status == RangeChange) {
|
||||
if (!snoopRangeSent) {
|
||||
snoopRangeSent = true;
|
||||
sendStatusChange(Port::RangeChange);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
panic("CacheUnit::CachePort doesn't expect recvStatusChange callback!");
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -90,11 +90,9 @@ class CacheUnit : public Resource
|
||||
CachePort(CacheUnit *_cachePortUnit)
|
||||
: Port(_cachePortUnit->name() + "-cache-port",
|
||||
(MemObject*)_cachePortUnit->cpu),
|
||||
cachePortUnit(_cachePortUnit), snoopRangeSent(false)
|
||||
cachePortUnit(_cachePortUnit)
|
||||
{ }
|
||||
|
||||
bool snoopRangeSent;
|
||||
|
||||
protected:
|
||||
/** Atomic version of receive. Panics. */
|
||||
Tick recvAtomic(PacketPtr pkt);
|
||||
@@ -102,13 +100,8 @@ class CacheUnit : public Resource
|
||||
/** Functional version of receive.*/
|
||||
void recvFunctional(PacketPtr pkt);
|
||||
|
||||
/** Receives status change. Other than range changing, panics. */
|
||||
void recvStatusChange(Status status);
|
||||
|
||||
/** Returns the address ranges of this device. */
|
||||
void getDeviceAddressRanges(AddrRangeList &resp,
|
||||
bool &snoop)
|
||||
{ resp.clear(); snoop = true; }
|
||||
/** Receives range changes. */
|
||||
void recvRangeChange();
|
||||
|
||||
/** Timing version of receive */
|
||||
bool recvTiming(PacketPtr pkt);
|
||||
|
||||
@@ -186,12 +186,10 @@ class FullO3CPU : public BaseO3CPU
|
||||
* As this CPU requires snooping to maintain the load store queue
|
||||
* change the behaviour from the base CPU port.
|
||||
*
|
||||
* @param resp list of ranges this port responds to
|
||||
* @param snoop indicating if the port snoops or not
|
||||
* @return true since we have to snoop
|
||||
*/
|
||||
virtual void getDeviceAddressRanges(AddrRangeList& resp,
|
||||
bool& snoop)
|
||||
{ resp.clear(); snoop = true; }
|
||||
virtual bool isSnooping()
|
||||
{ return true; }
|
||||
};
|
||||
|
||||
class TickEvent : public Event
|
||||
|
||||
@@ -87,13 +87,8 @@ class FrontEnd
|
||||
/** Functional version of receive. Panics. */
|
||||
virtual void recvFunctional(PacketPtr pkt);
|
||||
|
||||
/** Receives status change. Other than range changing, panics. */
|
||||
virtual void recvStatusChange(Status status);
|
||||
|
||||
/** Returns the address ranges of this device. */
|
||||
virtual void getDeviceAddressRanges(AddrRangeList &resp,
|
||||
bool &snoop)
|
||||
{ resp.clear(); snoop = true; }
|
||||
/** Receives range change. */
|
||||
virtual void recvRangeChange();
|
||||
|
||||
/** Timing version of receive. Handles setting fetch to the
|
||||
* proper status to start fetching. */
|
||||
|
||||
@@ -64,12 +64,8 @@ FrontEnd<Impl>::IcachePort::recvFunctional(PacketPtr pkt)
|
||||
|
||||
template<class Impl>
|
||||
void
|
||||
FrontEnd<Impl>::IcachePort::recvStatusChange(Status status)
|
||||
FrontEnd<Impl>::IcachePort::recvRangeChange()
|
||||
{
|
||||
if (status == RangeChange)
|
||||
return;
|
||||
|
||||
panic("FrontEnd doesn't expect recvStatusChange callback!");
|
||||
}
|
||||
|
||||
template<class Impl>
|
||||
|
||||
@@ -256,11 +256,13 @@ class OzoneLWLSQ {
|
||||
|
||||
virtual void recvFunctional(PacketPtr pkt);
|
||||
|
||||
virtual void recvStatusChange(Status status);
|
||||
virtual void recvRangeChange();
|
||||
|
||||
virtual void getDeviceAddressRanges(AddrRangeList &resp,
|
||||
bool &snoop)
|
||||
{ resp.clear(); snoop = true; }
|
||||
/**
|
||||
* Is a snooper due to LSQ maintenance
|
||||
*/
|
||||
virtual bool isSnooping()
|
||||
{ return true; }
|
||||
|
||||
virtual bool recvTiming(PacketPtr pkt);
|
||||
|
||||
|
||||
@@ -77,12 +77,8 @@ OzoneLWLSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
OzoneLWLSQ<Impl>::DcachePort::recvStatusChange(Status status)
|
||||
OzoneLWLSQ<Impl>::DcachePort::recvRangeChange()
|
||||
{
|
||||
if (status == RangeChange)
|
||||
return;
|
||||
|
||||
panic("O3CPU doesn't expect recvStatusChange callback!");
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
||||
@@ -96,9 +96,7 @@ AtomicSimpleCPU::init()
|
||||
tcBase()->initMemProxies(tcBase());
|
||||
#endif
|
||||
if (hasPhysMemPort) {
|
||||
bool snoop = false;
|
||||
AddrRangeList pmAddrList;
|
||||
physmemPort.getPeerAddressRanges(pmAddrList, snoop);
|
||||
AddrRangeList pmAddrList = physmemPort.getPeer()->getAddrRanges();
|
||||
physMemAddr = *pmAddrList.begin();
|
||||
}
|
||||
// Atomic doesn't do MT right now, so contextId == threadId
|
||||
|
||||
@@ -84,17 +84,8 @@ MemTest::CpuPort::recvFunctional(PacketPtr pkt)
|
||||
}
|
||||
|
||||
void
|
||||
MemTest::CpuPort::recvStatusChange(Status status)
|
||||
MemTest::CpuPort::recvRangeChange()
|
||||
{
|
||||
if (status == RangeChange) {
|
||||
if (!snoopRangeSent) {
|
||||
snoopRangeSent = true;
|
||||
sendStatusChange(Port::RangeChange);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
panic("MemTest doesn't expect recvStatusChange callback!");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -149,9 +140,6 @@ MemTest::MemTest(const Params *p)
|
||||
atomic(p->atomic),
|
||||
suppress_func_warnings(p->suppress_func_warnings)
|
||||
{
|
||||
cachePort.snoopRangeSent = false;
|
||||
funcPort.snoopRangeSent = true;
|
||||
|
||||
id = TESTER_ALLOCATOR++;
|
||||
|
||||
// Needs to be masked off once we know the block size.
|
||||
|
||||
@@ -93,8 +93,6 @@ class MemTest : public MemObject
|
||||
: Port(_name, _memtest), memtest(_memtest)
|
||||
{ }
|
||||
|
||||
bool snoopRangeSent;
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool recvTiming(PacketPtr pkt);
|
||||
@@ -103,20 +101,14 @@ class MemTest : public MemObject
|
||||
|
||||
virtual void recvFunctional(PacketPtr pkt);
|
||||
|
||||
virtual void recvStatusChange(Status status);
|
||||
virtual void recvRangeChange();
|
||||
|
||||
virtual void recvRetry();
|
||||
|
||||
virtual void getDeviceAddressRanges(AddrRangeList &resp,
|
||||
bool &snoop)
|
||||
{ resp.clear(); snoop = false; }
|
||||
};
|
||||
|
||||
CpuPort cachePort;
|
||||
CpuPort funcPort;
|
||||
|
||||
bool snoopRangeSent;
|
||||
|
||||
class MemTestSenderState : public Packet::SenderState, public FastAlloc
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -81,17 +81,8 @@ NetworkTest::CpuPort::recvFunctional(PacketPtr pkt)
|
||||
}
|
||||
|
||||
void
|
||||
NetworkTest::CpuPort::recvStatusChange(Status status)
|
||||
NetworkTest::CpuPort::recvRangeChange()
|
||||
{
|
||||
if (status == RangeChange) {
|
||||
if (!snoopRangeSent) {
|
||||
snoopRangeSent = true;
|
||||
sendStatusChange(Port::RangeChange);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
panic("NetworkTest doesn't expect recvStatusChange callback!");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -124,8 +115,6 @@ NetworkTest::NetworkTest(const Params *p)
|
||||
injRate(p->inj_rate),
|
||||
precision(p->precision)
|
||||
{
|
||||
cachePort.snoopRangeSent = false;
|
||||
|
||||
// set up counters
|
||||
noResponseCycles = 0;
|
||||
schedule(tickEvent, 0);
|
||||
|
||||
@@ -89,8 +89,6 @@ class NetworkTest : public MemObject
|
||||
: Port(_name, _networktest), networktest(_networktest)
|
||||
{ }
|
||||
|
||||
bool snoopRangeSent;
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool recvTiming(PacketPtr pkt);
|
||||
@@ -99,19 +97,13 @@ class NetworkTest : public MemObject
|
||||
|
||||
virtual void recvFunctional(PacketPtr pkt);
|
||||
|
||||
virtual void recvStatusChange(Status status);
|
||||
virtual void recvRangeChange();
|
||||
|
||||
virtual void recvRetry();
|
||||
|
||||
virtual void getDeviceAddressRanges(AddrRangeList &resp,
|
||||
bool &snoop)
|
||||
{ resp.clear(); snoop = false; }
|
||||
};
|
||||
|
||||
CpuPort cachePort;
|
||||
|
||||
bool snoopRangeSent;
|
||||
|
||||
class NetworkTestSenderState : public Packet::SenderState, public FastAlloc
|
||||
{
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user