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:
Andreas Hansson 2012-01-17 12:55:09 -06:00
parent 142380a373
commit 07cf9d914b
54 changed files with 345 additions and 416 deletions

View file

@ -353,25 +353,27 @@ X86ISA::Interrupts::recvResponse(PacketPtr pkt)
} }
void AddrRangeList
X86ISA::Interrupts::addressRanges(AddrRangeList &range_list) X86ISA::Interrupts::getAddrRanges()
{ {
range_list.clear(); AddrRangeList ranges;
Range<Addr> range = RangeEx(x86LocalAPICAddress(initialApicId, 0), Range<Addr> range = RangeEx(x86LocalAPICAddress(initialApicId, 0),
x86LocalAPICAddress(initialApicId, 0) + x86LocalAPICAddress(initialApicId, 0) +
PageBytes); PageBytes);
range_list.push_back(range); ranges.push_back(range);
pioAddr = range.start; pioAddr = range.start;
return ranges;
} }
void AddrRangeList
X86ISA::Interrupts::getIntAddrRange(AddrRangeList &range_list) X86ISA::Interrupts::getIntAddrRange()
{ {
range_list.clear(); AddrRangeList ranges;
range_list.push_back(RangeEx(x86InterruptAddress(initialApicId, 0), ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
x86InterruptAddress(initialApicId, 0) + x86InterruptAddress(initialApicId, 0) +
PhysAddrAPICRangeSize)); PhysAddrAPICRangeSize));
return ranges;
} }

View file

@ -217,8 +217,8 @@ class Interrupts : public BasicPioDevice, IntDev
return entry.periodic; return entry.periodic;
} }
void addressRanges(AddrRangeList &range_list); AddrRangeList getAddrRanges();
void getIntAddrRange(AddrRangeList &range_list); AddrRangeList getIntAddrRange();
Port *getPort(const std::string &if_name, int idx = -1) Port *getPort(const std::string &if_name, int idx = -1)
{ {

View file

@ -154,17 +154,8 @@ Walker::WalkerPort::recvFunctional(PacketPtr pkt)
} }
void void
Walker::WalkerPort::recvStatusChange(Status status) Walker::WalkerPort::recvRangeChange()
{ {
if (status == RangeChange) {
if (!snoopRangeSent) {
snoopRangeSent = true;
sendStatusChange(Port::RangeChange);
}
return;
}
panic("Unexpected recvStatusChange.\n");
} }
void void

View file

@ -63,26 +63,18 @@ namespace X86ISA
{ {
public: public:
WalkerPort(const std::string &_name, Walker * _walker) : WalkerPort(const std::string &_name, Walker * _walker) :
Port(_name, _walker), walker(_walker), Port(_name, _walker), walker(_walker)
snoopRangeSent(false)
{} {}
protected: protected:
Walker * walker; Walker * walker;
bool snoopRangeSent;
bool recvTiming(PacketPtr pkt); bool recvTiming(PacketPtr pkt);
Tick recvAtomic(PacketPtr pkt); Tick recvAtomic(PacketPtr pkt);
void recvFunctional(PacketPtr pkt); void recvFunctional(PacketPtr pkt);
void recvStatusChange(Status status); void recvRangeChange();
void recvRetry(); void recvRetry();
void getDeviceAddressRanges(AddrRangeList &resp, bool isSnooping() { return true; }
bool &snoop)
{
resp.clear();
snoop = true;
}
}; };
friend class WalkerPort; friend class WalkerPort;

View file

@ -527,23 +527,6 @@ BaseCPU::CpuPort::recvFunctional(PacketPtr pkt)
} }
void 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;
} }

View file

@ -126,7 +126,7 @@ class BaseCPU : public MemObject
* @param _name structural owner of this port * @param _name structural owner of this port
*/ */
CpuPort(const std::string& _name, MemObject* _owner) : CpuPort(const std::string& _name, MemObject* _owner) :
Port(_name, _owner), snoopRangeSent(false) Port(_name, _owner)
{ } { }
protected: protected:
@ -139,22 +139,7 @@ class BaseCPU : public MemObject
void recvFunctional(PacketPtr pkt); void recvFunctional(PacketPtr pkt);
void recvStatusChange(Status status); void recvRangeChange();
/**
* 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;
}; };

View file

@ -82,17 +82,8 @@ CacheUnit::CachePort::recvFunctional(PacketPtr pkt)
} }
void 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 bool

View file

@ -90,11 +90,9 @@ class CacheUnit : public Resource
CachePort(CacheUnit *_cachePortUnit) CachePort(CacheUnit *_cachePortUnit)
: Port(_cachePortUnit->name() + "-cache-port", : Port(_cachePortUnit->name() + "-cache-port",
(MemObject*)_cachePortUnit->cpu), (MemObject*)_cachePortUnit->cpu),
cachePortUnit(_cachePortUnit), snoopRangeSent(false) cachePortUnit(_cachePortUnit)
{ } { }
bool snoopRangeSent;
protected: protected:
/** Atomic version of receive. Panics. */ /** Atomic version of receive. Panics. */
Tick recvAtomic(PacketPtr pkt); Tick recvAtomic(PacketPtr pkt);
@ -102,13 +100,8 @@ class CacheUnit : public Resource
/** Functional version of receive.*/ /** Functional version of receive.*/
void recvFunctional(PacketPtr pkt); void recvFunctional(PacketPtr pkt);
/** Receives status change. Other than range changing, panics. */ /** Receives range changes. */
void recvStatusChange(Status status); void recvRangeChange();
/** Returns the address ranges of this device. */
void getDeviceAddressRanges(AddrRangeList &resp,
bool &snoop)
{ resp.clear(); snoop = true; }
/** Timing version of receive */ /** Timing version of receive */
bool recvTiming(PacketPtr pkt); bool recvTiming(PacketPtr pkt);

View file

@ -186,12 +186,10 @@ class FullO3CPU : public BaseO3CPU
* As this CPU requires snooping to maintain the load store queue * As this CPU requires snooping to maintain the load store queue
* change the behaviour from the base CPU port. * change the behaviour from the base CPU port.
* *
* @param resp list of ranges this port responds to * @return true since we have to snoop
* @param snoop indicating if the port snoops or not
*/ */
virtual void getDeviceAddressRanges(AddrRangeList& resp, virtual bool isSnooping()
bool& snoop) { return true; }
{ resp.clear(); snoop = true; }
}; };
class TickEvent : public Event class TickEvent : public Event

View file

@ -87,13 +87,8 @@ class FrontEnd
/** Functional version of receive. Panics. */ /** Functional version of receive. Panics. */
virtual void recvFunctional(PacketPtr pkt); virtual void recvFunctional(PacketPtr pkt);
/** Receives status change. Other than range changing, panics. */ /** Receives range change. */
virtual void recvStatusChange(Status status); virtual void recvRangeChange();
/** Returns the address ranges of this device. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
bool &snoop)
{ resp.clear(); snoop = true; }
/** Timing version of receive. Handles setting fetch to the /** Timing version of receive. Handles setting fetch to the
* proper status to start fetching. */ * proper status to start fetching. */

View file

@ -64,12 +64,8 @@ FrontEnd<Impl>::IcachePort::recvFunctional(PacketPtr pkt)
template<class Impl> template<class Impl>
void 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> template<class Impl>

View file

@ -256,11 +256,13 @@ class OzoneLWLSQ {
virtual void recvFunctional(PacketPtr pkt); virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status); virtual void recvRangeChange();
virtual void getDeviceAddressRanges(AddrRangeList &resp, /**
bool &snoop) * Is a snooper due to LSQ maintenance
{ resp.clear(); snoop = true; } */
virtual bool isSnooping()
{ return true; }
virtual bool recvTiming(PacketPtr pkt); virtual bool recvTiming(PacketPtr pkt);

View file

@ -77,12 +77,8 @@ OzoneLWLSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
template <class Impl> template <class Impl>
void 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> template <class Impl>

View file

@ -96,9 +96,7 @@ AtomicSimpleCPU::init()
tcBase()->initMemProxies(tcBase()); tcBase()->initMemProxies(tcBase());
#endif #endif
if (hasPhysMemPort) { if (hasPhysMemPort) {
bool snoop = false; AddrRangeList pmAddrList = physmemPort.getPeer()->getAddrRanges();
AddrRangeList pmAddrList;
physmemPort.getPeerAddressRanges(pmAddrList, snoop);
physMemAddr = *pmAddrList.begin(); physMemAddr = *pmAddrList.begin();
} }
// Atomic doesn't do MT right now, so contextId == threadId // Atomic doesn't do MT right now, so contextId == threadId

View file

@ -84,17 +84,8 @@ MemTest::CpuPort::recvFunctional(PacketPtr pkt)
} }
void 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 void
@ -149,9 +140,6 @@ MemTest::MemTest(const Params *p)
atomic(p->atomic), atomic(p->atomic),
suppress_func_warnings(p->suppress_func_warnings) suppress_func_warnings(p->suppress_func_warnings)
{ {
cachePort.snoopRangeSent = false;
funcPort.snoopRangeSent = true;
id = TESTER_ALLOCATOR++; id = TESTER_ALLOCATOR++;
// Needs to be masked off once we know the block size. // Needs to be masked off once we know the block size.

View file

@ -93,8 +93,6 @@ class MemTest : public MemObject
: Port(_name, _memtest), memtest(_memtest) : Port(_name, _memtest), memtest(_memtest)
{ } { }
bool snoopRangeSent;
protected: protected:
virtual bool recvTiming(PacketPtr pkt); virtual bool recvTiming(PacketPtr pkt);
@ -103,20 +101,14 @@ class MemTest : public MemObject
virtual void recvFunctional(PacketPtr pkt); virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status); virtual void recvRangeChange();
virtual void recvRetry(); virtual void recvRetry();
virtual void getDeviceAddressRanges(AddrRangeList &resp,
bool &snoop)
{ resp.clear(); snoop = false; }
}; };
CpuPort cachePort; CpuPort cachePort;
CpuPort funcPort; CpuPort funcPort;
bool snoopRangeSent;
class MemTestSenderState : public Packet::SenderState, public FastAlloc class MemTestSenderState : public Packet::SenderState, public FastAlloc
{ {
public: public:

View file

@ -81,17 +81,8 @@ NetworkTest::CpuPort::recvFunctional(PacketPtr pkt)
} }
void 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 void
@ -124,8 +115,6 @@ NetworkTest::NetworkTest(const Params *p)
injRate(p->inj_rate), injRate(p->inj_rate),
precision(p->precision) precision(p->precision)
{ {
cachePort.snoopRangeSent = false;
// set up counters // set up counters
noResponseCycles = 0; noResponseCycles = 0;
schedule(tickEvent, 0); schedule(tickEvent, 0);

View file

@ -89,8 +89,6 @@ class NetworkTest : public MemObject
: Port(_name, _networktest), networktest(_networktest) : Port(_name, _networktest), networktest(_networktest)
{ } { }
bool snoopRangeSent;
protected: protected:
virtual bool recvTiming(PacketPtr pkt); virtual bool recvTiming(PacketPtr pkt);
@ -99,19 +97,13 @@ class NetworkTest : public MemObject
virtual void recvFunctional(PacketPtr pkt); virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status); virtual void recvRangeChange();
virtual void recvRetry(); virtual void recvRetry();
virtual void getDeviceAddressRanges(AddrRangeList &resp,
bool &snoop)
{ resp.clear(); snoop = false; }
}; };
CpuPort cachePort; CpuPort cachePort;
bool snoopRangeSent;
class NetworkTestSenderState : public Packet::SenderState, public FastAlloc class NetworkTestSenderState : public Packet::SenderState, public FastAlloc
{ {
public: public:

View file

@ -703,12 +703,13 @@ Gic::postInt(uint32_t cpu, Tick when)
eventq->schedule(postIntEvent[cpu], when); eventq->schedule(postIntEvent[cpu], when);
} }
void AddrRangeList
Gic::addressRanges(AddrRangeList &range_list) Gic::getAddrRanges()
{ {
range_list.clear(); AddrRangeList ranges;
range_list.push_back(RangeSize(distAddr, DIST_SIZE)); ranges.push_back(RangeSize(distAddr, DIST_SIZE));
range_list.push_back(RangeSize(cpuAddr, CPU_SIZE)); ranges.push_back(RangeSize(cpuAddr, CPU_SIZE));
return ranges;
} }

View file

@ -259,7 +259,7 @@ class Gic : public PioDevice
/** Return the address ranges used by the Gic /** Return the address ranges used by the Gic
* This is the distributor address + all cpu addresses * This is the distributor address + all cpu addresses
*/ */
virtual void addressRanges(AddrRangeList &range_list); virtual AddrRangeList getAddrRanges();
/** A PIO read to the device, immediately split up into /** A PIO read to the device, immediately split up into
* readDistributor() or readCpu() * readDistributor() or readCpu()

View file

@ -735,11 +735,12 @@ Pl111::generateInterrupt()
} }
} }
void AddrRangeList
Pl111::addressRanges(AddrRangeList& range_list) Pl111::getAddrRanges()
{ {
range_list.clear(); AddrRangeList ranges;
range_list.push_back(RangeSize(pioAddr, pioSize)); ranges.push_back(RangeSize(pioAddr, pioSize));
return ranges;
} }
Pl111 * Pl111 *

View file

@ -325,10 +325,12 @@ class Pl111: public AmbaDmaDevice
virtual void serialize(std::ostream &os); virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section); virtual void unserialize(Checkpoint *cp, const std::string &section);
/** return the address ranges that this device responds to. /**
* @param range_list range list to populate with ranges * Determine the address ranges that this device responds to.
*
* @return a list of non-overlapping address ranges
*/ */
void addressRanges(AddrRangeList &range_list); AddrRangeList getAddrRanges();
}; };
#endif #endif

View file

@ -85,7 +85,6 @@ class CopyEngine : public PciDev
void init(); void init();
std::string name() { assert(ce); return ce->name() + csprintf("-chan%d", channelId); } std::string name() { assert(ce); return ce->name() + csprintf("-chan%d", channelId); }
virtual void addressRanges(AddrRangeList &range_list) { range_list.clear(); }
virtual Tick read(PacketPtr pkt) virtual Tick read(PacketPtr pkt)
{ panic("CopyEngineChannel has no I/O access\n");} { panic("CopyEngineChannel has no I/O access\n");}
virtual Tick write(PacketPtr pkt) virtual Tick write(PacketPtr pkt)

View file

@ -47,13 +47,10 @@ PioPort::recvAtomic(PacketPtr pkt)
return pkt->isRead() ? device->read(pkt) : device->write(pkt); return pkt->isRead() ? device->read(pkt) : device->write(pkt);
} }
void AddrRangeList
PioPort::getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) PioPort::getAddrRanges()
{ {
snoop = false; return device->getAddrRanges();
device->addressRanges(resp);
for (AddrRangeIter i = resp.begin(); i != resp.end(); i++)
DPRINTF(BusAddrRanges, "Adding Range %#x-%#x\n", i->start, i->end);
} }
@ -72,7 +69,7 @@ PioDevice::init()
{ {
if (!pioPort) if (!pioPort)
panic("Pio port of %s not connected to anything!", name()); panic("Pio port of %s not connected to anything!", name());
pioPort->sendStatusChange(Port::RangeChange); pioPort->sendRangeChange();
} }
Port * Port *
@ -105,13 +102,14 @@ BasicPioDevice::BasicPioDevice(const Params *p)
pioDelay(p->pio_latency) pioDelay(p->pio_latency)
{} {}
void AddrRangeList
BasicPioDevice::addressRanges(AddrRangeList &range_list) BasicPioDevice::getAddrRanges()
{ {
assert(pioSize != 0); assert(pioSize != 0);
range_list.clear(); AddrRangeList ranges;
DPRINTF(BusAddrRanges, "registering range: %#x-%#x\n", pioAddr, pioSize); DPRINTF(BusAddrRanges, "registering range: %#x-%#x\n", pioAddr, pioSize);
range_list.push_back(RangeSize(pioAddr, pioSize)); ranges.push_back(RangeSize(pioAddr, pioSize));
return ranges;
} }
@ -121,7 +119,7 @@ DmaPort::DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff,
pendingCount(0), actionInProgress(0), drainEvent(NULL), pendingCount(0), actionInProgress(0), drainEvent(NULL),
backoffTime(0), minBackoffDelay(min_backoff), backoffTime(0), minBackoffDelay(min_backoff),
maxBackoffDelay(max_backoff), inRetry(false), recvSnoops(recv_snoops), maxBackoffDelay(max_backoff), inRetry(false), recvSnoops(recv_snoops),
snoopRangeSent(false), backoffEvent(this) backoffEvent(this)
{ } { }
bool bool

View file

@ -51,7 +51,7 @@ class System;
* The PioPort class is a programmed i/o port that all devices that are * The PioPort class is a programmed i/o port that all devices that are
* sensitive to an address range use. The port takes all the memory * sensitive to an address range use. The port takes all the memory
* access types and roles them into one read() and write() call that the device * access types and roles them into one read() and write() call that the device
* must respond to. The device must also provide the addressRanges() function * must respond to. The device must also provide getAddrRanges() function
* with which it returns the address ranges it is interested in. * with which it returns the address ranges it is interested in.
*/ */
class PioPort : public SimpleTimingPort class PioPort : public SimpleTimingPort
@ -62,8 +62,7 @@ class PioPort : public SimpleTimingPort
virtual Tick recvAtomic(PacketPtr pkt); virtual Tick recvAtomic(PacketPtr pkt);
virtual void getDeviceAddressRanges(AddrRangeList &resp, virtual AddrRangeList getAddrRanges();
bool &snoop);
public: public:
@ -133,9 +132,6 @@ class DmaPort : public Port
/** Port accesses a cache which requires snooping */ /** Port accesses a cache which requires snooping */
bool recvSnoops; bool recvSnoops;
/** Records snoop response so we only reply once to a status change */
bool snoopRangeSent;
virtual bool recvTiming(PacketPtr pkt); virtual bool recvTiming(PacketPtr pkt);
virtual Tick recvAtomic(PacketPtr pkt) virtual Tick recvAtomic(PacketPtr pkt)
{ {
@ -150,25 +146,16 @@ class DmaPort : public Port
panic("dma port shouldn't be used for pio access."); panic("dma port shouldn't be used for pio access.");
} }
virtual void recvStatusChange(Status status) virtual void recvRangeChange()
{ {
if (recvSnoops) { // DMA port is a master with a single slave so there is no choice and
if (status == RangeChange) { // thus no need to worry about any address changes
if (!snoopRangeSent) {
snoopRangeSent = true;
sendStatusChange(Port::RangeChange);
}
return;
}
panic("Unexpected recvStatusChange\n");
}
} }
virtual void recvRetry() ; virtual void recvRetry() ;
virtual void getDeviceAddressRanges(AddrRangeList &resp, virtual bool isSnooping()
bool &snoop) { return recvSnoops; }
{ resp.clear(); snoop = recvSnoops; }
void queueDma(PacketPtr pkt, bool front = false); void queueDma(PacketPtr pkt, bool front = false);
void sendDma(); void sendDma();
@ -192,7 +179,7 @@ class DmaPort : public Port
/** /**
* This device is the base class which all devices senstive to an address range * This device is the base class which all devices senstive to an address range
* inherit from. There are three pure virtual functions which all devices must * inherit from. There are three pure virtual functions which all devices must
* implement addressRanges(), read(), and write(). The magic do choose which * implement getAddrRanges(), read(), and write(). The magic do choose which
* mode we are in, etc is handled by the PioPort so the device doesn't have to * mode we are in, etc is handled by the PioPort so the device doesn't have to
* bother. * bother.
*/ */
@ -210,7 +197,13 @@ class PioDevice : public MemObject
* that it sees. */ * that it sees. */
PioPort *pioPort; PioPort *pioPort;
virtual void addressRanges(AddrRangeList &range_list) = 0; /**
* Every PIO device is obliged to provide an implementation that
* returns the address ranges the device responds to.
*
* @return a list of non-overlapping address ranges
*/
virtual AddrRangeList getAddrRanges() = 0;
/** Pure virtual function that the device must implement. Called /** Pure virtual function that the device must implement. Called
* when a read command is recieved by the port. * when a read command is recieved by the port.
@ -269,10 +262,12 @@ class BasicPioDevice : public PioDevice
return dynamic_cast<const Params *>(_params); return dynamic_cast<const Params *>(_params);
} }
/** return the address ranges that this device responds to. /**
* @param range_list range list to populate with ranges * Determine the address ranges that this device responds to.
*
* @return a list of non-overlapping address ranges
*/ */
void addressRanges(AddrRangeList &range_list); virtual AddrRangeList getAddrRanges();
}; };

View file

@ -86,11 +86,12 @@ PciConfigAll::write(PacketPtr pkt)
} }
void AddrRangeList
PciConfigAll::addressRanges(AddrRangeList &range_list) PciConfigAll::getAddrRanges()
{ {
range_list.clear(); AddrRangeList ranges;
range_list.push_back(RangeSize(pioAddr, params()->size)); ranges.push_back(RangeSize(pioAddr, params()->size));
return ranges;
} }

View file

@ -80,7 +80,7 @@ class PciConfigAll : public PioDevice
virtual Tick write(PacketPtr pkt); virtual Tick write(PacketPtr pkt);
void addressRanges(AddrRangeList &range_list); AddrRangeList getAddrRanges();
private: private:
Addr pioAddr; Addr pioAddr;

View file

@ -72,13 +72,13 @@ PciDev::PciConfigPort::recvAtomic(PacketPtr pkt)
return pkt->isRead() ? device->readConfig(pkt) : device->writeConfig(pkt); return pkt->isRead() ? device->readConfig(pkt) : device->writeConfig(pkt);
} }
void AddrRangeList
PciDev::PciConfigPort::getDeviceAddressRanges(AddrRangeList &resp, PciDev::PciConfigPort::getAddrRanges()
bool &snoop)
{ {
snoop = false;; AddrRangeList ranges;
if (configAddr != ULL(-1)) if (configAddr != ULL(-1))
resp.push_back(RangeSize(configAddr, PCI_CONFIG_SIZE+1)); ranges.push_back(RangeSize(configAddr, PCI_CONFIG_SIZE+1));
return ranges;
} }
@ -152,7 +152,7 @@ PciDev::init()
{ {
if (!configPort) if (!configPort)
panic("pci config port not connected to anything!"); panic("pci config port not connected to anything!");
configPort->sendStatusChange(Port::RangeChange); configPort->sendRangeChange();
PioDevice::init(); PioDevice::init();
} }
@ -207,14 +207,15 @@ PciDev::readConfig(PacketPtr pkt)
} }
void AddrRangeList
PciDev::addressRanges(AddrRangeList &range_list) PciDev::getAddrRanges()
{ {
AddrRangeList ranges;
int x = 0; int x = 0;
range_list.clear();
for (x = 0; x < 6; x++) for (x = 0; x < 6; x++)
if (BARAddrs[x] != 0) if (BARAddrs[x] != 0)
range_list.push_back(RangeSize(BARAddrs[x],BARSize[x])); ranges.push_back(RangeSize(BARAddrs[x],BARSize[x]));
return ranges;
} }
Tick Tick
@ -301,7 +302,7 @@ PciDev::writeConfig(PacketPtr pkt)
BARAddrs[barnum] = BAR_IO_SPACE(he_old_bar) ? BARAddrs[barnum] = BAR_IO_SPACE(he_old_bar) ?
platform->calcPciIOAddr(he_new_bar) : platform->calcPciIOAddr(he_new_bar) :
platform->calcPciMemAddr(he_new_bar); platform->calcPciMemAddr(he_new_bar);
pioPort->sendStatusChange(Port::RangeChange); pioPort->sendRangeChange();
} }
} }
config.baseAddr[barnum] = htole((he_new_bar & ~bar_mask) | config.baseAddr[barnum] = htole((he_new_bar & ~bar_mask) |
@ -354,7 +355,7 @@ PciDev::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0])); UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0]));
UNSERIALIZE_ARRAY(config.data, UNSERIALIZE_ARRAY(config.data,
sizeof(config.data) / sizeof(config.data[0])); sizeof(config.data) / sizeof(config.data[0]));
pioPort->sendStatusChange(Port::RangeChange); pioPort->sendRangeChange();
} }

View file

@ -65,8 +65,7 @@ class PciDev : public DmaDevice
virtual Tick recvAtomic(PacketPtr pkt); virtual Tick recvAtomic(PacketPtr pkt);
virtual void getDeviceAddressRanges(AddrRangeList &resp, virtual AddrRangeList getAddrRanges();
bool &snoop);
Platform *platform; Platform *platform;
@ -187,10 +186,12 @@ class PciDev : public DmaDevice
interruptLine() interruptLine()
{ return letoh(config.interruptLine); } { return letoh(config.interruptLine); }
/** return the address ranges that this device responds to. /**
* @params range_list range list to populate with ranges * Determine the address ranges that this device responds to.
*
* @return a list of non-overlapping address ranges
*/ */
void addressRanges(AddrRangeList &range_list); AddrRangeList getAddrRanges();
/** /**
* Constructor for PCI Dev. This function copies data from the * Constructor for PCI Dev. This function copies data from the

View file

@ -1714,7 +1714,7 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
if (transmitTick) if (transmitTick)
schedule(txEvent, curTick() + transmitTick); schedule(txEvent, curTick() + transmitTick);
pioPort->sendStatusChange(Port::RangeChange); pioPort->sendRangeChange();
} }

View file

@ -325,12 +325,13 @@ Iob::receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1)
return true; return true;
} }
void AddrRangeList
Iob::addressRanges(AddrRangeList &range_list) Iob::getAddrRanges()
{ {
range_list.clear(); AddrRangeList ranges;
range_list.push_back(RangeSize(iobManAddr, iobManSize)); ranges.push_back(RangeSize(iobManAddr, iobManSize));
range_list.push_back(RangeSize(iobJBusAddr, iobJBusSize)); ranges.push_back(RangeSize(iobJBusAddr, iobJBusSize));
return ranges;
} }

View file

@ -141,7 +141,7 @@ class Iob : public PioDevice
bool receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, bool receiveJBusInterrupt(int cpu_id, int source, uint64_t d0,
uint64_t d1); uint64_t d1);
void addressRanges(AddrRangeList &range_list); AddrRangeList getAddrRanges();
virtual void serialize(std::ostream &os); virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section); virtual void unserialize(Checkpoint *cp, const std::string &section);

View file

@ -286,16 +286,14 @@ Uart8250::dataAvailable()
} }
void AddrRangeList
Uart8250::addressRanges(AddrRangeList &range_list) Uart8250::getAddrRanges()
{ {
assert(pioSize != 0); AddrRangeList ranges;
range_list.clear(); ranges.push_back(RangeSize(pioAddr, pioSize));
range_list.push_back(RangeSize(pioAddr, pioSize)); return ranges;
} }
void void
Uart8250::serialize(ostream &os) Uart8250::serialize(ostream &os)
{ {

View file

@ -100,7 +100,7 @@ class Uart8250 : public Uart
virtual Tick read(PacketPtr pkt); virtual Tick read(PacketPtr pkt);
virtual Tick write(PacketPtr pkt); virtual Tick write(PacketPtr pkt);
virtual void addressRanges(AddrRangeList &range_list); virtual AddrRangeList getAddrRanges();
/** /**
* Inform the uart that there is data available. * Inform the uart that there is data available.

View file

@ -43,12 +43,13 @@ const uint8_t CommandAck = 0xfa;
const uint8_t CommandNack = 0xfe; const uint8_t CommandNack = 0xfe;
const uint8_t BatSuccessful = 0xaa; const uint8_t BatSuccessful = 0xaa;
void AddrRangeList
X86ISA::I8042::addressRanges(AddrRangeList &range_list) X86ISA::I8042::getAddrRanges()
{ {
range_list.clear(); AddrRangeList ranges;
range_list.push_back(RangeSize(dataPort, 1)); ranges.push_back(RangeSize(dataPort, 1));
range_list.push_back(RangeSize(commandPort, 1)); ranges.push_back(RangeSize(commandPort, 1));
return ranges;
} }
void void

View file

@ -255,7 +255,7 @@ class I8042 : public BasicPioDevice
commandByte.keyboardFullInt = 1; commandByte.keyboardFullInt = 1;
} }
void addressRanges(AddrRangeList &range_list); AddrRangeList getAddrRanges();
Tick read(PacketPtr pkt); Tick read(PacketPtr pkt);

View file

@ -103,19 +103,21 @@ class I82094AA : public PioDevice, public IntDev
Tick read(PacketPtr pkt); Tick read(PacketPtr pkt);
Tick write(PacketPtr pkt); Tick write(PacketPtr pkt);
void addressRanges(AddrRangeList &range_list) AddrRangeList getAddrRanges()
{ {
range_list.clear(); AddrRangeList ranges;
range_list.push_back(RangeEx(pioAddr, pioAddr + 4)); ranges.push_back(RangeEx(pioAddr, pioAddr + 4));
range_list.push_back(RangeEx(pioAddr + 16, pioAddr + 20)); ranges.push_back(RangeEx(pioAddr + 16, pioAddr + 20));
return ranges;
} }
void getIntAddrRange(AddrRangeList &range_list) AddrRangeList getIntAddrRange()
{ {
range_list.clear(); AddrRangeList ranges;
range_list.push_back(RangeEx(x86InterruptAddress(initialApicId, 0), ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
x86InterruptAddress(initialApicId, 0) + x86InterruptAddress(initialApicId, 0) +
PhysAddrAPICRangeSize)); PhysAddrAPICRangeSize));
return ranges;
} }
void writeReg(uint8_t offset, uint32_t value); void writeReg(uint8_t offset, uint32_t value);

View file

@ -54,7 +54,7 @@ X86ISA::IntDev::init()
if (!intPort) { if (!intPort) {
panic("Int port not connected to anything!"); panic("Int port not connected to anything!");
} }
intPort->sendStatusChange(Port::RangeChange); intPort->sendRangeChange();
} }
X86ISA::IntSourcePin * X86ISA::IntSourcePin *

View file

@ -63,10 +63,9 @@ class IntDev
{ {
} }
void getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) AddrRangeList getAddrRanges()
{ {
snoop = false; return device->getIntAddrRange();
device->getIntAddrRange(resp);
} }
Tick recvMessage(PacketPtr pkt) Tick recvMessage(PacketPtr pkt)
@ -134,8 +133,8 @@ class IntDev
return 0; return 0;
} }
virtual void virtual AddrRangeList
getIntAddrRange(AddrRangeList &range_list) getIntAddrRange()
{ {
panic("intAddrRange not implemented.\n"); panic("intAddrRange not implemented.\n");
} }

View file

@ -57,14 +57,12 @@ BadAddrEvent::process(ThreadContext *tc)
uint64_t a0 = tc->readIntReg(16); uint64_t a0 = tc->readIntReg(16);
AddrRangeList resp;
bool snoop;
AddrRangeIter iter; AddrRangeIter iter;
bool found = false; bool found = false;
Port* dataPort = tc->getCpuPtr()->getPort("dcache_port"); Port* dataPort = tc->getCpuPtr()->getPort("dcache_port");
dataPort->getPeerAddressRanges(resp, snoop); AddrRangeList resp = dataPort->getPeer()->getAddrRanges();
for (iter = resp.begin(); iter != resp.end(); iter++) { for (iter = resp.begin(); iter != resp.end(); iter++) {
if (*iter == (K0Seg2Phys(a0) & PAddrImplMask)) if (*iter == (K0Seg2Phys(a0) & PAddrImplMask))
found = true; found = true;

View file

@ -338,21 +338,19 @@ Bridge::BridgePort::recvFunctional(PacketPtr pkt)
otherPort->sendFunctional(pkt); otherPort->sendFunctional(pkt);
} }
/** Function called by the port when the bus is receiving a status change.*/ /** Function called by the port when the bridge is receiving a range change.*/
void void
Bridge::BridgePort::recvStatusChange(Port::Status status) Bridge::BridgePort::recvRangeChange()
{ {
otherPort->sendStatusChange(status); otherPort->sendRangeChange();
} }
void AddrRangeList
Bridge::BridgePort::getDeviceAddressRanges(AddrRangeList &resp, Bridge::BridgePort::getAddrRanges()
bool &snoop)
{ {
otherPort->getPeerAddressRanges(resp, snoop); AddrRangeList ranges = otherPort->getPeer()->getAddrRanges();
FilterRangeList(filterRanges, resp); FilterRangeList(filterRanges, ranges);
// we don't allow snooping across bridges return ranges;
snoop = false;
} }
Bridge * Bridge *

View file

@ -178,14 +178,14 @@ class Bridge : public MemObject
pass it to the bridge. */ pass it to the bridge. */
virtual void recvFunctional(PacketPtr pkt); virtual void recvFunctional(PacketPtr pkt);
/** When receiving a status changefrom the peer port, /**
pass it to the bridge. */ * When receiving a range change, pass it through the bridge.
virtual void recvStatusChange(Status status); */
virtual void recvRangeChange();
/** When receiving a address range request the peer port, /** When receiving a address range request the peer port,
pass it to the bridge. */ pass it to the bridge. */
virtual void getDeviceAddressRanges(AddrRangeList &resp, virtual AddrRangeList getAddrRanges();
bool &snoop);
}; };
BridgePort portA, portB; BridgePort portA, portB;

View file

@ -1,4 +1,16 @@
/* /*
* Copyright (c) 2011 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2006 The Regents of The University of Michigan * Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved. * All rights reserved.
* *
@ -94,14 +106,21 @@ Bus::getPort(const std::string &if_name, int idx)
return bp; return bp;
} }
/** Get the ranges of anyone other buses that we are connected to. */
void void
Bus::init() Bus::init()
{ {
m5::hash_map<short,BusPort*>::iterator intIter; m5::hash_map<short,BusPort*>::iterator intIter;
for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++) // iterate over our interfaces and determine which of our neighbours
intIter->second->sendStatusChange(Port::RangeChange); // are snooping and add them as snoopers
for (intIter = interfaces.begin(); intIter != interfaces.end();
intIter++) {
if (intIter->second->getPeer()->isSnooping()) {
DPRINTF(BusAddrRanges, "Adding snooping neighbour %s\n",
intIter->second->getPeer()->name());
snoopPorts.push_back(intIter->second);
}
}
} }
Bus::BusFreeEvent::BusFreeEvent(Bus *_bus) Bus::BusFreeEvent::BusFreeEvent(Bus *_bus)
@ -468,20 +487,16 @@ Bus::recvFunctional(PacketPtr pkt)
} }
} }
/** Function called by the port when the bus is receiving a status change.*/ /** Function called by the port when the bus is receiving a range change.*/
void void
Bus::recvStatusChange(Port::Status status, int id) Bus::recvRangeChange(int id)
{ {
AddrRangeList ranges; AddrRangeList ranges;
bool snoops;
AddrRangeIter iter; AddrRangeIter iter;
if (inRecvStatusChange.count(id)) if (inRecvRangeChange.count(id))
return; return;
inRecvStatusChange.insert(id); inRecvRangeChange.insert(id);
assert(status == Port::RangeChange &&
"The other statuses need to be implemented.");
DPRINTF(BusAddrRanges, "received RangeChange from device id %d\n", id); DPRINTF(BusAddrRanges, "received RangeChange from device id %d\n", id);
@ -490,8 +505,7 @@ Bus::recvStatusChange(Port::Status status, int id)
defaultRange.clear(); defaultRange.clear();
// Only try to update these ranges if the user set a default responder. // Only try to update these ranges if the user set a default responder.
if (useDefaultRange) { if (useDefaultRange) {
defaultPort->getPeerAddressRanges(ranges, snoops); AddrRangeList ranges = defaultPort->getPeer()->getAddrRanges();
assert(snoops == false);
for(iter = ranges.begin(); iter != ranges.end(); iter++) { for(iter = ranges.begin(); iter != ranges.end(); iter++) {
defaultRange.push_back(*iter); defaultRange.push_back(*iter);
DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n", DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n",
@ -512,20 +526,7 @@ Bus::recvStatusChange(Port::Status status, int id)
portIter++; portIter++;
} }
for (SnoopIter s_iter = snoopPorts.begin(); ranges = port->getPeer()->getAddrRanges();
s_iter != snoopPorts.end(); ) {
if ((*s_iter)->getId() == id)
s_iter = snoopPorts.erase(s_iter);
else
s_iter++;
}
port->getPeerAddressRanges(ranges, snoops);
if (snoops) {
DPRINTF(BusAddrRanges, "Adding id %d to snoop list\n", id);
snoopPorts.push_back(port);
}
for (iter = ranges.begin(); iter != ranges.end(); iter++) { for (iter = ranges.begin(); iter != ranges.end(); iter++) {
DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for id %d\n", DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for id %d\n",
@ -546,24 +547,23 @@ Bus::recvStatusChange(Port::Status status, int id)
for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++) for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
if (intIter->first != id && intIter->first != funcPortId) if (intIter->first != id && intIter->first != funcPortId)
intIter->second->sendStatusChange(Port::RangeChange); intIter->second->sendRangeChange();
if (id != defaultId && defaultPort) if (id != defaultId && defaultPort)
defaultPort->sendStatusChange(Port::RangeChange); defaultPort->sendRangeChange();
inRecvStatusChange.erase(id); inRecvRangeChange.erase(id);
} }
void AddrRangeList
Bus::addressRanges(AddrRangeList &resp, bool &snoop, int id) Bus::getAddrRanges(int id)
{ {
resp.clear(); AddrRangeList ranges;
snoop = false;
DPRINTF(BusAddrRanges, "received address range request, returning:\n"); DPRINTF(BusAddrRanges, "received address range request, returning:\n");
for (AddrRangeIter dflt_iter = defaultRange.begin(); for (AddrRangeIter dflt_iter = defaultRange.begin();
dflt_iter != defaultRange.end(); dflt_iter++) { dflt_iter != defaultRange.end(); dflt_iter++) {
resp.push_back(*dflt_iter); ranges.push_back(*dflt_iter);
DPRINTF(BusAddrRanges, " -- Dflt: %#llx : %#llx\n",dflt_iter->start, DPRINTF(BusAddrRanges, " -- Dflt: %#llx : %#llx\n",dflt_iter->start,
dflt_iter->end); dflt_iter->end);
} }
@ -586,12 +586,21 @@ Bus::addressRanges(AddrRangeList &resp, bool &snoop, int id)
} }
} }
if (portIter->second != id && !subset) { if (portIter->second != id && !subset) {
resp.push_back(portIter->first); ranges.push_back(portIter->first);
DPRINTF(BusAddrRanges, " -- %#llx : %#llx\n", DPRINTF(BusAddrRanges, " -- %#llx : %#llx\n",
portIter->first.start, portIter->first.end); portIter->first.start, portIter->first.end);
} }
} }
return ranges;
}
bool
Bus::isSnooping(int id)
{
// in essence, answer the question if there are other snooping
// ports rather than the port that is asking
bool snoop = false;
for (SnoopIter s_iter = snoopPorts.begin(); s_iter != snoopPorts.end(); for (SnoopIter s_iter = snoopPorts.begin(); s_iter != snoopPorts.end();
s_iter++) { s_iter++) {
if ((*s_iter)->getId() != id) { if ((*s_iter)->getId() != id) {
@ -599,6 +608,7 @@ Bus::addressRanges(AddrRangeList &resp, bool &snoop, int id)
break; break;
} }
} }
return snoop;
} }
unsigned unsigned

View file

@ -1,4 +1,16 @@
/* /*
* Copyright (c) 2011 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2002-2005 The Regents of The University of Michigan * Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved. * All rights reserved.
* *
@ -81,6 +93,15 @@ class Bus : public MemObject
int getId() { return id; } int getId() { return id; }
/**
* Determine if this port should be considered a snooper. This
* is determined by the bus.
*
* @return a boolean that is true if this port is snooping
*/
virtual bool isSnooping()
{ return bus->isSnooping(id); }
protected: protected:
/** When reciving a timing request from the peer port (at id), /** When reciving a timing request from the peer port (at id),
@ -98,10 +119,10 @@ class Bus : public MemObject
virtual void recvFunctional(PacketPtr pkt) virtual void recvFunctional(PacketPtr pkt)
{ pkt->setSrc(id); bus->recvFunctional(pkt); } { pkt->setSrc(id); bus->recvFunctional(pkt); }
/** When reciving a status changefrom the peer port (at id), /** When reciving a range change from the peer port (at id),
pass it to the bus. */ pass it to the bus. */
virtual void recvStatusChange(Status status) virtual void recvRangeChange()
{ bus->recvStatusChange(status, id); } { bus->recvRangeChange(id); }
/** When reciving a retry from the peer port (at id), /** When reciving a retry from the peer port (at id),
pass it to the bus. */ pass it to the bus. */
@ -112,9 +133,8 @@ class Bus : public MemObject
// downstream from this bus, yes? That is, the union of all // downstream from this bus, yes? That is, the union of all
// the 'owned' address ranges of all the other interfaces on // the 'owned' address ranges of all the other interfaces on
// this bus... // this bus...
virtual void getDeviceAddressRanges(AddrRangeList &resp, virtual AddrRangeList getAddrRanges()
bool &snoop) { return bus->getAddrRanges(id); }
{ bus->addressRanges(resp, snoop, id); }
// Ask the bus to ask everyone on the bus what their block size is and // Ask the bus to ask everyone on the bus what their block size is and
// take the max of it. This might need to be changed a bit if we ever // take the max of it. This might need to be changed a bit if we ever
@ -174,8 +194,8 @@ class Bus : public MemObject
* requests. */ * requests. */
void recvRetry(int id); void recvRetry(int id);
/** Function called by the port when the bus is recieving a status change.*/ /** Function called by the port when the bus is recieving a range change.*/
void recvStatusChange(Port::Status status, int id); void recvRangeChange(int id);
/** Find which port connected to this bus (if any) should be given a packet /** Find which port connected to this bus (if any) should be given a packet
* with this address. * with this address.
@ -238,12 +258,23 @@ class Bus : public MemObject
portCache[0].valid = false; portCache[0].valid = false;
} }
/** Process address range request. /**
* @param resp addresses that we can respond to * Return the address ranges this port is responsible for.
* @param snoop addresses that we would like to snoop *
* @param id ide of the busport that made the request. * @param id id of the bus port that made the request
*
* @return a list of non-overlapping address ranges
*/ */
void addressRanges(AddrRangeList &resp, bool &snoop, int id); AddrRangeList getAddrRanges(int id);
/**
* Determine if the bus port is snooping or not.
*
* @param id id of the bus port that made the request
*
* @return a boolean indicating if this port is snooping or not
*/
bool isSnooping(int id);
/** Calculate the timing parameters for the packet. Updates the /** Calculate the timing parameters for the packet. Updates the
* firstWordTime and finishTime fields of the packet object. * firstWordTime and finishTime fields of the packet object.
@ -264,7 +295,7 @@ class Bus : public MemObject
BusFreeEvent busIdle; BusFreeEvent busIdle;
bool inRetry; bool inRetry;
std::set<int> inRecvStatusChange; std::set<int> inRecvRangeChange;
/** max number of bus ids we've handed out so far */ /** max number of bus ids we've handed out so far */
short maxId; short maxId;

View file

@ -70,11 +70,9 @@ BaseCache::BaseCache(const Params *p)
} }
void void
BaseCache::CachePort::recvStatusChange(Port::Status status) BaseCache::CachePort::recvRangeChange() const
{ {
if (status == Port::RangeChange) { otherPort->sendRangeChange();
otherPort->sendStatusChange(Port::RangeChange);
}
} }
@ -136,7 +134,7 @@ BaseCache::init()
{ {
if (!cpuSidePort || !memSidePort) if (!cpuSidePort || !memSidePort)
panic("Cache not hooked up on both sides\n"); panic("Cache not hooked up on both sides\n");
cpuSidePort->sendStatusChange(Port::RangeChange); cpuSidePort->sendRangeChange();
} }

View file

@ -105,7 +105,7 @@ class BaseCache : public MemObject
CachePort(const std::string &_name, BaseCache *_cache, CachePort(const std::string &_name, BaseCache *_cache,
const std::string &_label); const std::string &_label);
virtual void recvStatusChange(Status status); virtual void recvRangeChange() const;
virtual unsigned deviceBlockSize() const; virtual unsigned deviceBlockSize() const;

View file

@ -90,8 +90,7 @@ class Cache : public BaseCache
return static_cast<Cache<TagStore> *>(cache); return static_cast<Cache<TagStore> *>(cache);
} }
virtual void getDeviceAddressRanges(AddrRangeList &resp, virtual AddrRangeList getAddrRanges();
bool &snoop);
virtual bool recvTiming(PacketPtr pkt); virtual bool recvTiming(PacketPtr pkt);
@ -118,8 +117,7 @@ class Cache : public BaseCache
void processSendEvent(); void processSendEvent();
virtual void getDeviceAddressRanges(AddrRangeList &resp, virtual bool isSnooping();
bool &snoop);
virtual bool recvTiming(PacketPtr pkt); virtual bool recvTiming(PacketPtr pkt);

View file

@ -1554,14 +1554,15 @@ Cache<TagStore>::nextMSHRReadyTime()
/////////////// ///////////////
template<class TagStore> template<class TagStore>
void AddrRangeList
Cache<TagStore>::CpuSidePort:: Cache<TagStore>::CpuSidePort::
getDeviceAddressRanges(AddrRangeList &resp, bool &snoop) getAddrRanges()
{ {
// CPU side port doesn't snoop; it's a target only. It can // CPU side port doesn't snoop; it's a target only. It can
// potentially respond to any address. // potentially respond to any address.
snoop = false; AddrRangeList ranges;
resp.push_back(myCache()->getAddrRange()); ranges.push_back(myCache()->getAddrRange());
return ranges;
} }
@ -1612,14 +1613,13 @@ CpuSidePort::CpuSidePort(const std::string &_name, Cache<TagStore> *_cache,
/////////////// ///////////////
template<class TagStore> template<class TagStore>
void bool
Cache<TagStore>::MemSidePort:: Cache<TagStore>::MemSidePort::isSnooping()
getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
{ {
// Memory-side port always snoops, but never passes requests // Memory-side port always snoops, but never passes requests
// through to targets on the cpu side (so we don't add anything to // through to targets on the cpu side (so we don't add anything to
// the address range list). // the address range list).
snoop = true; return true;
} }

View file

@ -116,7 +116,7 @@ PhysicalMemory::init()
for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) { for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) {
if (*pi) if (*pi)
(*pi)->sendStatusChange(Port::RangeChange); (*pi)->sendRangeChange();
} }
} }
@ -398,36 +398,30 @@ PhysicalMemory::getPort(const std::string &if_name, int idx)
return port; return port;
} }
void
PhysicalMemory::recvStatusChange(Port::Status status)
{
}
PhysicalMemory::MemoryPort::MemoryPort(const std::string &_name, PhysicalMemory::MemoryPort::MemoryPort(const std::string &_name,
PhysicalMemory *_memory) PhysicalMemory *_memory)
: SimpleTimingPort(_name, _memory), memory(_memory) : SimpleTimingPort(_name, _memory), memory(_memory)
{ } { }
void void
PhysicalMemory::MemoryPort::recvStatusChange(Port::Status status) PhysicalMemory::MemoryPort::recvRangeChange()
{ {
memory->recvStatusChange(status); // memory is a slave and thus should never have to worry about its
// neighbours address ranges
} }
void AddrRangeList
PhysicalMemory::MemoryPort::getDeviceAddressRanges(AddrRangeList &resp, PhysicalMemory::MemoryPort::getAddrRanges()
bool &snoop)
{ {
memory->getAddressRanges(resp, snoop); return memory->getAddrRanges();
} }
void AddrRangeList
PhysicalMemory::getAddressRanges(AddrRangeList &resp, bool &snoop) PhysicalMemory::getAddrRanges()
{ {
snoop = false; AddrRangeList ranges;
resp.clear(); ranges.push_back(RangeSize(start(), size()));
resp.push_back(RangeSize(start(), size())); return ranges;
} }
unsigned unsigned

View file

@ -65,10 +65,9 @@ class PhysicalMemory : public MemObject
virtual void recvFunctional(PacketPtr pkt); virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status); virtual void recvRangeChange();
virtual void getDeviceAddressRanges(AddrRangeList &resp, virtual AddrRangeList getAddrRanges();
bool &snoop);
virtual unsigned deviceBlockSize() const; virtual unsigned deviceBlockSize() const;
}; };
@ -172,7 +171,7 @@ class PhysicalMemory : public MemObject
public: public:
unsigned deviceBlockSize() const; unsigned deviceBlockSize() const;
void getAddressRanges(AddrRangeList &resp, bool &snoop); AddrRangeList getAddrRanges();
virtual Port *getPort(const std::string &if_name, int idx = -1); virtual Port *getPort(const std::string &if_name, int idx = -1);
void virtual init(); void virtual init();
unsigned int drain(Event *de); unsigned int drain(Event *de);
@ -181,7 +180,6 @@ class PhysicalMemory : public MemObject
Tick doAtomicAccess(PacketPtr pkt); Tick doAtomicAccess(PacketPtr pkt);
void doFunctionalAccess(PacketPtr pkt); void doFunctionalAccess(PacketPtr pkt);
virtual Tick calculateLatency(PacketPtr pkt); virtual Tick calculateLatency(PacketPtr pkt);
void recvStatusChange(Port::Status status);
public: public:
virtual void serialize(std::ostream &os); virtual void serialize(std::ostream &os);

View file

@ -1,4 +1,16 @@
/* /*
* Copyright (c) 2011 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2002-2005 The Regents of The University of Michigan * Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved. * All rights reserved.
* *
@ -48,8 +60,7 @@
#include "mem/packet.hh" #include "mem/packet.hh"
#include "mem/request.hh" #include "mem/request.hh"
/** This typedef is used to clean up the parameter list of /** This typedef is used to clean up getAddrRanges(). It's declared
* getDeviceAddressRanges() and getPeerAddressRanges(). It's declared
* outside the Port object since it's also used by some mem objects. * outside the Port object since it's also used by some mem objects.
* Eventually we should move this typedef to wherever Addr is * Eventually we should move this typedef to wherever Addr is
* defined. * defined.
@ -101,13 +112,6 @@ class Port
virtual ~Port(); virtual ~Port();
// mey be better to use subclasses & RTTI?
/** Holds the ports status. Currently just that a range recomputation needs
* to be done. */
enum Status {
RangeChange
};
void setName(const std::string &name) void setName(const std::string &name)
{ portName = name; } { portName = name; }
@ -139,8 +143,8 @@ class Port
/** Called to recive a functional call from the peer port. */ /** Called to recive a functional call from the peer port. */
virtual void recvFunctional(PacketPtr pkt) = 0; virtual void recvFunctional(PacketPtr pkt) = 0;
/** Called to recieve a status change from the peer port. */ /** Called to recieve an address range change from the peer port. */
virtual void recvStatusChange(Status status) = 0; virtual void recvRangeChange() = 0;
/** Called by a peer port if the send was unsuccesful, and had to /** Called by a peer port if the send was unsuccesful, and had to
wait. This shouldn't be valid for response paths (IO Devices). wait. This shouldn't be valid for response paths (IO Devices).
@ -155,17 +159,31 @@ class Port
*/ */
virtual unsigned deviceBlockSize() const { return 0; } virtual unsigned deviceBlockSize() const { return 0; }
/** The peer port is requesting us to reply with a list of the ranges we
are responsible for.
@param resp is a list of ranges responded to
@param snoop is a list of ranges snooped
*/
virtual void getDeviceAddressRanges(AddrRangeList &resp,
bool &snoop)
{ panic("??"); }
public: public:
/**
* Get a list of the non-overlapping address ranges we are
* responsible for. The default implementation returns an empty
* list and thus no address ranges. Any slave port must override
* this function and return a populated list with at least one
* item.
*
* @return a list of ranges responded to
*/
virtual AddrRangeList getAddrRanges()
{ AddrRangeList ranges; return ranges; }
/**
* Determine if this port is snooping or not. The default
* implementation returns false and thus tells the neighbour we
* are not snooping. Any port that is to snoop (e.g. a cache
* connected to a bus) has to override this function.
*
* @return true if the port should be considered a snooper
*/
virtual bool isSnooping()
{ return false; }
/** Function called by associated memory device (cache, memory, iodevice) /** Function called by associated memory device (cache, memory, iodevice)
in order to send a timing request to the port. Simply calls the peer in order to send a timing request to the port. Simply calls the peer
port receive function. port receive function.
@ -193,10 +211,11 @@ class Port
void sendFunctional(PacketPtr pkt) void sendFunctional(PacketPtr pkt)
{ return peer->recvFunctional(pkt); } { return peer->recvFunctional(pkt); }
/** Called by the associated device to send a status change to the device /**
connected to the peer interface. * Called by the associated device to send a status range to the
*/ * peer interface.
void sendStatusChange(Status status) {peer->recvStatusChange(status); } */
void sendRangeChange() const { peer->recvRangeChange(); }
/** When a timing access doesn't return a success, some time later the /** When a timing access doesn't return a success, some time later the
Retry will be sent. Retry will be sent.
@ -208,12 +227,6 @@ class Port
*/ */
unsigned peerBlockSize() const { return peer->deviceBlockSize(); } unsigned peerBlockSize() const { return peer->deviceBlockSize(); }
/** Called by the associated device if it wishes to find out the address
ranges connected to the peer ports devices.
*/
void getPeerAddressRanges(AddrRangeList &resp, bool &snoop)
{ peer->getDeviceAddressRanges(resp, snoop); }
/** This function is a wrapper around sendFunctional() /** This function is a wrapper around sendFunctional()
that breaks a larger, arbitrarily aligned access into that breaks a larger, arbitrarily aligned access into
appropriate chunks. The default implementation can use appropriate chunks. The default implementation can use

View file

@ -671,9 +671,8 @@ RubyPort::PioPort::sendTiming(PacketPtr pkt)
bool bool
RubyPort::M5Port::isPhysMemAddress(Addr addr) RubyPort::M5Port::isPhysMemAddress(Addr addr)
{ {
AddrRangeList physMemAddrList; AddrRangeList physMemAddrList =
bool snoop = false; ruby_port->physMemPort->getPeer()->getAddrRanges();
ruby_port->physMemPort->getPeerAddressRanges(physMemAddrList, snoop);
for (AddrRangeIter iter = physMemAddrList.begin(); for (AddrRangeIter iter = physMemAddrList.begin();
iter != physMemAddrList.end(); iter != physMemAddrList.end();
iter++) { iter++) {

View file

@ -139,10 +139,13 @@ class SimpleTimingPort : public Port
bool recvTiming(PacketPtr pkt); bool recvTiming(PacketPtr pkt);
/** /**
* Simple ports generally don't care about any status * Simple ports are generally used as slave ports (i.e. the
* changes... can always override this in cases where that's not * respond to requests) and thus do not expect to receive any
* true. */ * range changes (as the neighbouring port has a master role and
virtual void recvStatusChange(Status status) { } * do not have any address ranges. A subclass can override the
* default behaviuor if needed.
*/
virtual void recvRangeChange() { }
public: public:

View file

@ -102,7 +102,13 @@ class System : public MemObject
{ panic("SystemPort does not receive atomic!\n"); return 0; } { panic("SystemPort does not receive atomic!\n"); return 0; }
void recvFunctional(PacketPtr pkt) void recvFunctional(PacketPtr pkt)
{ panic("SystemPort does not receive functional!\n"); } { panic("SystemPort does not receive functional!\n"); }
void recvStatusChange(Status status) { }
/**
* The system port is a master port connected to a single
* slave and thus do not care about what ranges the slave
* covers (as there is nothing to choose from).
*/
void recvRangeChange() { }
}; };